首页 > 解决方案 > 配置 cmake 以使用自制库而不是系统提供的库

问题描述

我发现自己一遍又一遍地用 ccmake 配置 cmake 路径,就像每次更改 for ex 一样。编译器我的一些库路径丢失了。

特别是(未链接的)lapack、lapacke、gsl 的路径要么丢失,要么设置为系统默认值,而不是我用 brew 安装的路径。

必须有一种方法可以告诉 cmake “忽略”系统库,而是查看自制程序路径(例如 /opt/homebrew/lib、/opt/homebrew/include 等)。

我不想链接这些库,因为不推荐这样做,而且我在切换环境方面没有经验。

[编辑] MRE:

git clone https://gitlab.physik.uni-muenchen.de/AG-Scrinzi/tRecX.git
cd tRecX
cmake . -DCMAKE_BUILD_TYPE=Parallel
make -j 8

我将以下内容添加到 .bash_profile/.zshrc:

export LDFLAGS="-L/opt/homebrew/opt/lapack/lib -L/opt/homebrew/opt/lapack/lib" 
export CPPFLAGS="-I/opt/homebrew/opt/lapack/include -I/opt/homebrew/opt/openblas/include" 
export PKG_CONFIG_PATH="/opt/homebrew/opt/lapack/lib/pkgconfig /opt/homebrew/opt/openblas/lib/pkgconfig"

然后我尝试:

cmake . -DCMAKE_PREFIX_PATH=/opt/homebrew -DCMAKE_FIND_FRAMEWORK=NEVER -DCMAKE_FIND_APPBUNDLE=NEVER -DCMAKE_FIND_USE_CMAKE_SYSTEM_PATH=FALSE -DCMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH=FALSE -DMPI_CXX_COMPILER=/opt/homebrew/bin/mpicxx -DMPI_C_COMPILER=/opt/homebrew/bin/mpicc -DCMAKE_CXX_COMPILER=/opt/homebrew/bin/g++-11 -DCMAKE_C_COMPILER=/opt/homebrew/bin/gcc-11

标签: cmake

解决方案


最常见的解决方案是设置CMAKE_PREFIX_PATH/opt/homebrew. 然后 CMake 将优先/opt/homebrew查看所有内容。由于您使用的是 Apple,因此您可能还需要设置CMAKE_FIND_FRAMEWORKand CMAKE_FIND_APPBUNDLEto LASTor NEVER

您可以通过在命令行、预设或工具链文件中设置CMAKE_FIND_USE_CMAKE_SYSTEM_PATH为来跳过标准平台搜索路径。您可能还希望通过设置来FALSE禁用查看PATH环境变量。CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATHFALSE

最后,如果您在交叉编译场景或工具链文件中,您可以通过设置来更改系统目录的定义CMAKE_SYSROOT。请注意,sysroot 必须包含语言运行时库(例如 glibc)并将传递给--sysroot标志(或等效项)。也请注意这些影响。

所有这些都记录在这里:


以下homebrew.cmake工具链文件对我有用:

set(HOMEBREW_PREFIX "/usr/local"
    CACHE PATH "Path to Homebrew installation")

set(CMAKE_C_COMPILER "${HOMEBREW_PREFIX}/bin/gcc-11")
set(CMAKE_CXX_COMPILER "${HOMEBREW_PREFIX}/bin/g++-11")

set(CMAKE_PREFIX_PATH
    "${HOMEBREW_PREFIX}"
    # These libraries are keg-only and not loaded into
    # the root prefix by default (to avoid clashes).
    "${HOMEBREW_PREFIX}/opt/lapack"
    "${HOMEBREW_PREFIX}/opt/openblas"
    "${HOMEBREW_PREFIX}/opt/gcc/lib/gcc/11"
)

list(TRANSFORM CMAKE_PREFIX_PATH APPEND "/include"
     OUTPUT_VARIABLE CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES)
set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "${CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES}")

set(CMAKE_FIND_FRAMEWORK NEVER)
set(CMAKE_FIND_APPBUNDLE NEVER)

set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH FALSE)
set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH FALSE)

我使用以下命令构建:

$ ls 
tRecX  homebrew.cmake
$ cmake -G Ninja -S tRecX -B tRecX-build \
    -DCMAKE_TOOLCHAIN_FILE=$PWD/homebrew.cmake \
    -DCBLAS=/usr/local/opt/openblas/lib/libblas.dylib \
    -DCMAKE_EXE_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
    -DCMAKE_SHARED_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
    -DCMAKE_BUILD_TYPE=Parallel

[ ... output clipped ... ]

Boost found -- full functionality

Build "Parallel" with C++ flags  -D_USE_BOOST_ -O3  -pthread  -D_USE_FFTW_, return to default by -UCMAKE_BUILD_TYPE

            Compiler: /usr/local/bin/g++-11, change by -DCMAKE_CXX_COMPILER=[path_to_complier]

-- Linking to libraries Boost::system;Boost::filesystem;/usr/local/lib/libfftw3.dylib;/usr/local/opt/gcc/lib/gcc/11/libgfortran.dylib;alglib;/usr/local/lib/libarpack.dylib;Boost::system;Boost::filesystem;/usr/local/opt/lapack/lib/liblapacke.dylib;/usr/local/opt/openblas/lib/libblas.dylib;/usr/local/opt/lapack/lib/liblapack.dylib;/usr/local/opt/lapack/lib/libblas.dylib;m
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/alexreinking/Development/tRecX-build
$ cmake --build tRecX-build

我不得不CBLAS手动设置,因为libblas.dylib提供了 OpenBLAS CBLAS 接口,但是构建系统专门寻找一个名为libcblas. 在这种情况下没有其他选择。

代码和构建的链接模型和依赖项存在问题。我可以通过设置来覆盖这些-Wl,-undefined,dynamic_lookup。但是,请注意,这只会将链接器错误推迟到运行时,并且可能会带来很大的启动成本。

如果您可以提交项目,我会将这些设置存储在预设中,也许可以命名homebrew-parallel或其他名称:

    -DCMAKE_TOOLCHAIN_FILE=$PWD/homebrew.cmake \
    -DCBLAS=/usr/local/opt/openblas/lib/libblas.dylib \
    -DCMAKE_EXE_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
    -DCMAKE_SHARED_LINKER_FLAGS="-Wl,-undefined,dynamic_lookup" \
    -DCMAKE_BUILD_TYPE=Parallel

然后你可以运行cmake --preset=homebrew-parallel


推荐阅读