From b7b2ea7513b087e35c6f1b26184a3904ac1e6b14 Mon Sep 17 00:00:00 2001 From: Eduard Valeyev Date: Thu, 25 Jan 2024 16:15:23 -0500 Subject: [PATCH] bump VG CMake kit to pull in https://github.com/ValeevGroup/kit-cmake/commit/034167146dc9ad28db07f5f726635693e1ec4a45 and try to make install of Boost built from source work "correctly" ... when building Boost a main project to install BTAS when building Boost from source need to build `build-boost-in-BTAS` target before trying to install --- README.md | 23 +++++++++++++++++++---- external/boost.cmake | 25 ++++++++++++++++++++++++- external/versions.cmake | 2 +- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 311fe062..e424fab1 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,34 @@ Prerequisites * C++17 compiler * CMake * Boost C++ libraries - - Iterator - - (optional, but recommended) Container for fast small vectors + - (required) Container, Iterator, Random - (optional) Serialization for serialization (non-header-only) * (used by default, strongly recommended, but can be disabled) BLAS+LAPACK libraries and their BLAS++/LAPACK++ C++ APIs for optimized operations (non-header-only) Building and Installing ======================= TL;DR version -* cmake . -* make check +* `cmake -S /path/to/BTAS/srcdir -B /path/to/BTAS/builddir -DCMAKE_PREFIX_PATH="/path/to/boost;/path/to/blas/and/lapack"` +* optional: `cmake --build /path/to/BTAS/builddir --target check` +* if configured with `-DBTAS_BUILD_DEPS_FROM_SOURCE=ON`: `cmake --build /path/to/BTAS/builddir --target build-boost-in-BTAS` +* `cmake --build /path/to/BTAS/builddir --target install` + +## obtaining prerequisites +* Linear algebra (BLAS+LAPACK): should come with your dev toolchain (e.g., on MacOS) or can be installed using the system package manager or as a vendor-provided package (e.g., Intel Math Kernel Libraries) +* Boost: + - It is recommended to use a package manager to install Boost. This can be doneas follows: + - APT package manager (e.g., on Ubuntu Linux): `apt-get install libboost-all-dev` + - Homebrew package manager (on MacOS) via `brew install boost`. + - You can also try to build Boost yourself by following instructions [here](https://www.boost.org/doc/libs/1_84_0/more/getting_started/unix-variants.html). + - Last resort is to let BTAS build Boost from source, as a CMake _subproject_ using [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html). Unfortunately, Boost's [emerging CMake harness](https://github.com/boostorg/cmake/) used to build it is not yet fully functional, hence may not be as robust as desired. Here are some ints: + - Configure with CMake cache variable `BTAS_BUILD_DEPS_FROM_SOURCE` to `ON` (either via command line or the `ccmake` GUI) + - If BTAS is the top-level CMake project (i.e. it is not being built as a subproject itself) installing BTAS by building its install target may not build Boost libraries automatically. Thus the user may need to build `build-boost-in-BTAS` target manually before building `install` target. ## useful CMake variables - `CMAKE_CXX_COMPILER` -- specifies the C++ compiler (by default CMake will look for the C++ compiler in `PATH`) +- `CMAKE_INSTALL_PREFIX` -- specifies the installation prefix (by default CMake will install to `/usr/local`) +- `CMAKE_BUILD_TYPE` -- specifies the build type (by default CMake will build in `Release` mode) +- `CMAKE_PREFIX_PATH` -- semicolon-separated list of paths specifying the locations of dependencies - `BTAS_USE_BLAS_LAPACK` -- specifies whether to enable the use of BLAS/LAPACK via the BLAS++/LAPACK++ APIs; the default is `ON` - `BTAS_BUILD_DEPS_FROM_SOURCE` -- specifies whether to enable building the missing dependencies (Boost) from source; the default is `OFF` - `BUILD_TESTING` -- specifies whether to build unit tests; the default is `ON` diff --git a/external/boost.cmake b/external/boost.cmake index 1611011c..33b8c836 100644 --- a/external/boost.cmake +++ b/external/boost.cmake @@ -28,11 +28,14 @@ if (BTAS_BUILD_DEPS_FROM_SOURCE AND NOT DEFINED Boost_FETCH_IF_MISSING) set(Boost_FETCH_IF_MISSING 1) endif() include(${vg_cmake_kit_SOURCE_DIR}/modules/FindOrFetchBoost.cmake) -if (DEFINED Boost_SOURCE_DIR) +if (Boost_BUILT_FROM_SOURCE) set(BTAS_BUILT_BOOST_FROM_SOURCE 1) endif() # make BTAS depend on Boost +if (NOT TARGET BTAS) + message(FATAL_ERROR "BTAS must be defined before including external/boost.cmake") +endif() set(Boost_LIBRARIES Boost::headers;Boost::random) if (TARGET Boost::serialization) list(APPEND Boost_LIBRARIES Boost::serialization) @@ -46,6 +49,26 @@ endif (TARGET Boost::serialization) target_link_libraries(BTAS INTERFACE ${Boost_LIBRARIES}) target_compile_definitions(BTAS INTERFACE -DBTAS_HAS_BOOST_ITERATOR=1 -DBTAS_HAS_BOOST_CONTAINER=1 -DBTAS_DEFAULT_TARGET_MAX_INDEX_RANK=${TARGET_MAX_INDEX_RANK}) +# add artificial dependencies on some Boost components to ensure they are built before BTAS ... this is purely to +# account for the fact that we do not properly deduce which targets we actually depend on AND some Boost targets +# are not built when install target is built +if (Boost_BUILT_FROM_SOURCE) + foreach (_target IN LISTS Boost_MODULAR_TARGETS_NOT_BUILT_BY_INSTALL) + add_dependencies(BTAS boost_${_target}) + endforeach() + # unfortunately install ignores dependence of BTAS on these targets, presumably because it is an INTERFACE library + # and install target does not really build BTAS target ... this is OK if BTAS is built as a subproject and + # the BTAS target is consumed by the parent project, but if BTAS is built as a standalone project, then there is no + # correct way to install BTAS other than to ask the user to build a target that will build+install Boost first + if ("${PROJECT_NAME}" STREQUAL "${CMAKE_PROJECT_NAME}") + message(WARNING "BTAS is built as a standalone project, but Boost is built from source and cannot not be installed automatically.\nThus to install BTAS build the \"build-boost-in-BTAS\" target first, then build the \"install\" target") + add_custom_target(build-boost-in-BTAS) + foreach(_target IN LISTS Boost_FOUND_TARGETS Boost_MODULAR_TARGETS_NOT_BUILT_BY_INSTALL) + add_dependencies(build-boost-in-BTAS Boost::${_target}) + endforeach() + endif() +endif() + # If building unit tests, perform a compile check with Boost # this is only possible, though, if did not build Boost from source, # since only imported targets can be used in CMAKE_REQUIRED_LIBRARIES diff --git a/external/versions.cmake b/external/versions.cmake index 2daf4469..e738e91b 100644 --- a/external/versions.cmake +++ b/external/versions.cmake @@ -1,4 +1,4 @@ -set(BTAS_TRACKED_VGCMAKEKIT_TAG 38f99f3da4810c97ed1d54f863120ae85120fa8f) +set(BTAS_TRACKED_VGCMAKEKIT_TAG e0d04e91a84b7e71d9b87682c46c518e9966bd78) # likely can use earlier, but # - as of oct 2023 tested with 1.71 and up only