我正在使用 C++ 中的 Slate 线性代数库编写一个项目,并以 MKL、MPI 和 OpenMP 作为依赖项。通常,我在基于 Linux 的系统上运行我的程序
$ mpicxx -fopenmp -Wall -std=c++17 -MMD -I/opt/slate/include -DSLATE_NO_CUDA -c -o test.o test.cpp
$ mpicxx -o test test.o -fopenmp -L/opt/slate/lib -Wl,-rpath,/opt/slate/lib -lslate -lblaspp -llapackpp
但是,最近我想尝试一下 CMake,但无法让它正常工作。
cmake_minimum_required(VERSION 3.12)
# set the project name and version
project(1D_DFT VERSION 0.1)
#Slate directories
set(slate_dir /opt/slate)
#Compiler and libraries
set(CXXFLAGS -fopenmp -Wall -std=c++17 -MMD -I${slate_dir}/include -DSLATE_NO_CUDA)
set(LDFLAGS -fopenmp -L${slate_dir}/lib -Wl,-rpath,${slate_dir}/lib)
set(LIBS -lslate -lblaspp -llapackpp)
#Setting compiler
set(CMAKE_CXX_FLAGS ${CXXFLAGS})
set(CMAKE_EXE_LINKER_FLAGS ${LDFLAGS} ${LIBS})
add_library(test.o OBJECT test.cpp)
#Add the executable
add_executable(1D_DFT $<TARGET_OBJECTS:test.o>)
SET_SOURCE_FILES_PROPERTIES(
$<TARGET_OBJECTS:test.o>
PROPERTIES
GENERATED true
它无法识别任何编译器或链接器标志!如何告诉 CMake 使用一组特定的标志运行?
最佳答案
正如 LHLaurini 在评论中所指出的,在将标志分配给变量时,应该在标志周围使用引号。如果不这样做,CMake 会将它们转换为分号分隔的列表并弄乱命令。以下是如何正确执行此操作的示例:
set(CXXFLAGS "-fopenmp -Wall -std=c++17 -MMD -I${slate_dir}/include -DSLATE_NO_CUDA")
set(CMAKE_CXX_FLAGS "${CXXFLAGS}")
然而,更重要的是,编写 CMake 文件涉及与编写 Makefile 非常不同的范例。现代最佳实践建议将标志和库设置为特定目标的属性。这是 presentation我建议更多地了解这个范例。如果您将这些设计原则应用到您的 CMake 代码中,它看起来更像这样:
cmake_minimum_required(VERSION 3.12)
# set the project name and version
project(1D_DFT VERSION 0.1)
#Slate directories
set(slate_dir /opt/slate)
add_executable(1D_DFT test.cpp)
target_compile_definitions(1D_DFT PRIVATE SLATE_NO_CUDA)
target_compile_features (1D_DFT PRIVATE cxx_std_17)
target_compile_options (1D_DFT PRIVATE -fopenmp -Wall)
target_include_directories(1D_DFT PRIVATE ${slate_dir}/include)
target_link_directories (1D_DFT PRIVATE ${slate_dir}/lib)
target_link_libraries (1D_DFT PRIVATE slate blaspp lapackpp)
set_property(TARGET 1D_DFT PROPERTY BUILD_RPATH "${slate_dir}/lib")
关于c++ - 如何在 CMake 中设置编译标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72235289/