在 bash 脚本中将选项传递给 cmake

在 bash 脚本中将选项传递给 cmake

我正在尝试编写一个脚本,该脚本将使用 bash 脚本为不同的消毒剂构建多个 cppUtes lib.a 文件。

当尝试将编译器标志作为变量传递给 cmake 时,我无法正确格式化它们。请参阅下面的简短示例。

#!/bin/sh
set -euo pipefail
COMMON_OPTS='-fno-common -g -fno-omit-frame-pointer'
ASAN_OPT='-fsanitize=address'
ASAN_C_FLAGS="-DCMAKE_C_FLAGS=\"$ASAN_OPT $COMMON_OPTS\""

echo "cmake ../ $ASAN_C_FLAGS"
cmake ../ $ASAN_C_FLAGS
make

echo 的输出正是我所期望的,以及在未在 bash 脚本中运行时设置标志的有效方法:

cmake ../ -DCMAKE_C_FLAGS="-fsanitize=address -fno-common -g -fno-omit-frame-pointer"

但是,当我运行脚本时,cmake 无法正确解释这些标志。它们不会出现在配置期间显示的 cmake 标志中:

CppUTest CFLAGS: -include "/home/ubuntu/cpputest/include/CppUTest/MemoryLeakDetectorMallocMacros.h" -Wall -Wextra -pedantic -Wshadow -Wswitch-default -Wswitch-enum -Wconversion -Wsign-conversion -Wno-padded -Wno-long-long -Wstrict-prototypes

最后,我从 make 中得到以下编译错误:

c++: error: unrecognized argument to '-fsanitize=' option: 'address -g -fno-omit-frame-pointer'

任何帮助将不胜感激。

答案1

请考虑使用数组来保存选项。这样,您仍然能够正确地将它们cmake作为单独的参数提供,而不是作为 shell 将在空格上分割并执行文件名通配的单个字符串。

shellsh通常不支持数组,因此我更改了 -line#!来调用bash

#!/bin/bash
set -euo pipefail

common_opts=( -fno-common -g -fno-omit-frame-pointer )
asan_opt='-fsanitize=address'
asan_c_cflags=( -DCMAKE_C_FLAGS="$asan_opt" "${common_opts[@]}" )

echo "cmake ${asan_c_cflags[@]} ../"
cmake "${asan_c_cflags[@]}" ../
make

在这里,数组允许我们传递多个带引号的参数,而cmake无需将它们降级为单个字符串并依赖 shell 正确地 split+glob 它。这也使我们能够正确传递可能由带空格的字符串组成的参数。

有关的:

答案2

此处的问题是由于 中的转义引号ASAN_C_FLAGS,CMake 会将其变量视为带引号的值CMAKE_C_FLAGS,因此会将整个变量作为单个参数传递给编译器。删除这些转义引号后,CMake 应在将传递的参数传递给编译器之前,在空格处正确拆分传递的参数。

相关内容