Supporting configurations with ExternalProject_Add and Boost - boost

I'm currently building Boost via ExternalProject_Add with this command:
ExternalProject_Add(Boost
PREFIX workspace/Boost
URL http://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz
URL_MD5 51528a0e3b33d9e10aaa311d9eb451e3
UPDATE_COMMAND ./bootstrap.sh
CONFIGURE_COMMAND ""
BUILD_COMMAND ./b2 --layout=tagged link=static -s NO_BZIP2=1 cxxflags="-std=c++11" install
INSTALL_COMMAND ""
BUILD_IN_SOURCE 1
)
The problem is that this will always build both release and debug variants/configurations for boost, no matter which configuration I actually want to build. How can I "pass" the current configuration to the ExternalProject_Add command in this case?
This seems to just work when the "internal" build tool, i.e. the one called by ExternalProject_Add is also CMake. I have no idea how to pass that information to Boost's b2, however.
The above sample is for Windows / VisualStudio2013, so a multi configuration CMake target, but ideally, I'd have something that works for single configuration targets as well.

Related

cmake command issue while compile project of tbb

I tried using a demo to compile tbb in my project.
Link of the demo https://www.selectiveintellect.net/blog/2016/7/29/using-cmake-to-add-third-party-libraries-to-your-project-1
IDE for me is VS2013 and get an error about command 'make'
Performing build step for 'tbb44'
2> CMake Error at F:/CPPs/FAsT-Match-master/build/tbb44/src/tbb44-stamp/tbb44-build-Debug.cmake:49 (message):
2> Command failed: 2
2>
2> 'make' 'tbb_build_prefix=tbb44'
The original command is generated via tbb.cmake, for which it looks like
ExternalProject_Add(${TBB_PREFIX}
PREFIX ${TBB_PREFIX}
URL ${TBB_URL}
URL_MD5 ${TBB_URL_MD5}
CONFIGURE_COMMAND ""
# BUILD_COMMAND ${TBB_MAKE} -j${NCPU} tbb_build_prefix=${TBB_PREFIX}
BUILD_COMMAND ${TBB_MAKE} tbb_build_prefix=${TBB_PREFIX}
The one commented is the original and the one behind is modified.
Is this the problem of MSVC?
That blog post is just completely wrong. TBB comes with its own CMake build now, so there's absolutely no reason to go through ExternalProject like this.
Here's how I built it from source, using Visual Studio 2019 (the instructions should be pretty much the same). From a developer command prompt, using CMake 3.20:
D:\>git clone https://github.com/oneapi-src/oneTBB
D:\>cmake -S oneTBB -B oneTBB-build -DTBB_TEST=OFF
D:\>cmake --build oneTBB-build --config Release
D:\>cmake --build oneTBB-build --config Debug
D:\>cmake --install oneTBB-build --prefix oneTBB-install --config Release
D:\>cmake --install oneTBB-build --prefix oneTBB-install --config Debug
Setting TBB_TEST to OFF saves a lot of time waiting on TBB's tests to build. These commands install the Debug and Release binaries to D:\oneTBB-install. Of course, you can place this folder anywhere you like.
Once this is done, you may use your new TBB build from your project like so:
cmake_minimum_required(VERSION 3.20)
project(TBB-test)
find_package(TBB REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE TBB::tbb)
The TBB package also includes libraries TBB::tbbmalloc and TBB::tbbmalloc_proxy.
When you build your project, you may point find_package to your TBB installation by setting the CMake variable TBB_ROOT to D:/oneTBB-install at the command line via:
D:\>cmake -S myProject -B myProject-build -DTBB_ROOT=D:/oneTBB-install

How to build libgit2 with embedded libssh2 on Windows

First we build libssh2 with the WinCNG backend using msvc:
cmake . -DCRYPTO_BACKEND=WinCNG -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=%LIBSSH2%
cmake --build . --target install
libgit2 docs say all we have to do is to set DEMBED_SSH_PATH, although it fails to mentation what to set it to. Maybe it's so obvious that it seems irrelevant. However: I'm not a C guy and have no clue of the cmake build process. From what I understand the folder where the result of the previous built resides with all it's subfolders such as include and bin should be the correct path, so using %LIBSSH2% should be fine.
When finally trying to build libgit2 running
cmake . -DBUILD_CLAR=OFF -DCMAKE_BUILD_TYPE=Release -DEMBED_SSH_PATH=%LIBSSH2% -DCMAKE_INSTALL_PREFIX="%LIBGIT2%"
cmake --build . --target install
It'll fail because it's unable to find the links to the header files / binaries. We see things along the line of:
error LNK2019: unresolved external symbol libssh2_init referenced in function
I already tried replacing the paths backslashes \ with normal slashes /, since this seems to be a common issue. I also tried explicitly setting
set CMAKE_INCLUDE_PATH=%LIBSSH2%/include
set CMAKE_LIBRARY_PATH=%LIBSSH2%/lib
both faild with the same result.
Can anyone provide a reproducible way to compile libgit2 with embedded libssh2?
Using EMBED_SSH_PATH means libssh2 sources will be compiled at the same time as libgit2s. This means you don't actually have to compile libssh2 at all.
I managed to get it to compile successfully by downloading the source for libssh2 and libgit2, then running the following commands:
cd libgit2
mkdir build
cd build
cmake .. -DBUILD_CLAR=OFF -DCMAKE_BUILD_TYPE=Release -DEMBED_SSH_PATH="C:/path-to-ssh/libssh2" -DCMAKE_INSTALL_PREFIX="%LIBGIT2%"
cmake --build . --target install
Internally, it looks for all files that match ${EMBED_SSH_PATH}/src/*.cif EMBED_SSH_PATH is set.
As for using WinCNG as the backend, using embedded SSH creates this file (libssh2_config.h) in the libssh2 directory:
#define HAVE_WINCNG
#define LIBSSH2_WINCNG
#include "../win32/libssh2_config.h"
I assume that means it is already the default backend for an embedded install.

Use boost libraries in appveyor

I am writng a script for appveyor.
I need to use boost libraries in my c++ project.
In my appveyor script I have written these lines:
set INCLUDE=C:\Libraries\boost_1_67_0;%INCLUDE%
cd C:\Libraries\boost_1_67_0
dir
.\bootstrap.bat
.\b2 --with-iostreams runtime-link=static --build-type=complete
set LIB=C:\Libraries\boost_1_67_0\stage\lib;%LIB%
but that gives an error on .\bootstrap.bat
.\bootstrap.bat
Building Boost.Build engine
Failed to build Boost.Build engine.
Please consult bootstrap.log for further diagnostics.
Command exited with code 1
you could find the log of appveyor at https://ci.appveyor.com/project/srbcheema1/vcf-demo/build/1.0.32
my CMakeLists.txt is like :
cmake_minimum_required (VERSION 2.8.9)
project (reader-demo CXX C)
set (CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build" FORCE)
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(Boost_USE_STATIC_LIBS ON)
add_executable(reader uncompress.cpp)
how could I use the boost libraries in appveyor ?
There is no need to manually install a recent version of boost. It is already there and precompiled. Just make sure your to pass the correct path to your build configuration for using boost headers and the appropriate linkder flag. For a cmake build, this would be
cmake -DBOOST_ROOT=C:\Libraries\boost_1_67_0 path\to\your\source

make without makefile after cmake

I try to use the c++ language bindings for the ev3dev lego brick: https://github.com/ddemidov/ev3dev-lang-cpp
The instruction is as follows:
mkdir build
cd build
cmake .. -DEV3DEV_PLATFORM=EV3
make
I am running windows and have cmake and mingw available. After running cmake it creates some files in the build directory. However: There is no makefile which could be picked of by make. So I am wondering how iam supposed to compile these bindings
On Windows, CMake generates a MSVC solution by default. Check for a .sln file in your build directory.
The instructions you linked are assuming a Unix-ish platform, where the default is to create Makefiles.
If you actually want Makefiles on Windows, add -G "Unix Makefiles" to the cmake line.
If you want to use MSVC as compiler but work on the command line, another option is -G "NMake Makefiles", and calling nmake after that.
Make sure to delete your build directory before trying to build a new generator target. CMake can be touchy about that.
Check cmake --help for a list of available options. (Especially the generator targets are platform-specific.)

When does ExternalProject_Add build?

I want to build openssl and link my project against it. In my project, I have a library called net which is the part that uses openssl. So in my net\CMakeList, I added
include_directories(
../
+ ../../../ext/openssl/inc32/
)
add_library(net STATIC ${sources})
+ ADD_DEPENDENCIES(net openssl)
In my ext folder that is used for organizing all external library, I have a fresh unzipped openssl source code in a folder named openssl. Then I edited ext\CmakeList
message(STATUS "Configuring OpenSSL")
set(openssl_dir openssl)
if (CMAKE_CL_64)
include(ExternalProject)
set(OPENSSL_CONFIGURE perl\ Configure\ VC-WIN64A)
set(OPENSSL_MAKE ms\\do_win64a\ &&\ nmake\ -f\ ms\\ntdll.mak)
ExternalProject_Add(openssl
PREFIX openssl
#-- Download Step ----------
SOURCE_DIR ${CMAKE_SOURCE_DIR}/ext/openssl
#--Configure step ----------
CONFIGURE_COMMAND ${OPENSSL_CONFIGURE}
#--Build Step ----------
BUILD_COMMAND ${OPENSSL_MAKE}
BUILD_IN_SOURCE 1
#--install Step ----------
INSTALL_COMMAND ""}
)
endif()
When I built, the compiler complained the it can't find include files, and the openssl source code was not built at all, since there is no out32dll and inc32.
My question is: When does ExternalProject_Add actually build the project? If I make my net library depending on openssl, does it mean when I build net it would need to check and build openssl first?
ExternalProject use add_custom_target internally to create project and according to its document
By default nothing depends on the custom target. Use ADD_DEPENDENCIES
to add dependencies to or from other targets.
So if no project depend on it, it will not build by default.
When this ExternalProject_Add actually builds the project?
At build time(not at cmake time).
If I make my net library depends on openssl, does it mean when I build net it would need to check and build openssl first?
No. Since you make the dependency, cmake will handle it and openssl will be build before your library.
PS: There's still a lot of work to do. Because cmake doesn't know where the openssl result is, your project may run into link error. Here is a good example from the answer of "What is the best way to build boost with cmake".It use add_library with IMPORTED GLOBAL and set_target_properties with IMPORTED_LOCATION_* to solve the problem
Install missed
First of all I think you missed an install step. See documentation:
nmake -f "ms\ntdll.mak" install
So simplified version of ExternalProject_Add is:
ExternalProject_Add(
OpenSSL
URL https://github.com/openssl/openssl/archive/OpenSSL_1_0_1h.tar.gz
CONFIGURE_COMMAND perl Configure VC-WIN64A "--prefix=${CMAKE_INSTALL_PREFIX}"
BUILD_COMMAND "ms\\do_win64a.bat"
COMMAND nmake -f "ms\\ntdll.mak"
BUILD_IN_SOURCE 1
INSTALL_COMMAND nmake -f "ms\\ntdll.mak" install
)
Find OpenSSL
Second, if you want to find openssl libraries and headers, you need to use find_package(OpenSSL) command:
find_package(OpenSSL REQUIRED)
message("Libs: ${OPENSSL_LIBRARIES}")
message("Includes: ${OPENSSL_INCLUDE_DIR}")
Builds
Now, if you put all this commands together in one project configure step will fail :) Because it's not how ExternalProject designed. Superbuild that made by few or one ExternalProject_Add commands must be configured first, then build step will install the libraries from external archives. This will conflict with your project, because openssl libraries can't be found - they are not installed by superbuild yet.
Fix
Split cmake code. Run superbuild first (i.e. download and install openssl):
> cmake -Hsuperbuild -B_builds\superbuild "-GVisual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=ext\install
# note, no ext\install directory yet
> cmake --build _builds\superbuild
# install done, libraries can be found in ext\install
Then build your project, note that the libraries found on configure step:
> cmake -Huse -B_builds\use "-GVisual Studio 12 2013 Win64" -DCMAKE_INSTALL_PREFIX=ext\install
-- Found OpenSSL: .../ext/install/lib/ssleay32.lib;.../ext/install/lib/libeay32.lib (found version "1.0.1h")
Libs: .../ext/install/lib/ssleay32.lib;.../ext/install/lib/libeay32.lib
Includes: .../ext/install/include
> cmake --build _builds\use
# OK
Experimental
I have an experimental project that wrap all of this noise in one command (Windows tested on Visual Studio 2013):
hunter_add_package(OpenSSL)
find_package(OpenSSL REQUIRED)
https://github.com/ruslo/hunter

Resources