Comments (11)
So my current understanding is:
- For Boost ≤ 1.69, we can specify the location with
BOOST_ROOT
as a command line parameter,set()
, or environment variable. - The world is ❤️ 🌷 🌞 😎 👍
- But from ≥ Boost 1.70, it will start preferring to use "config mode", meaning it will silently ignore the
BOOST_ROOT
if we specify it via the command line orset()
. - But it will continue heeding it if we specify it via an environment variable.
- But the new config mode will find Boost directories in new places (eg
/opt
) and these will silently override ourBOOST_ROOT
, even if specified via an environment variable (that it otherwise heeds). - To revert to the previous, non "config mode" behaviour, we must specify
Boost_NO_BOOST_CMAKE=ON
- But this must be specified via a command line parameter or
set()
; if we specify it via an environment variable, it will be silently ignored. - To specify the location under "config mode", we can specify
Boost_DIR
- But this must be specified as an environment variable or
set( Boost_DIR <value> CACHE )
; if it is specified via the command line or the a plainset( Boost_DIR <value )
, it will be silently ignored. - There is further complexity with
Boost_ROOT
(the same asBOOST_ROOT
?) and the version of cmake we're using and the version of cmake we've required. - The world is 💔 🔥 ⛈️ 😕 👎
Does that sound about right?
To me, this story, even if only rougly accurate is a recipe for much confusion and frustration. I'm happy to raise issues against CMake if that might help but I'm unclear about what can be plausibly fixed. In particular, what are issues in FindBoost.cmake
rather than fundamental issues with the CMake architecture?
from boost_install.
Dang even with this great help after 4 hours I still cannot get my Centos7 gcc 8.2 static build of Boost 1.72 to be found from CMake 3.15.
Arrrgghh!
Update: I had to set via shell environment variable
export Boost_DIR=/opt/boost/boost_1_72_0/stage/lib/cmake
It also worked via the ENV trick in the toolchain file.
from boost_install.
More info in case it helps…
I'm testing with a CMakeLists.txt
like this:
cmake_minimum_required( VERSION 3.7 )
project( cmake-boost-problems )
find_package( Boost 1.68.0 REQUIRED program_options )
add_executable( example_exe example_exe.cpp )
target_link_libraries( example_exe Boost::program_options )
…and a C++ file like this:
#include <iostream>
#include <boost/program_options.hpp>
using ::boost::program_options::notify;
using ::boost::program_options::options_description;
using ::boost::program_options::parse_command_line;
using ::boost::program_options::store;
using ::boost::program_options::value;
using ::boost::program_options::variables_map;
using ::std::cout;
int main(int ac, char **av) {
::std::cout << "Hello world\n";
// Declare the supported options.
options_description desc("Allowed options");
desc.add_options()("help", "produce help message")(
"compression", value<int>(), "set compression level");
variables_map vm;
store(parse_command_line(ac, av, desc), vm);
notify(vm);
if (vm.count("help")) {
cout << desc << "\n";
return 1;
}
if (vm.count("compression")) {
cout << "Compression level was set to " << vm["compression"].as<int>()
<< ".\n";
} else {
cout << "Compression level was not set.\n";
}
}
I'm using program_options so that I get obvious link errors on attempts to link against the wrong Boost (GCC+libstc++ / Clang+libc++).
I'm using invocations like:
/some/specific/cmake -Bcmbi-clang -DBOOST_ROOT=/opt/obscure/boost_1_70_0_clang_c++14_build -H. -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -DCMAKE_CXX_FLAGS=-stdlib=libc++
/some/specific/cmake -Bcmbi-gcc -DBOOST_ROOT=/opt/obscure/boost_1_70_0_gcc_c++14_build -H. -DCMAKE_BUILD_TYPE=RELEASE
I'm using cmake
from the Linux-x86_64.tar.gz
downloads on https://cmake.org/download. I'm running on Ubuntu 18.04.2.
from boost_install.
find_package
has two modes, "module mode", using FindBoost.cmake, and "config mode", using BoostConfig.cmake. The default is module mode, but FindBoost has logic to automatically find and use a config file. This is documented here: https://cmake.org/cmake/help/v3.15/module/FindBoost.html#boost-cmake
If you want to disable the use of BoostConfig (installed by 1.70), set Boost_NO_BOOST_CMAKE=ON
. If you want to keep using BoostConfig, but control the directory in which it's found, set Boost_DIR
, which is the documented mechanism to control the search. See https://cmake.org/cmake/help/v3.15/command/find_package.html#search-procedure
For this specific use case, you may consider building and installing Boost with --layout=versioned
, in which case the gcc
and clang
libraries can go into a single directory; BoostConfig will select the correct libraries based on the CMake compiler id.
from boost_install.
Thanks very much for your very quick and very helpful response.
I think your explanation is much clearer than the ones in the documentation to which you linked - even after you've highlighted the relevant sections, I can barely make out the solution to my problem from it.
I feel like many people are likely to hit this sort of issue and will, like me, waste a lot of time wondering what they've done wrong. Is there some way we could try to mitigate this? Could the config mode detect when BOOST_ROOT
has been specified an print a helpful warning message?
From my experiments, I think I'm finding that:
- for
Boost_NO_BOOST_CMAKE
, it will be heeded if specified via a command-line flag of-DBoost_NO_BOOST_CMAKE=ON
but ignored if via an environment variable - for
Boost_DIR
, it will be heeded if specified via an environment variableBoost_DIR=/my/dir
but ignored if via command line flag
Is that correct? Is it possible to make both work via both?
Thanks very much for all your work on this really important area. It's much appreciated.
from boost_install.
For reference (potentially for other people that may stumble across this issue), I'm finding these toolchain files (-DCMAKE_TOOLCHAIN_FILE=file.cmake
) do the trick:
clang-168.toolchain.cmake
:
set( Boost_NO_BOOST_CMAKE ON )
set( BOOST_ROOT /opt/boost_1_68_0_clang_c++14_build )
set( CMAKE_BUILD_TYPE RELEASE )
set( CMAKE_C_COMPILER /usr/bin/clang )
set( CMAKE_CXX_COMPILER /usr/bin/clang++ )
set( CMAKE_CXX_FLAGS -stdlib=libc++ )
clang-170.toolchain.cmake
:
set( ENV{Boost_DIR} /opt/boost_1_70_0_clang_c++14_build )
set( CMAKE_BUILD_TYPE RELEASE )
set( CMAKE_C_COMPILER /usr/bin/clang )
set( CMAKE_CXX_COMPILER /usr/bin/clang++ )
set( CMAKE_CXX_FLAGS -stdlib=libc++ )
gcc-168.toolchain.cmake
:
set( Boost_NO_BOOST_CMAKE ON )
set( BOOST_ROOT /opt/boost_1_68_0_gcc_c++14_build )
set( CMAKE_BUILD_TYPE RELEASE )
gcc-170.toolchain.cmake
:
set( ENV{Boost_DIR} /opt/boost_1_70_0_gcc_c++14_build )
set( CMAKE_BUILD_TYPE RELEASE )
from boost_install.
I think that set(Boost_DIR "/my/dir")
needs CACHE
in order to work.
There is also the option of using Boost_ROOT
, both as an environment variable and a CMake variable. The subtlety there is that pre-3.12, it's ignored for compatibility reasons. In other words, cmake_minimum_required(3.7)
will turn it off. See https://cmake.org/cmake/help/v3.15/policy/CMP0074.html#policy:CMP0074
This is all CMake behavior, we have no control over it.
from boost_install.
No control, that is, apart from filing issues against CMake. :-)
https://gitlab.kitware.com/cmake/cmake/issues?scope=all&utf8=%E2%9C%93&state=opened&search=boost
from boost_install.
To confuse matters further, BOOST_ROOT
is not the same as Boost_ROOT
. The former is what FindBoost.cmake
looks at; the latter is what CMake looks at (<PACKAGE>_ROOT
, with <PACKAGE>
being Boost
in our case - the argument given to find_package
).
Since FindBoost.cmake
was written before the CMake naming conventions were established, it deviates from them. It arguably should be changed to look at Boost_ROOT
, if it doesn't already, but even so, we can't retroactively fix older CMake versions.
from boost_install.
I suppose that FindBoost.cmake
can be changed to look for BoostConfig.cmake in BOOST_ROOT
, when that is set, via something like find_package(Boost CONFIG PATHS ${BOOST_ROOT})
. You could try filing a CMake issue to that effect.
from boost_install.
* To specify the location under "config mode", we can specify `Boost_DIR` * But this must be specified as an environment variable or `set( Boost_DIR <value> CACHE )`; if it is specified via the command line or the a plain `set( Boost_DIR <value )`, it will be silently ignored.
You could also add the path you would otherwise set in a Boost_DIR
cache-variable to the list stored in the CMAKE_PREFIX_PATH
variable (no need for a cache-variable) before trying to locate Boost in "config mode".
The only side-effect is, that if you do not restore the former value of CMAKE_PREFIX_PATH
afterwards other calls to find_package
for other libraries might also consider that path (and might find non-desired versions in that path).
Then again you could always use the PATHS
or HINTS
option of find_package
to point to a search-location.
from boost_install.
Related Issues (20)
- Versioned symlinks are now installed, but used to not be
- PDB files should be installed along with DLLs HOT 1
- staging-prefix not respected by cmake files HOT 3
- Non-boost dependencies included in INTERFACE_LINK_LIBRARIES for shared libraries HOT 9
- Some CMake options are not marked as advanced HOT 1
- cmake configs don't allow static vs shared library paths
- Building without a library seems to install its headers HOT 2
- Boost_USE_STATIC_RUNTIME when not set should be autodetected from CMAKE_MSVC_RUNTIME_LIBRARY
- Why is "BOOST_ALL_NO_LIB" set automatically? HOT 12
- Boost.Stacktrace libraries are not being installed by `b2 install` HOT 2
- BoostDetectToolset.cmake needs to be updated to support detection of vc143 toolset with MSVC 2022 HOT 3
- IntelLLVM is not supported HOT 8
- boost_mpi tries to find the C++ MPI API HOT 1
- boost's cmake config files are not compatible with clang-cl HOT 4
- Boost_COMPILER should accept a list HOT 1
- Exported CMake config should use thirdparty lib targets and preferably find them on its own HOT 1
- boost_install license HOT 1
- Boost_USE_STATIC_LIBS deviates from FindBoost.cmake behaviour HOT 5
- Missing MPI::MPI_C dependency in boost::mpi targets HOT 1
- [boost1.68]Specifying more parameters will not generate cmake files HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from boost_install.