Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logr v0.1.0 #3812

Merged
merged 15 commits into from
Dec 14, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions recipes/logr/0.1.0/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.14)
project(cmake_wrapper)

include(conanbuildinfo.cmake)
conan_basic_setup()

add_subdirectory(source_subfolder/logr)
4 changes: 4 additions & 0 deletions recipes/logr/0.1.0/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sources:
"0.1.0":
url: "https://github.com/ngrodzitski/logr/archive/v0.1.0.tar.gz"
sha256: "6b2e68b6425362f678b7485cd2c8cef7db377ac8ccd45646c84941b189b0b82d"
92 changes: 92 additions & 0 deletions recipes/logr/0.1.0/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration
import os

class LogrConan(ConanFile):
name = "logr"
version = "0.1.0"
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved
license = "BSD 3-Clause License"
homepage = "https://github.com/ngrodzitski/logr"
url = "https://github.com/conan-io/conan-center-index"
description = "Logger frontend substitution for spdlog, glog, etc for server/desktop applications"
topics = ("logger", "development", "util", "utils")
generators = "cmake"
settings = "os", "compiler", "build_type", "arch"
build_policy = "missing"
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved
exports_sources = ["CMakeLists.txt"]

options = { 'spdlog_backend' : [True, False],
'glog_backend' : [True, False],
'log4cplus_backend' : [True, False] }

default_options = { 'spdlog_backend': True,
'glog_backend': True,
'log4cplus_backend': True }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please rename these options to: spdlog, glog and log4cplus.
Also can all 3 backends be used together, or are they to be used exclusive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning of this options is whether the corresponding header file would be installed or not. By default all of them are present.

_cmake = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"

def requirements(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised you don't add a requirement on either spdlog, glog or log4plus.
If this is a frontend substitution, then the backend should be available. Isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider the following reasoning:

  • Deciding what logger to use in your application (among the three supported).
  • Once logger library is decided, the application adds it to the list of dependencies (so logger is already in deps list).
  • Then it is decided to use another "frontend" to it.

Deciding the logger happens in the first place (so deps machinery is applied for logger lib), and the logr is like an extension to a selected library.

And in case of using in conanfile it would be less bothering to just specify logr without forcing the user to dig into options.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that logr won't work when having the following conanfile.txt:

[requires]
spdlog/0.1.0
[options]
logr:with_spdlog_backend=True
logr:with_glog_backend=False
logr:with_log4cplus_backend=False

because spdlog is is not available.
I would do this in requirements:

if self.options.with_spdlog_backend:
    self.requires("spdlog/x.y")
elif self.options.with_glog_backend
    self.requires("log4cplus/x.y")
elif self.options.with_log4cplus_backend:
    self.requires("log4cplus/x.y")

Copy link
Contributor Author

@ngrodzitski ngrodzitski Dec 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested the following conanfile.txt

[requires]
logr/0.1.0
[options]
logr:spdlog_backend=True
logr:glog_backend=False
logr:log4cplus_backend=False

[generators]
cmake

And a project based on test_project works just fine.

The libs is a collection of headers and it has some options to add a certain headers or not.

Would it be ok to just remove all options and make all headers to be unconditionally present?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How usable is this library without any backend?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That could be a way, but I think you should also add these library as a requirement of logr. Or shouldn't you?

Copy link
Contributor Author

@ngrodzitski ngrodzitski Dec 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    options = { "backend": ["spdlog", "glog", "log4cplus", "all", None }
    default_options = { "backend": ["spdlog"]}

all is the option for local dev builds. As I want all of them to be available in single build (for examples and benchmarks) and I want to keep local conanfile at most similar to projects own conanfile.

Does Conan introduces dependencie propogation when I specify self.requires("spdlog/x.y")? Or I need to modify projects cmake files and add something like target_link_libraries(logr INTERFACE spdlog::spdlog)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I have given up on keeping project's conanfiles equal to cci's conanfiles.
Mostly because I don't want the project to need a cmake wrapper script, just for conan.

When you add self.requires("spdlog/x.y") to logr,
then linking to the logr::logr cmake target will also link to spdlog::spdlog.

I changed your example a bit by removing the list from default_options.
It can only have one.

    options = { "backend": ["spdlog", "glog", "log4cplus", "all", None }
    default_options = { "backend": "spdlog"}

As @prince-chrismc already mentioned, I don't think an all option does not make muck sense for cci. For your personal development branch, it might.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I have given up on keeping project's conanfiles equal to cci's conanfiles.

Yep! CCI is trying to provide the most convince to as many consumers as possible. Which may not meet the needs of the project!

That being said, as a very happy RESTinio consumer, it seems unlikely that a project will have multiple logging methods.... but then they wouldn't need this library either!

✅ There is no right or wrong answer, so ultimately the choice is yours.

I have to agree with @madebr suggestion for a single option that adds the correct requires... for myself this adds the freedom to change in the future with little impact.

Again the opinion of a potential consumer =)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored to a single option "backend", which implies dependency to a specific logger library.

self.requires( "fmt/7.1.2" )
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved

def configure(self):
minimal_cpp_standard = "17"
if self.settings.compiler.cppstd:
tools.check_min_cppstd(self, minimal_cpp_standard)
minimal_version = {
"gcc": "7",
"clang": "7",
"apple-clang": "10",
"Visual Studio": "16"
}
compiler = str(self.settings.compiler)
if compiler not in minimal_version:
self.output.warn(
"%s recipe lacks information about the %s compiler standard version support" % (self.name, compiler))
self.output.warn(
"%s requires a compiler that supports at least C++%s" % (self.name, minimal_cpp_standard))
return

version = tools.Version(self.settings.compiler.version)
if version < minimal_version[compiler]:
raise ConanInvalidConfiguration("%s requires a compiler that supports at least C++%s" % (self.name, minimal_cpp_standard))


def _configure_cmake(self):
if self._cmake:
return self._cmake

self._cmake = CMake(self)
self._cmake.definitions['LOGR_WITH_SPDLOG_BACKEND'] = self.options.spdlog_backend
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved
self._cmake.definitions['LOGR_WITH_GLOG_BACKEND'] = self.options.glog_backend
self._cmake.definitions['LOGR_WITH_LOG4CPLUS_BACKEND'] = self.options.log4cplus_backend

self._cmake.definitions['LOGR_INSTALL'] = True

self._cmake.configure(build_folder=self._build_subfolder)
return self._cmake

def source(self):
tools.get(**self.conan_data["sources"][self.version])
extracted_dir = self.name + "-" + self.version
os.rename(extracted_dir, self._source_subfolder)

ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved
def package(self):
self.copy("LICENSE", src=self._source_subfolder, dst="licenses")
cmake = self._configure_cmake()
cmake.install()

tools.rmdir(os.path.join(self.package_folder, "lib"))

def package_id(self):
self.info.header_only()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An optimisation we like to add is no_copy_source attribute near the options.

On mobile so I do not have an example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to set no_copy_source, but then I have to use projects own root CMakeLists.txt, and it doesn't workout great as I use "cmake_find_package" generator there and some cmake-scripts are in submodule wich is not a part of tarball. For next release I'll handle those issues and will apply this options.


def package_info(self):
self.info.header_only()
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved
14 changes: 14 additions & 0 deletions recipes/logr/0.1.0/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.14)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
message(STATUS "ENABLE C++17")
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved

project(PackageTest CXX)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

add_executable(example example.cpp)
target_link_libraries(example ${CONAN_LIBS})
20 changes: 20 additions & 0 deletions recipes/logr/0.1.0/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os

from conans import ConanFile, CMake, tools


class LogrTestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"

def build(self):
cmake = CMake(self)
# Current dir is "test_package/build/<build_id>" and CMakeLists.txt is
# in "test_package"
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
os.chdir("bin")
self.run(".%sexample" % os.sep)
ngrodzitski marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 18 additions & 0 deletions recipes/logr/0.1.0/test_package/example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <iostream>

#include <logr/ostream_backend.hpp>
#include <logr/config.hpp>

int main()
{
logr::ostream_logger_t<> logger{ std::cout,
logr::log_message_level::trace };

logger.info( []( auto & out ){
fmt::format_to( out,
"Welcome to logr (v{}.{}.{}), package is provided by Conan!",
LOGR_VERSION_MAJOR,
LOGR_VERSION_MINOR,
LOGR_VERSION_PATCH );
} );
}