I have a project Foo that links libraries curl, threads and jsoncpp. I build Foo and it generates a FooTargets.cmake targets file, that I can use in my project Bar to link it (with something like find_package(Foo REQUIRED) and then Foo::Foo).
Now this FooTargets.cmake somehow links curl and threads in a weird way:
INTERFACE_LINK_LIBRARIES "\$<LINK_ONLY:CURL::libcurl::#<0x56344f65d140>>;
\$<LINK_ONLY:Threads::Threads::#<0x56344f65d140>>;\$<LINK_ONLY:JsonCpp::JsonCpp>;
i.e. it adds this weird #<0x56344f65d140>, for some reason.
But then, when configuring project Bar, I get the following errors:
CMake Error at bar/CMakeLists.txt:13 (add_executable):
Target "bar" links to target "CURL::libcurl::#<0x55c57ad49530>"
but the target was not found. Perhaps a find_package() call is missing for
an IMPORTED target, or an ALIAS target is missing?
CMake Error at bar/CMakeLists.txt:13 (add_executable):
Target "bar" links to target "Threads::Threads::#<0x55c57ad49530>"
but the target was not found. Perhaps a find_package() call is missing for
an IMPORTED target, or an ALIAS target is missing?
Note that when running the same steps on my CI, it seems to just work. Also if I manually edit FooTargets.cmake and remove the #<0x55c57ad49530>, it works just fine.
Why do they have this #<0x55c57ad49530> appended, where e.g. JsonCpp does not?
This was happening with CMake version 3.16.3. Newer versions of CMake don't seem to have that problem, which explains why the CI was fine.
Ran into the same issue. alternatively I was able to solve it by only having one target_link_libraries (on cmake 3.13). If you ran into the same issue and you are unable to upgrade, try to call target_link_libraries only once for the target.
Related
I have installed package "spdlog" from vcpkg manager, successfully linked with the library by providing CMake instruction and generated foo.dll and foo.dll.a
Now, I use these dll's in my application by linking with foo.dll
spdlog headers (used in foo.dll) can not be found by my application fooapp now.
If I use target_link_libraries(foo INTERFACE spdlog::spdlog spdlog::spdlog_header_only) in CmakeLists.txt of fooapp, include error is gone. But Linker complains that it can't find the foo.dll.a at xxx path. What is confusing that at xxx path the .dll.a file is present. (Don't know if its correct, just did to let cmake find spdlog headers as per vcpkg instructions)
Note: If I remove dependency of spdlog in foo.dll and try simple cout all works fine. Linker can find and link foo.dll.a and successfully make fooapp.exe. This is becoming too confusing for me now and I can't find good stack answers related to this. spdlog here is just a reference, It can be any other package by vcpkg.
a) Are dll headers also the dependency of applications?
b) Why .dll.a is not found, It is at the exact location for what it complains about.
c) Why removing the dependency of spdlog make it all work again?
I would like to use the Antlr framework in a project. I'm using CMake to build the project.
I would like to use the SHARED library version of Antlr, not the STATIC one. Its CMake file contains targets for both.
Antlr's github site explicity tells me to use the following code:
find_package(antlr4-runtime REQUIRED)
# add runtime include directories on this project.
include_directories( ${ANTLR4_INCLUDE_DIR} )
# add runtime to project dependencies
add_dependencies( Parsertest antlr4_shared )
# add runtime to project link libraries
target_link_libraries( Parsertest PRIVATE
antlr4_shared)
(another target, antlr4_static, exists, but shouldn´t be used.)
I copied it exactly like this and am getting the following error:
CMake Error at /usr/lib64/cmake/antlr4-runtime/antlr4-targets.cmake:82 (message):
The imported target "antlr4_static" references the file
"/usr/lib/libantlr4-runtime.a"
but this file does not exist.
I dont have the static library installed in my system as I have no intention of using it. Still, how do I make CMake stop looking for the wrong target in the first place? I use it nowhere in my CMakeLists.txt file and am puzzled by this behavior.
I am specifying a shared library build from source files in my CMakeLists.txt file like so:
# Library setup
file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/Source/*.cpp)
file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/Source/*.h)
Inside the source directories contain all my .h and .cpp files required to build my shared library. So I then do something like this:
add_library(mylibrary SHARED ${SOURCES} ${HEADERS} )
I also link a bunch of other .libs with mylibrary later on as well (Could there be a clashing issue?). The problem arises when I try to build mylibrary. I receive linking errors such as:
Severity Code Description Project File Line Suppression State
Error LNK2001 unresolved external symbol __imp_cosf mylibrary ***.obj 1
even though the symbol is defined in my source files that I have included. I am not exactly sure what to do in order to properly let my project find those symbols. The funny thing is is that when I build as a static library it is fine. However, when I try to build as a dynamic library, these errors appear.
So, I'm not exactly sure why this worked. But there was a conflict warning between linking to MSVRCT and libcmt. It said something like this in the output log:
Resolving LNK4098: defaultlib 'MSVCRT' conflicts with ...
This is because libcmt is a static library for release build and uses \MT flags. MSVRCT is a release DLL version and compiled with \MD flag. Because of this conflict, I had to change my compiler flags to be:
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
Then the symbols were able to be found. If anyone has any comments/corrections to why this worked please add.
I am working on a larger C++ library that is using CMake and depends on Qt.
We moved from Qt4 to Qt5 and now I encounter a problem when using our lib
in an upstream project. As a minimal working example demonstrating the problem please have a look at this repo:
https://github.com/philthiel/cmake_qt5_upstream
It contains two separate CMake projects:
MyLIB: a tiny library that uses QString from Qt5::Core.
It generates and installs package configuration files
MyLIBConfig.cmake, MyLIBConfigVersion.cmake, and MyLIBTargets.cmake
in order to be searchable by CMake find_package()
MyAPP: a tiny executable depending on MyLIB
The project uses find_package(MyLIB) and creates an executable that uses MyLIB
The problem is that CMake gives me the following error message when configuring the MyAPP project:
CMake Error at CMakeLists.txt:11 (add_executable):
Target "MyAPP" links to target "Qt5::Core" but the target was not found.
Perhaps a find_package() call is missing for an IMPORTED target, or an
ALIAS target is missing?
The reason for this behaviour is that in the automatically generated MyLIBTargets.cmake file the INTERFACE_LINK_LIBRARIES entry for Qt5 Core is the Qt5::Core symbol. Using Qt4, the absolute path to the Qt core lib was specified here.
Now, I simply can resolve this by using
find_package(Qt5Core 5.X REQUIRED)
in the MyAPP project.
However, I would like to know if this is the intended/generic way to go, i.e. requesting upstream projects of our lib to search for the required transitive Qt5 dependencies themselves, or if I probably misuse CMake here and need to change my configuration procedure?
The CMake docu on package file generation
https://cmake.org/cmake/help/v3.0/manual/cmake-packages.7.html
mentions that macros can be provided by the package configuration files to upstream. Maybe this would be the correct place to search for imported targets like Qt5 and break upstream configuration runs when these dependencies are not found?
Best,
Philipp
[edit of the edit] Full Source Example
You need to deliver a CMake config file for your project, and probably the ConfigFile should be generated via CMake itself (because you cannot know for shure where the user will install your software).
Tip, use the ECM cmake modules to ease the creation of that:
find_package(ECM REQUIRED NO_MODULE)
include(CMakePackageConfigHelpers)
ecm_setup_version(${PROJECT_VERSION}
VARIABLE_PREFIX ATCORE
VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/atcore_version.h"
PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5AtCoreConfigVersion.cmake"
SOVERSION 1
)
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/KF5AtCoreConfig.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/KF5AtCoreConfig.cmake"
INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR}
)
and the KF5AtCoreConfig.cmake.in:
#PACKAGE_INIT#
find_dependency(Qt5Widgets "#REQUIRED_QT_VERSION#")
find_dependency(Qt5SerialPort "#REQUIRED_QT_VERSION#")
find_dependency(KF5Solid "#KF5_DEP_VERSION#")
include("${CMAKE_CURRENT_LIST_DIR}/KF5AtCoreTargets.cmake")
This will generate the correct FindYourSortware.cmake with all your dependencies.
[edit] Better explanation on what's going on.
If you are providing a library that will use Qt, and that would also need to find the Qt5 library before compilling the user's source, you need to provide yourself a FindYourLibrary.cmake code, that would call
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Whatever)
Now, if it's your executable that needs to be linked, use the Components instead of the way you are doing it now.
find_package(Qt5 REQUIRED COMPONENTS Core)
then you link your library with
target_link_libraries(YourTarget Qt5::Core)
I installed Ogre3D 1.8.1 (the source package) on Ubuntu 12.04 and everything went fine (I managed to run some samples on the Ogre interface). However, I hit a problem while I was compiling an external project (that one) that needed the OpenCV, ArUco and Ogre librarys. When I run the CMake of the project, I receive the following:
CMake Error at CMakeLists.txt:46 (find_package):
By not providing "FindOGRE.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "OGRE", but
CMake did not find one.
Could not find a package configuration file provided by "OGRE" with any of
the following names:
OGREConfig.cmake
ogre-config.cmake
Add the installation prefix of "OGRE" to CMAKE_PREFIX_PATH or set
"OGRE_DIR" to a directory containing one of the above files. If "OGRE"
provides a separate development package or SDK, be sure it has been
installed.
-- Configuring incomplete, errors occurred!
I know where the FindOGRE.cmake is, it's in the /usr/local/lib/OGRE/cmake, but I don't know how to say to CMake to look for that folder and fix this problem.
You just need to use the -D command line option along with the CMAKE_MODULE_PATH variable:
cmake . -DCMAKE_MODULE_PATH=/usr/local/lib/OGRE/cmake
Just for the record, an alternative solution would be to add the module path directly in the CMakeLists.txt. For example (tested on Debian 9):
set(CMAKE_MODULE_PATH "/usr/share/OGRE/cmake/modules/;${CMAKE_MODULE_PATH}")
Just make sure to add the line before find_package is called.
For me, it only works to set the following in CMakeLists.txt before find_package:
set(OGRE_DIR /usr/share/OGRE/build/sdk/CMake)
Note that the CMake directory is the one containing OGREConfig.cmake. For some reason, my CMake ignores CMAKE_MODULE_PATH.
Maybe, of some help for someone
For me, this solution work on manjaro:
set(CMAKE_MODULE_PATH "/usr/lib/OGRE/cmake;${CMAKE_MODULE_PATH}")
find_package(OGRE QUIET)
if (OGRE_FOUND)
include_directories( ${ogre_INCLUDE_DIR})
link_directories(${OGRE_LIBRARIES})
message(STATUS "OGRE: FOUND")
else()
message(STATUS "OGRE: NOT FOUND")
endif()