Build dependency in CMake
cmake
Solution
Take a look at the ExternalProject module:
The 'ExternalProject_Add' function creates a custom target to drive download, update/patch, configure, build, install and test steps of an external project
Note that this will only create a utility target. That is, you may run the target to build the library and you may add dependencies from your project's targets to the utility target. You can not however link to the target directly.
You still need to obtain the paths to the library and include directories of the external project manually. Since the project in question does not seem to use CMake by itself, that means writing your own calls to `find_library`, `find_path`, etc. and use the results from those calls to properly integrate the dependency.
Since the external project is built as part of your normal CMake run it should be quite easy to obtain the correct values by searching in the install path given to `ExternalProject_Add`.
However, there is an additional complication: The build managed by `ExternalProject` will execute as part of the build of your enclosing project, but for the `find_*` calls to succeed, it needs to be able to find the library files already during the CMake configure run (so before you start building). You have two options to resolve this:
- Hardcode the library paths for the external project into your build. This really only works for the most simple cases and is not recommended in general. In particular for dependencies that provide CMake config files as part of their install step, you will lose a lot of information from the original build that you will have to painfully replicate in the enclosing project's build configuration.
- Run `ExternalProject` not as part of your build, but move it to its own CMake project that you configure and build during the initial CMake configuration of your enclosing project. That way, when CMake reaches the `find_package` call, the dependency has already been fully built and installed within your CMake binary directory. The disadvantage here is that the external project is only built once when running CMake and will not automatically rebuild when you touch one of the external project's source files. In most cases you won't touch the sources of external dependencies anyway, so this is not a problem, but be aware of this limitation.
Problem
I want to build and use Botan linked statically in my application, which means first ``` python configure.py --disable shared ``` followed by ``` make ``` And then I'd like to create a dependency target for libbotan.a as "libbotan" that I can use in the rest of my CMake files. Since Botan not using CMake I'm not sure how to include the dependency in my project. My current attempt looks like this: in deps/Botan.1.11.7/CmakeLists.txt ``` add_custom_command(OUTPUT botan-configure COMMAND ./configure.py --disable-shared) add_custom_command(OUTPUT botan-build COMMAND make DEPENDS botan-configure) add_custom_target(botan DEPENDS botan-configure botan-build) ``` but when I added botan as a dependency in core/CMakeLists.txt like this ``` add_executable(console console.cpp) target_link_libraries(console messages core botan ${Boost_LIBRARIES}) ``` I get ``` CMake Error at simpleclient/CMakeLists.txt:5 (target_link_libraries): Target "botan" of type UTILITY may not be linked into another target. One may link only to STATIC or SHARED libraries, or to executables with the ENABLE_EXPORTS property set. ``` I tried using ExternalProject_Add like this ``` ExternalProject_Add(botan GIT_REPOSITORY https://github.com/randombit/botan.git CONFIGURE_COMMAND python configure.py --disable-shared BUILD_COMMAND make INSTALL_COMMAND make install ) ``` But that gives me the same error.