cmake FindBoost not finding Boost libraries when building with MinGW on Windows - c++

qtcreator supports both qmake and cmake for cross platform development and
qmake works fine for both msvc and MinGW builds on Windows. However, I'd prefer to support just one tool: cmake.
The CMakeLists.txt at via-httplib works fine on linux and when using cmake to build msvc on Windows.
However, when using cmake to build MinGW on Windows, I get the following error:
CMake Error at C:/Program
Files/CMake/share/cmake-3.13/Modules/FindBoost.cmake:2100 (message):
Unable to find the requested Boost libraries.
Boost version: 1.69.0
Boost include path: D:/DevLibraries/boost/boost_1_69_0
Could not find the following Boost libraries:
boost_system
No Boost libraries were found. You may need to set BOOST_LIBRARYDIR
to the directory containing Boost libraries or BOOST_ROOT to the
location of Boost.
Both the BOOST_LIBRARYDIR and BOOST_ROOT environment variables are set and are found when using the Visual Studio 15 2017 Win64 generator and default native compilers
The error message indicates that when using the MinGW Makefiles and default native compilers, cmake finds the BOOST_ROOT environment variable but not BOOST_LIBRARYDIR. So it does not seem to be the same problem described here: Cmake doesn't find Boost
Is this a bug in FindBoost.cmake? Is there a "work around"?

It is an issue with the _boost_ARCHITECTURE_TAG in FindBoost.cmake, described on line 1518.
The tag was added to handle Boost 1.66.0 and later versions.
It is not setting the _boost_ARCHITECTURE_TAG for MinGW to -x64, so it is searching for boost library names like:
libboost_system-mgw73-mt-d-1_69.a
instead of:
libboost_system-mgw73-mt-d-x64-1_69.a
There is a workaround: set the cmake variable: Boost_ARCHITECTURE to -x64.
Note: setting Boost_ARCHITECTURE as an environment variable does not work, as FindBoost.cmake does not read Boost_ARCHITECTURE as an environment variable.

Related

Cannot find boost libraries with cmake

I've install boost 1.63.0 on Windows and I am trying to build with CMake (using Visual Studio 2017 as a generator). I'm having trouble getting find_package() to find my boost libraries and I can't figure out why.
CMakeLists.txt:
find_package(Boost REQUIRED COMPONENTS system filesystem thread)
Output:
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.8/Modules/FindBoost.cm
ake:1813 (message):
Unable to find the requested Boost libraries.
Boost version: 1.63.0
Boost include path: C:/Program Files (x86)/boost/boost_1_63_0
Could not find the following Boost libraries:
boost_system
boost_filesystem
boost_thread
Some (but not all) of the required Boost libraries were found. You may
need to install these additional Boost libraries. Alternatively, set
BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT
to the location of Boost.
Boost finds the includes, but not the libraries. Headers are located at:
%BOOST_ROOT%. Libraries are located at %BOOST_ROOT%/stage/lib. When I look at _boost_LIBRARY_SEARCH_DIRS_RELEASE, the first place it looks is the correct location. I've also tried hard-coding BOOST_LIBRARYDIR to that path just to be sure.
To install boost I extracted the downloaded archive to %BOOST_ROOT%, then ran bootstrap and .\b2 link=static,shared threading=single,multi. This should give me all versions of the libraries. In the case of boost:system, I have the following binaries in %BOOST_ROOT%/stage/lib%:
boost_system-vc100-mt-1_63.dll
boost_system-vc100-mt-1_63.lib
boost_system-vc100-mt-gd-1_63.dll
boost_system-vc100-mt-gd-1_63.lib
libboost_system-vc100-mt-1_63.lib
libboost_system-vc100-mt-gd-1_63.lib
I've tried enabling and disabling the following, but to no avail:
set( Boost_USE_STATIC_LIBS ON )
set( Boost_USE_MULTITHREADED OFF )
set( Boost_DEBUG ON )
Here is an interesting part. The Boost_DEBUG parameter spits out this line:
Searching for SYSTEM_LIBRARY_RELEASE: boost_system-vc141-mt-1_63;boost_system-vc141-mt;boost_system-mt-1_63;boost_system-mt;boost_system
Note the vc141 versus vc100. I think .\b2 built something for vc100. That's strange because I was running it from the Dev Command Prompt for VS 2017. I've taken a wild guess and tried to build boost with ./b2 toolset=msvc-14.1 but I get an error: *** argument error * rule maybe-rewrite-setup ( toolset : setup-script : setup-options : version : rewrite-setup ? )".
How can I ensure that I compile boost with VS2017 or MSVC141?
This thread seems related:
Version numbers for Visual Studio 2017, Boost and CMake
Check the FindBoost.cmake script that is being used. Depending on the version of CMake you use, this version of Boost may not be handled. The dependencies between libraries is set depending on the version of Boost found.
For example the latest version of the script in CMake sources on GitHub handles version 1.63. I had the problem with CMake v3.6.2 which does not handle it.
Regarding the version mismatch for MSVC I don't know, sorry.
I compiled boost, and am compiling the linking application with the same toolset. Therefore I decided that it was safe to simply rename all compiled libs from *-vc100-* to *-vc141-*. While normally I would discourage that (you could get subtle differences in the ABI), in this case I was certain that it was the same compiler and so it's clear that either cmake or b2 had a bug which created(or searched) a file with the wrong name.
After doing that, cmake not only found boost, but linked successfully.

CMake FindBoost module and Boost C++ libraries built with BOOST_LIB_BUILDID

Is it possible to specify the BOOST_LIB_BUILDID for an already built Boost C++ library with the CMake FindBoost module?
I am supposed to use a Boost library that is built for x86 and x64 in the same directory, whereas the x64 version has been built with the following b2 arguments:
-layout=versioned --buildid=x64
I couldn't find anything related to this in the official CMake documentation.

Cmake finds hdf5 but tries to link against dll on windows

I use find_package(HDF5 COMPONENTS CXX REQUIRED) in my CMAKE script to load the include directories and libraries of HDF5. Cmake tells me
Found HDF5: C:/Program Files/HDF_Group/HDF5/1.10.0/bin/hdf5_cpp.dll (found version "1.10.0") found components: CXX
And generates my visual studio solution.
I also use the library stored in ${HDF5_LIBRARIES} ${HDF5_CXX_LIBRARIES} for my target, but when I try to build it, I get a Linker Error LNK1107 saying that for file hdf5_cpp.dll:
invalid or corrupt file: cannot read at 0x380
which I think is due to the fact that visual studio is trying to directly link against the dll file instead of against the lib file which is in another folder, namely in:
C:\Program Files\HDF_Group\HDF5\1.10.0\lib
Question: Is this a bug in FindHDF or did I configure something wrong?
I have not used hdf5 on windows for some time, but I do recall there being a bug that causes it to link against the dll instead of the lib.
you should manually set (either via the command line cmake -D method, or via the cmake gui)
HDF5_hdf5_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5.lib
HDF5_hdf5_cpp_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5_cpp.lib
etc. - or just
HDF5_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5.lib
HDF5_cpp_LIBRARY=C:\Program Files\HDF_Group\HDF5\1.10.0\lib\libhdf5_cpp.lib
depending on whether you have an older or newer version of FindHDF5 (they change the library var names in newer versions - check the ones used to make sure you get them right - I'm doing this from memory so might have made a mistake)
EDIT:
If the option of manaully specifying the libs is a problem, then there is the option of using FindPackage(HDF5 NO_MODULE) if your hdf5 library was compiled using cmake generated makefilesetc.
When using NO_MODULE, the find package scripts will bypass the findhdf5.cmake script and look for the HDF5Config.cmake or hdf5-config.cmake file that is placed in the relevant subdir of the hdf5 build/install folfer.
This is cross platform friendly and is supported by all newer hdf5 versions - provided they were built using cmake and not ./configure ...

Possible causes for Boost not being found by CMake in certain situations?

I build a C++ project depending on the Boost library using CMake (3.4.1). Host platform is Linux, targets are that host and cross-build Android NDK.
I'm only using Boost header files and I just downloaded/extracted the boost folder (and I don't have a /usr/include/boost directory).
In my CMakeLists.txt file I declare the dependency to Boost like this:
find_package(Boost 1.57 REQUIRED)
And I configure my build like this:
BOOST_ROOT=/path/to/boost cmake ../src
Which actually works as expected for my native build.
When I now configure a build exactly the same way (only specifying some more environment variables and a CMAKE_TOOLCHAIN_FILE) CMake gives me:
BOOST_ROOT=/path/to/boost JAVA_HOME=/bla/bla/bla \
ANDROID_NDK=/bla/bla/bla \
ANDROID_SDK=/bla/bla/bla \
ANT=/usr/bin/ant \
cmake ../src -DCMAKE_TOOLCHAIN_FILE=/bla/bla/android.toolchain.cmake
CMake Error at /usr/share/cmake/Modules/FindBoost.cmake:1247 (message):
Unable to find the requested Boost libraries.
Unable to find the Boost header files. Please set BOOST_ROOT to the root
directory containing Boost or BOOST_INCLUDEDIR to the directory containing
Boost's headers.
Call Stack (most recent call first):
CMakeLists.txt:4 (find_package)
So I believe I did almost the same to build for the Android target but the very same method that finds Boost for the host-build doesn't work here.
I tried to set Boost_DIR, BOOSTROOT and BOOST_INCLUDEDIR all with the same effect. Also I've deleted all content in the build directory before trying anything new.
What can be possible reasons for this behavior? I've already tried to print BOOST_ROOT directly in the FindBoost.cmake script like this:
message("BOOST_ROOT: $ENV{BOOST_ROOT}")
With the expected behavior (writing BOOST_ROOT: /path/to/boost).
Of course I can cheat now and just link the boost folder into the include folder of the cross compiler but that's not nice of course and I want to find out what's going on.
When cross-compiling, the toolchain file normally sets the variable CMAKE_FIND_ROOT_PATH. Combined with the CMAKE_FIND_ROOT_PATH_MODE_LIBRARY variable set to ONLY, CMAKE_FIND_ROOT_PATH variable is used as effective chroot for find_library calls, so only libraries under the given prefix(es) are searched.
Analogue variables exist to adjust the behavior for find_path (used for searching include paths) and find_program.
THe toolchain file you use actually sets CMAKE_FIND_ROOT_PATH at line 1521:
set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_ROOT}/bin"
"${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN_MACHINE_NAME}"
"${ANDROID_SYSROOT}"
"${CMAKE_INSTALL_PREFIX}"
"${CMAKE_INSTALL_PREFIX}/share" )
and below sets CMAKE_FIND_ROOT_PATH_MODE_* variables to ONLY. So you need to have Boost installed under one of these directories, and give hints (like BOOST_ROOT) relative to it.
Note, that Boost should be built for the target platform (Android NDK in you case), not for the platform where you cross-compile (Linux).

C++ cmake errors BOOST_ROOT DOXYGEN

I am trying to build a c++ implementation of hidden markov models - downloaded from
http://www.cs.au.dk/~asand/?page_id=152
I am compiling this on an ubuntu 12.04 with a g++ 4.6 compiler.
Following the instructions mentioned on the webpage, on typing
cmake .
I get the following errors,
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
CMake Error at CMakeLists.txt:101 (message):
The Boost C++ libraries was not found. Get Boost from
http://www.boost.org/ or set the environment variable BOOST_ROOT to point
to the root of boost directory.
Could someone help me resolve these issues out.
My boost folder is situated at
/usr/local/boost_1_52_0
It's telling you to set BOOST_ROOT environment variable. So just do it:
BOOST_ROOT=/usr/local/boost_1_52_0 cmake
(prefixing a command with setting of an environment variable in posix shell sets it for just that command; cmake will remember the value in CMakeCache.txt afterwards)
I suppose the fact it didn't find doxygen does not matter. You will should still be able to build the library, you just won't be able to generate nice documentation for it, but that probably exists on the web somewhere or you can read it in the headers directly anyway.