I am trying to install boost by ExternalProject_Add but I get error.
Question What does the error mean and how can I resolve it?
This is the error message I have:
Performing update step for 'boost-external'
No patch step for 'boost-external'
Performing configure step for 'boost-external'
'cp' is not recognized as an internal or external command,
operable program or batch file.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Msbuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(241,5): e
rror MSB8066: Custom build for 'C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeFiles\7a303cde471
9f69085ebded4413f3304\boost-external-mkdir.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeF
iles\7a303cde4719f69085ebded4413f3304\boost-external-download.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02
_Boost\build\CMakeFiles\7a303cde4719f69085ebded4413f3304\boost-external-update.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super
_build\Example_02_Boost\build\CMakeFiles\7a303cde4719f69085ebded4413f3304\boost-external-patch.rule;C:\IBOIS57\_Code\Software
\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeFiles\7a303cde4719f69085ebded4413f3304\boost-external-configure.rule;C:\IB
OIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeFiles\7a303cde4719f69085ebded4413f3304\boost-external-
build.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeFiles\7a303cde4719f69085ebded4413f3304
\boost-external-install.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeFiles\1a2a6d9ea64ba5
92f97cd191c1d5acb1\boost-external-complete.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\CMakeF
iles\a70b522e33d20f4a0fb02fd1b3fdb173\boost-external.rule;C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\CM
akeLists.txt' exited with code 9009. [C:\IBOIS57\_Code\Software\CPP\CMAKE\super_build\Example_02_Boost\build\boost-external.v
cxproj]
This is the screenshot:
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/HyrKM.jpg
This is my full CMakeLists.txt
###############################################################################
#cmake + project name
###############################################################################
cmake_minimum_required(VERSION 3.10)
project(boostdemo)
###############################################################################
#create executable
###############################################################################
add_executable(boostdemo ${PROJECT_SOURCE_DIR}/main.cpp)
###############################################################################
#boost
###############################################################################
#https://github.com/BBO-repo/cpp-boost-cmake-superbuild
set( Boost_Bootstrap_Command ${CMAKE_BINARY_DIR}/boost-download/src/boost-external/bootstrap.sh && cp ${CMAKE_BINARY_DIR}/boost-download/src/boost-external-build/b2 ${CMAKE_BINARY_DIR}/boost-download/src/boost-external/)
set( Boost_b2_Command cd ${CMAKE_BINARY_DIR}/boost-download/src/boost-external && ./b2 )
include(ExternalProject)
ExternalProject_Add(
boost-external #library name that will be used for linking in the executable
GIT_REPOSITORY https://github.com/boostorg/boost.git
GIT_TAG boost-1.79.0
PREFIX boost-download
CONFIGURE_COMMAND ${Boost_Bootstrap_Command}
BUILD_COMMAND ${Boost_b2_Command} install
--without-python
--without-mpi
--disable-icu
--prefix=${CMAKE_SOURCE_DIR}/thirdparty/boost/
--threading=single,multi
--link=shared
--variant=release
-j12
INSTALL_COMMAND ""
)
set(Boost_LIBS ${CMAKE_SOURCE_DIR}/thirdparty/boost/lib/${CMAKE_STATIC_LIBRARY_PREFIX}boost_chrono${CMAKE_SHARED_LIBRARY_SUFFIX})
set(Boost_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/thirdparty/boost/include/)
###############################################################################
#link boost
###############################################################################
add_dependencies(boostdemo boost-external)
include_directories(boostdemo ${Boost_INCLUDE_DIR})
target_link_libraries(boostdemo ${Boost_LIBS})
In case it helps someone, below is the cmake fragment I used to have for obtaining boost with ExternalProject_Add. I was focussed at the time on the header only parts so it may not be complete.
I was never entirely happy with this and in the end switched to obtaining all of our third party dependencies with vcpkg. I have been much happier ever since, especially with regard to boost. In fact I just deleted this file from our repo. So I strongly recommend looking at vcpkg (or conan or ...) instead of ExternalProject_Add.
if(WIN32)
set( Boost_Bootstrap_Command bootstrap.bat )
set( Boost_b2_Command b2.exe )
set( Boost_version_dir /boost-1_77 )
else()
set( Boost_Bootstrap_Command ./bootstrap.sh )
set( Boost_b2_Command ./b2 )
set( Boost_version_dir "")
endif()
ExternalProject_Add(git_boost
URL https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.gz
BUILD_IN_SOURCE 1
CONFIGURE_COMMAND ${Boost_Bootstrap_Command}
BUILD_COMMAND ""
INSTALL_COMMAND ${Boost_b2_Command} --with-headers --with-math install --prefix=${CMAKE_CURRENT_BINARY_DIR}/boost
TEST_COMMAND ""
)
add_library(ours_boost INTERFACE)
add_library(ours::boost ALIAS ours_boost)
target_include_directories(ours_boost INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/boost/include${Boost_version_dir})
message(${CMAKE_CURRENT_BINARY_DIR}/boost/include${Boost_version_dir})
add_dependencies(ours_boost git_boost)
Related
I am building a project with Cmake and use FetchContent to manage dependencies. For several reasons I cannot depend on system-wide installed packages, so this package helps a lot. It allows me to do things like this:
cmake_minimum_required(VERSION 3.14)
project(dummy LANGUAGES C CXX)
include(FetchContent)
FetchContent_Declare(nlohmann
GIT_REPOSITORY https://github.com/onavratil-monetplus/json
GIT_TAG v3.7.3
)
FetchContent_MakeAvailable(nlohmann)
add_executable(dummy main.cpp)
target_link_libraries(dummy PUBLIC nlohmann_json::nlohmann_json)
Now this works nicely as long as the repo is a cmake project with CMakeLists.txt. I would love to use similar approach for non-cmake projects, such as Botan library. Apparently
FetchContent_Declare(botan
GIT_REPOSITORY https://github.com/onavratil-monetplus/botan
GIT_TAG 2.17.2
)
FetchContent_MakeAvailable(botan)
does not really do the job, the build doesnt run since its not a cmake project. One would consider adding
CONFIGURE_COMMAND "<SOURCE_DIR>/configure.py --prefix=<BINARY_DIR>"
BUILD_COMMAND "cd <SOURCE_DIR> && make"
or something similar to the declare command, yet the FetchContent docs explicitly says that these particular arguments are ignored when passed to FetchContent.
Now the struggle is obvious - how to properly use FetchContent in this scenario? I was considering using ExternalProject_Add after the fetchcontent, yet then fetchcontent seems useless (ExternalProject can download git repo as well). Moreover, I would like to use some of the targets of botan at config time (if it makes sense).
I'm facing the same problem. Since the Botan library does not use the CMake build system internally, we cannot use the Botan "targets". But it is possible to build the Botan library at CMake configure time and use library and header files. Here is my solution (minimal configuration, works only for MS Visual Studio):
cmake_minimum_required (VERSION 3.20)
if(WIN32)
if(NOT (${CMAKE_BUILD_TYPE} STREQUAL "Release"))
message(FATAL_ERROR "This configuration only works for a Release build")
endif()
# set paths
set(BOTAN_LIB_ROOT_DIR "${CMAKE_SOURCE_DIR}/external/botan")
set(BOTAN_LIB_REPOS_DIR "${BOTAN_LIB_ROOT_DIR}/repos")
set(BOTAN_LIB_FCSTUFF_DIR "${BOTAN_LIB_ROOT_DIR}/cmake-fetchcontent-stuff")
set(BOTAN_LIB_INSTALL_DIR "${BOTAN_LIB_ROOT_DIR}-install")
# download and unpack Botan library
include(FetchContent)
FetchContent_Declare(
botan
GIT_REPOSITORY https://github.com/randombit/botan.git
GIT_TAG 2.19.1
PREFIX ${BOTAN_LIB_FCSTUFF_DIR}
SOURCE_DIR ${BOTAN_LIB_REPOS_DIR}
)
set(FETCHCONTENT_QUIET OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(botan)
# find Python3 Interpreter and run build, testing and installation
if(${botan_POPULATED} AND MSVC AND NOT EXISTS "${BOTAN_LIB_INSTALL_DIR}/lib/botan.lib")
find_package(Python3 COMPONENTS Interpreter)
if(NOT ${Python3_Interpreter_FOUND})
message(FATAL_ERROR "Python3 Interpreter NOT FOUND")
endif()
execute_process(
COMMAND ${Python3_EXECUTABLE} configure.py --cc=msvc --os=windows --prefix=${BOTAN_LIB_INSTALL_DIR}
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake check
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake install
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
endif()
endif()
add_executable (main "main.cpp")
if(WIN32)
target_include_directories(main PUBLIC "${BOTAN_LIB_INSTALL_DIR}/include/botan-2")
target_link_libraries(main PUBLIC "${BOTAN_LIB_INSTALL_DIR}/lib/botan.lib")
configure_file("${BOTAN_LIB_INSTALL_DIR}/bin/botan.dll"
"${CMAKE_CURRENT_BINARY_DIR}/botan.dll"
COPYONLY
)
install(TARGETS main DESTINATION bin)
install(FILES "${BOTAN_LIB_INSTALL_DIR}/bin/botan.dll" DESTINATION bin)
endif()
Here is the full version: https://github.com/weenchvd/cmake-build-botan-lib
I'm trying to download externally the mongo-cxx-driver on Windows from the given github repositories, but unfortunately my knowledge of cmake is less to none. I found the next given script in one of the stackoverflow questions: Building mongo-cxx-driver using CMake ExternalProject_Add, but even when it seems to work, it doesn't work. It does make the given project but without the libraries. May someone help with creating those libraries through cmake, externally or internally after downloading the mongo-c-driver and the mongo-cxx-driver from the github repositories.
If someone could go through the needed steps I'd be delighted.
Also if boost could be removed from this equation, it would be good.
The CMakeLists.txt file:
cmake_minimum_required(VERSION 3.12)
set(CMAKE_CXX_STANDARD 11)
project(Test)
option(${PROJECT_NAME}_SUPERBUILD "Build ${PROJECT_NAME} and the projects it depends on." ON)
if(${PROJECT_NAME}_SUPERBUILD)
include(ExternalProject)
set(common_cmake_cache_args
-DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
)
if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
list(APPEND common_cmake_cache_args
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
)
endif()
ExternalProject_Add(libmongoc
GIT_REPOSITORY "https://github.com/mongodb/mongo-c-driver.git"
GIT_TAG "1.16.2"
GIT_PROGRESS 1
GIT_SHALLOW 1
SOURCE_DIR "${CMAKE_BINARY_DIR}/libmongoc"
BINARY_DIR "${CMAKE_BINARY_DIR}/libmongoc-build"
INSTALL_DIR "${CMAKE_BINARY_DIR}/libmongoc-install"
CMAKE_CACHE_ARGS
${common_cmake_cache_args}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongoc-install
-DENABLE_TESTS:BOOL=OFF
-DENABLE_STATIC:BOOL=OFF
-DENABLE_EXAMPLES:BOOL=OFF
-DENABLE_EXTRA_ALIGNMENT:BOOL=OFF
#INSTALL_COMMAND ""
)
set(libmongoc-1.0_DIR "${CMAKE_BINARY_DIR}/libmongoc-install/lib/cmake/libmongoc-1.0/")
set(libbson-1.0_DIR "${CMAKE_BINARY_DIR}/libmongoc-install/lib/cmake/libbson-1.0/")
ExternalProject_Add(libmongocxx
GIT_REPOSITORY "https://github.com/mongodb/mongo-cxx-driver.git"
GIT_TAG "r3.4.2"
GIT_PROGRESS 1
GIT_SHALLOW 1
SOURCE_DIR "${CMAKE_BINARY_DIR}/libmongocxx"
BINARY_DIR "${CMAKE_BINARY_DIR}/libmongocxx-build"
INSTALL_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install"
CMAKE_CACHE_ARGS
${common_cmake_cache_args}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongocxx-install
-DBUILD_SHARED_LIBS:BOOL=ON
-DENABLE_TESTS:BOOL=OFF
-DENABLE_EXAMPLES:BOOL=OFF
-DBSONCXX_POLY_USE_BOOST:BOOL=OFF
-DBSONCXX_POLY_USE_MNMLSTC:BOOL=ON
-DBSONCXX_POLY_USE_STD:BOOL=OFF
-Dlibmongoc-1.0_DIR:PATH=${libmongoc-1.0_DIR}
-Dlibbson-1.0_DIR:PATH=${libbson-1.0_DIR}
DEPENDS
libmongoc
)
set(libmongocxx_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install/lib/cmake/libmongocxx-3.4.2/")
set(libbsoncxx_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install//lib/cmake/libbsoncxx-3.4.2/")
function(ExternalProject_AlwaysConfigure proj)
# This custom external project step forces the configure and later
# steps to run.
_ep_get_step_stampfile(${proj} "configure" stampfile)
ExternalProject_Add_Step(${proj} forceconfigure
COMMAND ${CMAKE_COMMAND} -E remove ${stampfile}
COMMENT "Forcing configure step for '${proj}'"
DEPENDEES build
ALWAYS 1
)
endfunction()
ExternalProject_Add(${PROJECT_NAME}
SOURCE_DIR "${CMAKE_SOURCE_DIR}"
BINARY_DIR "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build"
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CMAKE_CACHE_ARGS
${common_cmake_cache_args}
-D${PROJECT_NAME}_SUPERBUILD:BOOL=OFF
-Dlibbsoncxx_DIR:PATH=${libbsoncxx_DIR}
-Dlibmongocxx_DIR:PATH=${libmongocxx_DIR}
INSTALL_COMMAND ""
DEPENDS
libmongocxx
)
ExternalProject_AlwaysConfigure(${PROJECT_NAME})
return()
endif()
message(STATUS "Configuring inner-build")
find_package(libmongocxx REQUIRED)
add_executable(test_mongocxx test.cpp)
target_link_libraries(test_mongocxx PUBLIC ${LIBMONGOCXX_LIBRARIES})
target_include_directories(test_mongocxx PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS})
target_compile_definitions(test_mongocxx PUBLIC ${LIBMONGOCXX_DEFINITIONS})
I am trying to add boost as an external project to my project. However when I add the URL to boosts releases and use their hash, I get a hash mismatch even if I have copied it straight from their website. Link here for latest release. Here is my boostExternal.cmake file:
#---------------------------------------------------------------------------
# Get and build boost
SET_PROPERTY(DIRECTORY PROPERTY "EP_BASE" ${ep_base})
SET(boost_GIT_TAG "origin/master")
set( Boost_Bootstrap_Command )
if( UNIX )
set( Boost_url "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz")
set( Boost_Hash "SHA256=882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9")
set( Boost_Bootstrap_Command ./bootstrap.sh )
set( Boost_b2_Command ./b2 )
elseif( WIN32 )
set( Boost_url "https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.zip")
set( Boost_Hash "SHA256=48f379b2e90dd1084429aae87d6bdbde9670139fa7569ee856c8c86dd366039d")
set( Boost_Bootstrap_Command bootstrap.bat )
set( Boost_b2_Command b2.exe )
endif()
ExternalProject_Add(Boost_external_Download
URL ${Boost_url}
URL_HASH ${Boost_Hash}
BUILD_IN_SOURCE 1
UPDATE_COMMAND ""
PATCH_COMMAND ""
CONFIGURE_COMMAND ${Boost_Bootstrap_Command}
BUILD_COMMAND ${Boost_b2_Command} install
--with-system
--with-chrono
--with-filesystem
--disable-icu
--prefix=${CMAKE_BINARY_DIR}/Boost
--threading=single,multi
--link=shared
--variant=release
-j8
INSTALL_COMMAND ""
INSTALL_DIR ""
)
#CACHE PATH "" seems to write the path to a file that I can set
#library paths to.
set(Boost_LIBRARY_DIR ${CMAKE_BINARY_DIR}/Boost/lib CACHE PATH "")
if(WIN32)
set(Boost_INCLUDE_DIR ${CMAKE_BINARY_DIR}/Boost/include/boost-1_70 CACHE PATH "")
set(BOOST_ROOT ${CMAKE_BINARY_DIR}/Boost)
else()
set(Boost_INCLUDE_DIR ${CMAKE_BINARY_DIR}/Boost/include CACHE PATH "")
endif()
ExternalProject_Get_Property(Boost_external_Download BINARY_DIR)
SET(Boost_DIR ${BINARY_DIR} CACHE PATH "")
add_library(Boost_external SHARED IMPORTED)
message(STATUS "Boost_DIR: ${Boost_DIR}")
But when I call this cmake file, I get the error:
-- verifying file...
file='/home/sailanarmo/Documents/build/Superbuild/Download/Boost_external_Download/boost_1_70_0.tar.gz'
-- SHA256 hash of
/home/sailanarmo/Documents/build/Superbuild/Download/Boost_external_Download/boost_1_70_0.tar.gz
does not match expected value
expected: '882b48708d211a5f48e60b0124cf5863c1534cd544ecd0664bb534a4b5d506e9'
actual: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
-- File already exists but hash mismatch. Removing...
Which doesn't make sense because I have put in the correct hash and the correct protocol within the .cmake file. However the actual doesn't seem to match what I have pasted in. Am I doing something wrong?
I found the reason.
When building CMake, you have to configure SSL support otherwise CMake will not allow the https protocol to be used. To do that you will need to configure CMake as the following:
./bootstrap --system-curl
make
sudo make install
This will use Linux's system curl which should be configured with SSL Support. However, instead of re-installing CMake manually. I decided to drop the s in the https. Which means I changed https://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz to http://dl.bintray.com/boostorg/release/1.70.0/source/boost_1_70_0.tar.gz and it downloaded and compiled just fine.
I am trying to build mongo-cxx-driver in a CMake based project. This project is supposed to build on Windows, macOS and in an ubuntu container and I want to ensure that my software on all these platforms will use the same driver version so I cannot afford installing the driver and its dependencies via apt-get, brew etc. So I am left with one option: ExternalProject_Add. But I am having difficulty making that work given how libmongoc is setup.
Below is the CMake module I currently have.
include(ExternalProject)
set(libmongoc_CMAKE_ARGS
"-DCMAKE_BUILD_TYPE:STRIING=${CMAKE_BUILD_TYPE}"
"-DENABLE_TESTS:BOOL=OFF"
"-DENABLE_STATIC:BOOL=OFF"
"-DENABLE_EXAMPLES:BOOL=OFF"
"-DENABLE_EXTRA_ALIGNMENT:BOOL=OFF"
)
set(mongocxx_CMAKE_ARGS
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_BUILD_TYPE:STRIING=${CMAKE_BUILD_TYPE}"
"-DBUILD_SHARED_LIBS:BOOL=ON"
"-DENABLE_TESTS:BOOL=OFF"
"-DENABLE_EXAMPLES:BOOL=OFF"
"-DBSONCXX_POLY_USE_BOOST:BOOL=ON"
"-DBSONCXX_POLY_USE_MNMLSTC:BOOL=OFF"
"-Dlibbson-1.0_DIR:PATH=${OTS_DEPDENDENCIES_DIR}/libmongoc/src/libbson"
)
if (NOT TARGET libmongoc)
ExternalProject_Add(
libmongoc
GIT_REPOSITORY "https://github.com/mongodb/mongo-c-driver.git"
GIT_TAG "1.12.0"
SOURCE_DIR "${OTS_DEPDENDENCIES_DIR}/libmongoc"
BINARY_DIR "${OTS_DEPDENDENCIES_DIR}/libmongoc"
CMAKE_ARGS "${libmongoc_CMAKE_ARGS}"
INSTALL_COMMAND ""
)
endif()
if (NOT TARGET mongocxx)
ExternalProject_Add(
mongocxx
GIT_REPOSITORY "https://github.com/mongodb/mongo-cxx-driver.git"
GIT_TAG "r3.3.1"
SOURCE_DIR "${OTS_DEPDENDENCIES_DIR}/mongocxx"
BINARY_DIR "${OTS_DEPDENDENCIES_DIR}/mongocxx"
CMAKE_ARGS "${mongocxx_CMAKE_ARGS}"
INSTALL_COMMAND ""
DEPENDS libmongoc
)
endif()
Note the CMAKE option libbson-1.0_DIR given as one of the CMAKE_ARGS for mongo-cxx-driver. I am skeptic about it and I believe that may be the culprit. With it I get the following error:
CMake Error at ${OTS_DEPENDENCIES_DIR}/libmongoc/src/libbson/libbson-1.0-config.cmake:30 (message):
File or directory
${OTS_DEPENDENCIES_DIR}/include/libbson-1.0
referenced by variable BSON_INCLUDE_DIRS does not exist !
Call Stack (most recent call first):
${OTS_DEPENDENCIES_DIR}/libmongoc/src/libbson/libbson-1.0-config.cmake:46 (set_and_check)
src/bsoncxx/CMakeLists.txt:81 (find_package)
which kind of makes sense because src/bsoncxx/CMakeLists.txt:81 reads:
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
set_and_check (BSON_INCLUDE_DIRS "${PACKAGE_PREFIX_DIR}/include/libbson-1.0")
which makes CMake end up looking for libbson-1.0 in ${OTS_DEPDENDENCIES_DIR}/include that does not exist. If only, I could tell cmake, "hey don't run this find_package" I can give you the path to INCLUDE_DIR, LIBRARIES and DEFINITIONS myself.
If I remove this option, I get the following error:
CMake Error at src/bsoncxx/CMakeLists.txt:81 (find_package):
By not providing "Findlibbson-1.0.cmake" in CMAKE_MODULE_PATH this project
has asked CMake to find a package configuration file provided by
"libbson-1.0", but CMake did not find one.
Could not find a package configuration file provided by "libbson-1.0"
(requested version 1.10.0) with any of the following names:
libbson-1.0Config.cmake
libbson-1.0-config.cmake
Add the installation prefix of "libbson-1.0" to CMAKE_PREFIX_PATH or set
"libbson-1.0_DIR" to a directory containing one of the above files. If
"libbson-1.0" provides a separate development package or SDK, be sure it
has been installed.
which is not very odd either because CMake tries to find_package libbson-1.0 but cannot figure out where it is installed.
preliminary remarks
While looking at the details, here are few preliminary comments:
Use different directory for SOURCE_DIR and BINARY_DIR
Instead of CMAKE_ARG, prefer CMAKE_CACHE_ARGS
libbson-1.0_DIR should NOT be set to a source directory, instead if should be set to a build directory containing a config-file package (link below provide more details about this concept)
Make sure to always specify the type of CMake argument (-DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} instead of -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER})
Do not set CMAKE_BUILD_TYPE for multi-configuration generator
Regarding this last point, this means that you should do the following:
set(EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS)
if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
list(APPEND EXTERNAL_PROJECT_OPTIONAL_CMAKE_CACHE_ARGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
)
endif()
In this post, you can learn how you could structure your project: Correct way to use third-party libraries in cmake project
working project allowing to compile the mongocxx "test.cpp"
Below is the content of CMakeLists.txt and test.cpp allowing to build an executable named <build-dir>/Test-build/test_mongocxx :
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
set(CMAKE_CXX_STANDARD 11)
project(Test)
option(${PROJECT_NAME}_SUPERBUILD "Build ${PROJECT_NAME} and the projects it depends on." ON)
if(${PROJECT_NAME}_SUPERBUILD)
include(ExternalProject)
set(common_cmake_cache_args
-DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER}
)
if(NOT DEFINED CMAKE_CONFIGURATION_TYPES)
list(APPEND common_cmake_cache_args
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
)
endif()
ExternalProject_Add(libmongoc
GIT_REPOSITORY "https://github.com/mongodb/mongo-c-driver.git"
GIT_TAG "1.12.0"
GIT_PROGRESS 1
GIT_SHALLOW 1
SOURCE_DIR "${CMAKE_BINARY_DIR}/libmongoc"
BINARY_DIR "${CMAKE_BINARY_DIR}/libmongoc-build"
INSTALL_DIR "${CMAKE_BINARY_DIR}/libmongoc-install"
CMAKE_CACHE_ARGS
${common_cmake_cache_args}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongoc-install
-DENABLE_TESTS:BOOL=OFF
-DENABLE_STATIC:BOOL=OFF
-DENABLE_EXAMPLES:BOOL=OFF
-DENABLE_EXTRA_ALIGNMENT:BOOL=OFF
#INSTALL_COMMAND ""
)
set(libmongoc-1.0_DIR "${CMAKE_BINARY_DIR}/libmongoc-install/lib/cmake/libmongoc-1.0/")
set(libbson-1.0_DIR "${CMAKE_BINARY_DIR}/libmongoc-install/lib/cmake/libbson-1.0/")
ExternalProject_Add(libmongocxx
GIT_REPOSITORY "https://github.com/mongodb/mongo-cxx-driver.git"
GIT_TAG "r3.3.1"
GIT_PROGRESS 1
GIT_SHALLOW 1
SOURCE_DIR "${CMAKE_BINARY_DIR}/libmongocxx"
BINARY_DIR "${CMAKE_BINARY_DIR}/libmongocxx-build"
INSTALL_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install"
CMAKE_CACHE_ARGS
${common_cmake_cache_args}
-DCMAKE_INSTALL_PREFIX:PATH=${CMAKE_BINARY_DIR}/libmongocxx-install
-DBUILD_SHARED_LIBS:BOOL=ON
-DENABLE_TESTS:BOOL=OFF
-DENABLE_EXAMPLES:BOOL=OFF
-DBSONCXX_POLY_USE_BOOST:BOOL=OFF
-DBSONCXX_POLY_USE_MNMLSTC:BOOL=ON
-DBSONCXX_POLY_USE_STD:BOOL=OFF
-Dlibmongoc-1.0_DIR:PATH=${libmongoc-1.0_DIR}
-Dlibbson-1.0_DIR:PATH=${libbson-1.0_DIR}
DEPENDS
libmongoc
)
set(libmongocxx_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install/lib/cmake/libmongocxx-3.3.1/")
set(libbsoncxx_DIR "${CMAKE_BINARY_DIR}/libmongocxx-install//lib/cmake/libbsoncxx-3.3.1/")
function(ExternalProject_AlwaysConfigure proj)
# This custom external project step forces the configure and later
# steps to run.
_ep_get_step_stampfile(${proj} "configure" stampfile)
ExternalProject_Add_Step(${proj} forceconfigure
COMMAND ${CMAKE_COMMAND} -E remove ${stampfile}
COMMENT "Forcing configure step for '${proj}'"
DEPENDEES build
ALWAYS 1
)
endfunction()
ExternalProject_Add(${PROJECT_NAME}
SOURCE_DIR "${CMAKE_SOURCE_DIR}"
BINARY_DIR "${CMAKE_BINARY_DIR}/${PROJECT_NAME}-build"
DOWNLOAD_COMMAND ""
UPDATE_COMMAND ""
CMAKE_CACHE_ARGS
${common_cmake_cache_args}
-D${PROJECT_NAME}_SUPERBUILD:BOOL=OFF
-Dlibbsoncxx_DIR:PATH=${libbsoncxx_DIR}
-Dlibmongocxx_DIR:PATH=${libmongocxx_DIR}
INSTALL_COMMAND ""
DEPENDS
libmongocxx
)
ExternalProject_AlwaysConfigure(${PROJECT_NAME})
return()
endif()
message(STATUS "Configuring inner-build")
find_package(libmongocxx REQUIRED)
add_executable(test_mongocxx test.cpp)
target_link_libraries(test_mongocxx PUBLIC ${LIBMONGOCXX_LIBRARIES})
target_include_directories(test_mongocxx PUBLIC ${LIBMONGOCXX_INCLUDE_DIRS})
target_compile_definitions(test_mongocxx PUBLIC ${LIBMONGOCXX_DEFINITIONS})
test.cpp (copied from https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/#step-6-test-your-installation):
#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
int main(int, char**) {
mongocxx::instance inst{};
mongocxx::client conn{mongocxx::uri{}};
bsoncxx::builder::stream::document document{};
auto collection = conn["testdb"]["testcollection"];
document << "hello" << "world";
collection.insert_one(document.view());
auto cursor = collection.find({});
for (auto&& doc : cursor) {
std::cout << bsoncxx::to_json(doc) << std::endl;
}
}
I have the following code in one of my CMakeLists.txt:
FIND_PACKAGE(sphinxbase)
if (${SPHINXBASE_FOUND})
INCLUDE_DIRECTORIES(${SPHINXBASE_INCLUDE_DIR}/sphinxbase/)
else ()
ExternalProject_Add(
sphinxbase
GIT_REPOSITORY "https://github.com/cmusphinx/sphinxbase.git"
GIT_TAG "e34b1c632392276101ed16e8a05862e43f038a7c"
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/sphinxbase
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lib/sphinxbase/autogen.sh
BUILD_COMMAND ${MAKE}
UPDATE_COMMAND ""
INSTALL_COMMAND ""
BUILD_IN_SOURCE ON
LOG_DOWNLOAD ON
LOG_UPDATE ON
LOG_CONFIGURE ON
LOG_BUILD ON
LOG_TEST ON
LOG_INSTALL ON
)
ExternalProject_Get_Property(sphinxbase SOURCE_DIR)
ExternalProject_Get_Property(sphinxbase BINARY_DIR)
SET(SPHINXBASE_SOURCE_DIR ${SOURCE_DIR})
SET(SPHINXBASE_BINARY_DIR ${BINARY_DIR})
SET(SPHINXBASE_LIBRARIES ${SPHINXBASE_BINARY_DIR}/src/libsphinxbase/.libs/libsphinxbase.a)
INCLUDE_DIRECTORIES(${SPHINXBASE_SOURCE_DIR}/include)
endif ()
SET(DEPENDENCIES ${DEPENDENCIES} sphinxbase)
SET(LIBS ${LIBS} ${SPHINXBASE_LIBRARIES})
In addition to the TARGET that I'm trying to install, how would I go about installing this ExternalProject? Right now I'm trying to do it like this:
install(TARGETS ${LIBS}
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
OPTIONAL
)
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
)
But I'm getting the following error thrown at me:
CMake Error at CMakeLists.txt:197 (install):
install TARGETS given target
"/Users/syb0rg/Dropbox/Development/Khronos/Khronos/lib/sphinxbase/src/libsphinxbase/.libs/libsphinxbase.a"
which does not exist in this directory.
Any suggestions?
Command flow install(TARGETS) installs targets, which are created with add_executable or add_library commands. For install concrete files, you need to use command flow install(FILES).
Instead of installing selected files from subproject's build directory, you may install subproject as is. For that you can use
make DESTDIR=<...> install
command as INSTALL option of ExeternalProject_Add. This command will install whole subproject into directory given as DESTDIR parameter for make (more information about this parameter can be found here).
Then you may use install(DIRECTORY) command for install all subproject's files at once:
# It is better to use binary directory for download or build 3d-party project
set(sphinxbase_SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib/sphinxbase)
# This will be used as DESTDIR on subproject's `make install`.
set(sphinxbase_DESTDIR ${CMAKE_CURRENT_BINARY_DIR}/lib/sphinxbase_install)
ExternalProject_Add(
sphinxbase
GIT_REPOSITORY "https://github.com/cmusphinx/sphinxbase.git"
GIT_TAG "e34b1c632392276101ed16e8a05862e43f038a7c"
SOURCE_DIR ${sphinxbase_SOURCE_DIR}
# Specify installation prefix for configure.sh (autogen.sh).
CONFIGURE_COMMAND ./autogen.sh --prefix=${CMAKE_INSTALL_PREFIX}
BUILD_COMMAND ${MAKE}
UPDATE_COMMAND ""
# Fake installation: copy installed files into DESTDIR.
INSTALL_COMMAND make DESTDIR=${sphinxbase_DESTDIR} install
...
)
# Actually install subproject.
install(
DIRECTORY ${sphinxbase_DESTDIR}/
DESTINATION "/"
USE_SOURCE_PERMISSIONS # Remain permissions (rwx) for installed files
)
Note, that root directory is used as DESTINATION. This is because files under sphinxbase_DESTDIR directory already located in accordance to CMAKE_INSTALL_PREFIX, which is passed as --prefix option to configure.sh (autogen.sh in the given case).
If you know, that subprojects installs its files only under installation prefix (given by --prefix), you can make main project installation more packaging-friendly:
install(
DIRECTORY ${sphinxbase_DESTDIR}/${CMAKE_INSTALL_PREFIX}/
DESTINATION "."
USE_SOURCE_PERMISSIONS
)
Because now relative path is used for DESTINATION option, the project will correctly support packaging. For example, make DESTDIR=<...> install will work for main project too.
Note, that even if ExternalProject_Add is used for build CMake subproject, targets created in this subroject are not seen by the main project.