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