Home > database >  CMake: proper way to handle dependencies which require cmake themself ( crossplatform )
CMake: proper way to handle dependencies which require cmake themself ( crossplatform )

Time:12-09

What is the proper way to structure a project with dependencies that don't offer pre-build binaries ( or if you would want to build the dependencies yourself )

Normally I structure my projects as follows

/root/
 - Dependencies/
 - ...Subdirs...
 - Output/
 - CMakeLists.txt

Which is then cmade into the Output/, If an library is already build usually you can simply use find_package to use it as an dependency.

However if cmake has not been executed for each dependency, they won't have an <PackageName>Config.cmake and can thus not be found using find_package.

So the question is how do you organize a project if you want/have to build a dependency from source, on multiple platforms.

  • Use a script which builds all the dependencies
  • Make a cmake target which does something similar
  • Something else

And what if a dependency has another dependency which needs to be build as well.

Also for .ignore files it would be better if all dependencies where build/cmade into the Output/ directory

CodePudding user response:

Commonly libraries' CMakeLists.txt is configured to introduce a library target. That means that you can just add it to your own project and use almost the same way you use find_package dependencies. Assuming the project directory is something like this:

.
|-- CMakeLists.txt
|-- build
|-- src
|-- libs
|   |-- lib1Folder
|   `-- lib2Folder

And provided lib1 and lib2 have CMakeLists.txt configuration in their corresponding folders (lib1Folder and lib2Folder), you add them in your own CMakeLists.txt as follows:

add_subdirectory(libs/lib1Folder)
list(APPEND LIB_TARGETS lib1)
list(APPEND LIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libs/lib1Folder/include")

add_subdirectory(libs/lib2Folder)
list(APPEND LIB_TARGETS lib2)
list(APPEND LIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libs/lib2Folder/include")


target_include_directories(MyExecutable SYSTEM PRIVATE ${LIB_INCLUDE_DIRS})
target_link_libraries(MyExecutable PRIVATE ${LIB_TARGETS})

Where MyExecutable is name of the target you want to link the dependencies with. Of course different libs may have different configuration (some libs make include folders variable themselves, others may not do that and also don't have the include folder explicitly given), but this works for me personally most of the time.

CodePudding user response:

If the project is a cmake project, you can add it as a subdirectory and add it to the build with:

add_subdirectory(<src-dir> <build-dir>)

After that you can add the build targets as dependency to your project, so that cmake will build them if not present.For example if you want to use cpputest in your project, you add it to Dependencies/cpputest` and add it in cmake with

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Dependencies/cpputest ${CMAKE_CURRENT_BINARY_DIR}/cpputest)

All targets of cpputest will be build in a subdirectory in your build directory. After that you can add the cpputest library as dependency

target_link_libraries(my_binary CppUTest)`

If you build the my_binary, cpputest will be build automatically.

You can have a look at a project, where I used this: https://github.com/sweintritt/cora

Dependencies are added as submodules in the subdirectory third_party and added to the build in cmake/dependencies.cmake. The external build targets are then used in cmake/cora.cmake

  • Related