Comments (9)
You are missing linking core -> common.
the following fixes it:
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 65a29e5..a329800 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -18,6 +18,7 @@ string(REPLACE ";" "$<SEMICOLON>" dirs "${core_build_include_dirs}")
add_library(core ${SOURCES})
add_library(my_algorithm::core ALIAS core)
+target_link_libraries(core PUBLIC common)
#target_include_directories(core PUBLIC include)
message("CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
from conan.
Thanks for your question.
If common
is a header-only library then the following line is incorrect:
self.cpp_info.components["common"].libs = ["common"]
That means that there is a compiled library called libcommon.a
or common.lib
depending on the system, but this is not the case.
- How can I build and export both libraries (header-only and non-header-only) in this modular setup? Since there are consumers that may want to require just the common header-only library but not together with the core library.
You were almost there, I think just fixing the above it should work, and consumers could link with just the header-only library if they want to.
If I have to include other packages like fmt in my common library (header-only library), how can I set up my cmake and conan configuration?
Typically with something like:
requires = "fmt/version"
def package_info(self):
...
# check the target, I am just guessing fmt::fmt, I haven't checked
self.cpp_info.components["common"].requires = ["fmt::fmt"]
If (2) is possible, is it possible that the consumer (like the core library here) install the fmt library right away and the consumer libraries do not have to each specify the requirements in conan and findPackage in cmake for example?
Yes, Conan will handle transitivity from components too. That means that find_package(mypkg ...)
and then target_link_libraries(.... test_foundation::core)
will include transtively the common
and if common
does requires=[fmt::fmt]
, then fmt
will also be transitively included.
from conan.
@memsharded Thank you for your reply.
If I have to include other packages like fmt in my common library (header-only library), how can I set up my cmake and conan configuration?
I have updated the conanfile.py
self.cpp_info.components["common"].requires = ["fmt::fmt", "spdlog::spdlog"]
And on my common/CMakeLists.txt
,
I have references
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
file(GLOB HEADERS include/*.h include/**/*.h)
add_library(common INTERFACE)
add_library(my_algorithm::common ALIAS common)
target_link_libraries(common INTERFACE fmt::fmt spdlog::spdlog)
target_include_directories(
common INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
But I built my project with the following errors
.conan2/p/b/my_alaeb574bf0f0d3/b/common/include/common/algorithm.h:8:10: fatal error: 'spdlog/spdlog.h' file not found
#include <spdlog/spdlog.h>
The package is not properly linked to my header-only library (common
folder). Do you know how I can link the package to my solution?
from conan.
If the headers of fmt
and others are visible through the dependency, that means, the public headers of your package include the headers of those dependencies, then it is necessary first to specify that in the requires as:
def requirements(self):
self.requires("fmt/version", transitive_headers=True)
The default is to assume that dependencies are "implementation detail" of the packages, and are not propagated through the package headers, this is why it is necessary to explicitly tell that they should be propagated to consumers. Check about it in https://docs.conan.io/2/reference/conanfile/methods/requirements.html#requirement-traits. Note that transitive_libs=True
is not necessary in most cases, as Conan knows how to propagate that when necessary.
Please try that and let me know.
from conan.
Hi @memshared. Thanks for the reply. I added the transitive_header=True
option to my fmt and spdlog packages that the header-only library (common
) depends on it. But I cannot this header-only library.
When I run conan create . -v
,
.conan2/p/b/my_al1414ac9f90079/b/common/include/common/algorithm.h:8:10: fatal error: 'spdlog/spdlog.h' file not found
#include <spdlog/spdlog.h>
^~~~~~~~~~~~~~~~~
Currently I have added the following configuration to build the header-only library.
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
FILE(GLOB HEADERS include/*.h include/**/*.h)
add_library(common INTERFACE)
add_library(my_algorithm::common ALIAS common)
message(STATUS "HEADERS: ${HEADERS}")
target_include_directories(
common INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include> ##
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_link_libraries(common INTERFACE fmt::fmt spdlog::spdlog)
include(CMakePackageConfigHelpers)
write_basic_package_version_file("${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
install(TARGETS common
EXPORT ${PROJECT_NAME}_Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) # CHANGE HERE
install(EXPORT ${PROJECT_NAME}_Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) # CHANGE HERE
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
I linked my library with the packages target_link_libraries(common INTERFACE fmt::fmt spdlog::spdlog)
and included instructions to make the proper Cnfig.cmake
and ConfigVersion.cmake
for the consumer to find the my library. But conan is telling it cannot find the fmt and spdlog headers.
What have I done wrong?
from conan.
Hi @memshared. Thanks for the reply. I added the transitive_header=True option to my fmt and spdlog packages that the header-only library (common) depends on it. But I cannot this header-only library.
Aren't you using the ConanCenter recipes? do you have your own recipes?
We might need a full (minimal) reproducible example, I think we start to have too many moving pieces. If the recipes are your own, maybe is it possible that some headers are not being correctly packaged? There would be some things to check. For example it is not clear at all at this point if you are using the Conan CMakeDeps
generated cmake files for dependencies, or you are trying to use the xxx-config.cmake
bundled inside the packages.
If we can reproduce with your repo and the recipes from ConanCenter, can you please make sure the repo contains the latest code and provide the exact commands to reproduce it?
from conan.
I am using the spdlog
and fmt
recipes from ConanCenter.
from conan.
You are missing linking core -> common. the following fixes it:
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 65a29e5..a329800 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -18,6 +18,7 @@ string(REPLACE ";" "$<SEMICOLON>" dirs "${core_build_include_dirs}") add_library(core ${SOURCES}) add_library(my_algorithm::core ALIAS core) +target_link_libraries(core PUBLIC common) #target_include_directories(core PUBLIC include) message("CMAKE_CURRENT_SOURCE_DIR: ${CMAKE_CURRENT_SOURCE_DIR}")
I thought the lines
get_target_property(common_LIB_INCLUDE_DIRS common INTERFACE_INCLUDE_DIRECTORIES)
set(core_build_include_dirs
"${HEADERS}"
"${common_LIB_INCLUDE_DIRS}")
include_directories(${core_build_include_dirs})
was doing the job. 😭 It is working now, thank you so much @memsharded
from conan.
include_directories
No, please note that in the majority of cases, doing things like what you are doing there with get_target_property
and include_directories()
is not recommended. Targets already contain information about headers, that should be enough to use the headers from other targets. Make sure that every target has its property for its header set, and just let target_link_libraries()
deal with it.
It is working now, thank you so much @memsharded
I am closing the ticket as solved then, happy to help! :)
from conan.
Related Issues (20)
- [suggestion] Label only highest tag as latest release HOT 5
- [bug] Conflict with built-in cmake findpackage scripts can break the build HOT 2
- [question] Is there a way to define information in a recipe that can be used in CMake (or other build systems potentially) HOT 2
- [question] How to build C++ project with Apple Hardened Runtime enabled? HOT 12
- [question] Can I pass --vs-args or --ninja-args arguments to the meson tool when executing build command HOT 1
- [bug] file DOWNLOAD cannot compute hash on failed download, it shows 'status: [35;"SSL connect error"]' HOT 16
- [bug] test_package_folder attribute doesn't work HOT 1
- [question] Limitations of `CMakeToolchain` wrt legacy generators HOT 4
- [bug] Github actions fail when set `tools.system.package_manager:mode` HOT 2
- [question] How to depend on a specific Git commit or branch of a project HOT 7
- [bug] build_requires with different #RREV are not used correctly HOT 2
- [question] What is the correct way of exposing PATH when packaging library type? HOT 2
- [bug] CMakeToolchain changes the value of string variables unexpectedly/incorrectly HOT 6
- [feature] [question] Support the Tricore-gcc toolchain and arch
- Incorrect generation of file conanvcvars.ps1 HOT 2
- [question] Conan centre package rereleases HOT 9
- [question] Should Visual Studio 17.10 require a profile update to 194? HOT 38
- [bug] Multiple `--build=missing:~foo` does not work HOT 3
- [bug] Conan setting `CMAKE_FIND_ROOT_PATH_MODE_*=BOTH` fundamentally breaks cross-compilation HOT 4
- [feature] Add a --skip-generator option HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from conan.