I currently have a project called LIBS with a structure like this:
├── Lib1
│ ├── CMakeLists.txt
│ ├── lib1-class.cpp
│ └── lib1-class.h
├── lib2
│ └── CMakeLists.txt
│ ├── lib2-class.cpp
│ ├── lib2-class.h
├── cmake
│ └── LIBSConfig.cmake.in
├── CMakeLists.txt
in the main cmake file, I have:
install(
TARGETS
lib1
lib2
DESTINATION
${PROJECT_DIRNAME_lib}
EXPORT
${PROJECT_NAME}Exports
)
install(
EXPORT
${PROJECT_NAME}Exports
DESTINATION
${PROJECT_DIRNAME_lib}
)
as I want to export these in a package that is discoverable by find_package().
My problem is that I generate lib1
and lib2
in their respective directories and when installing them, Cmake tells me that
Error:install TARGETS given target "lib1" which does not exist in this directory.
As suggested here, My understanding is that I should use Export()
and in lib1 and lib2, have something of the form:
export(TARGETS lib1 FILE lib1Exports.cmake)
and in the LIBS project, have something like this:
ADD_LIBRARY(lib1 UNKNOWN IMPORTED)
set_property(TARGET lib1 PROPERTY IMPORTED_LOCATION lib1)
However it does not like me using the same name for this library that is being added from the parent project. It tells me:
Error:add_library cannot create imported target "lib1" because another target with the same name already exists.
so the library is available and I can link to it, etc. if I were to create another target in the parent directory, but I can't install it.
I have found the exact same problem in a bug report here but I believe cmake handles things differently now and I am just not doing it correctly. So am I doing it wrong? I would like to avoid using external packages if possible.
Update: the accepted solution works only for cases where there is no dependency between lib1, lib2. In that case one should use the solution provided to this question.
The export() command is used to generate a file exporting targets from a project build tree. Here we use the export() command to generate the export targets for the build tree. In this case, we'll create a file called MathFunctionsTargets. cmake in the cmake subdirectory of the build directory.
You can show the Targets View by clicking on the view dropdown in the Solution Explorer: If you have worked with the projects and Solutions generated by CMake before, you should feel right at home.
Add a subdirectory to the build. Adds a subdirectory to the build. The source_dir specifies the directory in which the source CMakeLists.
As noted in the bugreport you refer to install()
command should be issued from the same directory where target is created. As you have libraries target created in different directories, you need to assign different export names for them, and, consequently, different export files.
But you are free to include both export files into the LIBSConfig.cmake
script:
cmake/LIBSConfig.cmake:
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${SELF_DIR}/LIBS-lib1.cmake)
include(${SELF_DIR}/LIBS-lib2.cmake)
lib1/CMakeLists.txt:
add_library(lib1 ...)
install(TARGET lib1 EXPORT lib1-export ...)
lib2/CMakeLists.txt:
add_library(lib2 ...)
install(TARGET lib2 EXPORT lib2-export ...)
CMakeLists.txt:
add_subdirectory(lib1)
add_subdirectory(lib2)
install(EXPORT lib1-export FILENAME LIBS-lib1.cmake DESTINATION lib/LIBS)
install(EXPORT lib2-export FILENAME LIBS-lib2.cmake DESTINATION lib/LIBS)
install(FILES cmake/LIBSConfig.cmake DESTINATION lib/LIBS)
Note, that export command exports build tree. It is usually not suitable for find_package
, which is normally used for find installed files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With