我有一个我想要编译的大项目,但它使用了一些我不想使用的g++
标志。我没有编辑Makefile,而是考虑编写一个小脚本,它将运行而不是编译器,处理命令行参数并将它们传递给编译器。
#!/bin/bash
~/g++ `echo "$@" | sed "s/-Os//gi; s/-O0//gi; s/-O1//gi; s/-O2//gi;"` -O3
它运行良好,直到make
进入名称中包含空格的某个目录,g++
使我的控制台出现No such file or directory
错误。如何替换每个参数中的文本,并以原始形式将其传递给编译器(例如,带空格)?
答案 0 :(得分:2)
我不相信你的出发点是正确的 - 你应该修复makefile
以便他们做你想做的事。理想情况下,所有其他文件都包含一个文件,允许您配置编译器选项等内容。但是,为了便于讨论,我们必须假设您不能这样做。
我认为您需要使用Bash数组来完成任务。
#!/bin/bash
i_args=( "$@" )
o_args=( "-O3" )
for arg in "${i_args[@]}"
do
case "$arg" in
(-O[0123s]) : OK;;
(*) o_args+=( "$arg" );;
esac
done
exec ~/g++ "${o_args[@]}"
此代码还确保不重复-O3
(通过将其添加到已删除选项列表中)。传递两次没有特别的伤害,但也没有任何好处。
用最后一行替换:
printf "%s\n" "${o_args[@]}"
并运行如下所示的脚本生成输出,如下所示:
$ bash x3.sh -o filtration -I$HOME/inc -I "/path/ with /blanks in names" -Os -O0 \
-Wall -O1 -Wextra -O2 -L /library/of/alexandria -O3 -lpapyrus
-O3
-o
filtration
-I/Users/jleffler/inc
-I
/path/ with /blanks in names
-Wall
-Wextra
-L
/library/of/alexandria
-lpapyrus
$
答案 1 :(得分:1)
如何告诉make使用不同的CFLAGS? e.g:
make CFLAGS='-g -O'
答案 2 :(得分:1)
这是一个非常棘手的问题,因为脚本必须在删除引号后保留引用的效果。
我设法想出来了。为了测试,我使用了touch命令而不是g ++
你可能会重构一些事情,但它似乎至少起作用了!
#!/bin/bash
whitespace="[[:space:]]"
for i in "$@"
do
# Skip the options we don't want.
if [[ $i == "-Os" ]] || [[ $i == "-O0" ]] || [[ $i == "-O1" ]] || [[ $i == "-O2" ]]
then
continue
fi
# Escape any whitespace characters
if [[ $i =~ $whitespace ]]
then
i=$(printf %q "$i")
fi
# Build a command line
a=$a' '"$i"
done
# Build the final command line by adding the command we are stubbing.
cmd="touch "$a # In your case replace touch with g++
# Use eval to execute the command.
eval ${cmd}
输出:
$ ./stub.sh "two words" -Os oneword
$ ls -al
total 8
drwxr-xr-x+ 5 jcreasey staff 170 19 Jun 12:49 .
drwxr-xr-x+ 22 jcreasey staff 748 19 Jun 12:49 ..
-rwxr-xr-x+ 1 jcreasey staff 308 19 Jun 12:49 arg2.sh
-rw-r--r--+ 1 jcreasey staff 0 19 Jun 12:49 oneword
-rw-r--r--+ 1 jcreasey staff 0 19 Jun 12:49 two words