I am trying to convert an existing cmake project to use some of the more modern cmake patterns and generate the correct Config.cmake files to be imported by another project
I have the following file structure in the one I want to update
./zoo/
cmake/
*.cmake.in
libzoo/
bind/
CMakeLists.txt
*.cpp
*.h
*etc.
include/
*.h
libzoo/
*.hpp
src/
*.cpp
test/
CMakeLists.txt
CMakeLists.txt
App/
src/
include/
CMakeLists.txt
Issues:
- In the original code everything built and ran fine, but now I am getting errors saying that the APP can’t find the guile include headers now. How do I properly connect and inherit the header dependencies? I think its that modern cmake is more explicit, but I don’t know what I am missing.
Do I need to re-include the headers? meaning the app does not inherit the includes from the library?
target_include_directories(App
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
${Boost_INCLUDE_DIRS}
${PNG_INCLUDE_DIR}
${EIGEN_INCLUDE_DIRS}
${GUILE_INCLUDE_DIRS}
)
- I want to be able to export a
ZooConfig.cmake
such that it can be found withfind_package
and would include libzoo, zoo-guile, and the App. There appears to be many paths, but I am having a hard time finding information out there that makes cohesive sense, and am really confused at this point.
The dependency chain is as follows:
- build a shared library from the source in
libzoo/src
with the header files inlibzoo/include
which depend on Boost, Eigen, PNG, and Threads called libzoo.
add_library(zoo SHARED
${zoo_sources}
)
add_library(zoo::core ALIAS zoo)
target_include_directories(zoo
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
${Boost_INCLUDE_DIRS}
${PNG_INCLUDE_DIR}
${EIGEN_INCLUDE_DIRS}
)
set(LIBS ${PNG_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} )
target_link_libraries(zoo PRIVATE ${LIBS})
set_target_properties(five
PROPERTIES
CXX_STANDARD "${ZOO_CXX_STANDARD}"
CXX_STANDARD_REQUIRED "YES"
CXX_EXTENSION "NO"
INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib
)
install(
TARGETS zoo
EXPORT LibZooTargets
RUNTIME DESTINATION ${ZOO_INSTALL_BIN_DIR}
LIBRARY DESTINATION ${ZOO_INSTALL_LIB_DIR}
ARCHIVE DESTINATION ${ZOO_INSTALL_LIB_DIR}
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION ${ZOO_INSTALL_INCLUDE_DIR}
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.hpp"
)
if (BUILD_TESTS)
add_subdirectory(test)
endif(BUILD_TESTS)
if (BUILD_GUILE_BINDINGS AND GUILE_FOUND)
add_subdirectory(bind)
endif(BUILD_GUILE_BINDINGS AND GUILE_FOUND)
- build the test suite which depends on libzoo
set(SRCS ${test_srcs} )
set(LIBS zoo ${CMAKE_THREAD_LIBS_INIT} )
if (BUILD_GUILE_BINDINGS AND GUILE_FOUND)
set(SRCS ${SRCS} guile.cpp)
set(LIBS ${LIBS} zoo-guile)
endif(BUILD_GUILE_BINDINGS AND GUILE_FOUND)
add_executable(libzoo-test ${SRCS})
target_link_libraries(libzoo-test ${LIBS})
target_include_directories(libzoo-test PRIVATE .)
- build a guile binding library from
/libproject/bind
called zoo-guile depends on libzoo
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/bundle.cpp
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/bundle.cmake
DEPENDS libzoo-guile.cpp shapes.scm csg.scm transforms.scm text.scm util.scm vec.scm
sandbox.scm ${CMAKE_CURRENT_SOURCE_DIR}/bundle.cmake)
add_library(zoo-guile SHARED ${CMAKE_CURRENT_BINARY_DIR}/bundle.cpp)
add_library(zoo::guile ALIAS zoo-guile)
add_dependencies(zoo-guile zoo)
target_link_libraries(zoo-guile zoo ${GUILE_LIBRARIES})
target_include_directories(zoo-guile
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
${GUILE_INCLUDE_DIRS}
)
set_target_properties(zoo-guile
PROPERTIES
CXX_STANDARD "${FIVE_CXX_STANDARD}"
CXX_STANDARD_REQUIRED "YES"
CXX_EXTENSION "NO"
INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib
)
install(
TARGETS zoo-guile
EXPORT LibZooTargets
RUNTIME DESTINATION ${ZOO_INSTALL_BIN_DIR}
LIBRARY DESTINATION ${ZOO_INSTALL_LIB_DIR}
ARCHIVE DESTINATION ${ZOO_INSTALL_LIB_DIR}
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DESTINATION ${ZOO_INSTALL_INCLUDE_DIR}
FILES_MATCHING
PATTERN "*.h"
)
- build the App in which depends on zoo-guile in
App
directory.
# Instruct CMake to run moc, uic, and rrc automatically when needed.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
# Find the Qt libraries
find_package(Qt5Core REQUIRED)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5OpenGL REQUIRED)
find_package(Qt5Network REQUIRED)
find_package(Qt5Concurrent REQUIRED)
set(SRCS ${app_srcs})
set(QOBJECTS ${Qobj_srcs})
add_executable(App ${SRCS} ${QOBJECTS})
install(TARGETS App DESTINATION bin RENAME app)
target_include_directories(App
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include>
)
target_link_libraries(App
PUBLIC
zoo-guile
Qt5::Widgets
Qt5::Gui
Qt5::OpenGL
Qt5::Concurrent
${EXTRA_LIBS}
)
set_target_properties(App
PROPERTIES
CXX_STANDARD "${ZOO_CXX_STANDARD}"
CXX_STANDARD_REQUIRED "YES"
CXX_EXTENSION "NO"
INSTALL_RPATH ${ZOO_INSTALL_LIB_DIR}
)
install(
TARGETS App
EXPORT LibZooTargets
RUNTIME DESTINATION ${ZOO_INSTALL_BIN_DIR}
LIBRARY DESTINATION ${ZOO_INSTALL_LIB_DIR}
ARCHIVE DESTINATION ${ZOO_INSTALL_LIB_DIR}
)
- Export the targets to a Config.cmake file from the project level CMakeLists.txt
#Skipping all the variable setting
add_subdirectory(libzoo)
This makes sense up until here when I try to export the target stuff
if(BUILD_APP AND GUILE_FOUND AND Qt5Core_FOUND)
add_subdirectory(App)
endif(BUILD_APP AND GUILE_FOUND AND Qt5Core_FOUND)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
LibZooConfigVersion.cmake
VERSION ${ZOO_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(EXPORT LibZooTargets
DESTINATION ${ZOO_CMAKE_INSTALL_DIR}
)
configure_package_config_file(
"cmake/LibZooConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/LibZooConfig.cmake"
INSTALL_DESTINATION ${ZOO_CMAKE_INSTALL_DIR}
)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/LibZooConfig.cmake"
DESTINATION ${ZOO_CMAKE_INSTALL_DIR}
)