【问题标题】:Switching CC variable in Makefile based on argument根据参数在 Makefile 中切换 CC 变量
【发布时间】:2013-06-03 15:05:50
【问题描述】:

我有一个 C 程序,我想为主机和来宾架构编译。

主机是 i86 访客是 ARM

我尝试编写如下代码

CC=arm-none-linux-gnueabi-gcc

all : arm

arm :
    CC=arm-none-linux-gnueabi-gcc

host :
    CC=gcc

clean :
    rm -rf *.o
    rm bench

$(CC) src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench

但是当我运行 make arm 或 make host 时,我得到一个缺少分隔符的错误。 我怎样才能实现这个功能?

编辑: 我遵循了公认的答案,但仍然想要一个目标来完成我的任务.. 为此,我重写了我的 Makefile 如下,

all : bench

host_helper :
    CC=gcc

arm_helper :
    CC=arm-none-linux-gnueabi-gcc

arm : arm_helper bench

host : host_helper bench

all : bench

clean :
    @rm -rf *.o
    @rm -f bench

bench : clean
    $(CC) src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench

这是我在运行make arm时得到的输出

CC=arm-none-linux-gnueabi-gcc
cc src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench

为什么 CC 变量没有改变?
这是因为 Makefile 对每个目标都进行了 fork,因此一旦 arm_helper 目标完成,CC 变量就会丢失?
这种方法是否可以达到预期的目的?

【问题讨论】:

  • makefile 中的最后一行是做什么的?这不是规则的一部分...
  • 是的,我确定..它抱怨最后一行..该行中没有选项卡..因为我的目标是不管选项如何都执行它..虽然,我会最终希望在执行make clean时避免运行$(CC)@
  • 我希望将其编写为类似于 bash 脚本。如何在一组命令后获得一个标签来执行另一个标签?我希望标签 armhost 的功能如下:1)设置 CC 变量 2)运行公共代码 $(CC) src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench

标签: gcc makefile cross-compiling


【解决方案1】:

最后一行不应按原样格式化。 makefile 的目的是告诉系统输入、输出和它们的依赖关系。因此,你应该更恰当地写:

bench: src/main.c src/cpu/cpu.c src/include/common.c
    $(CC) $^ -Isrc -lrt -static -o $@

也许在all 中包含bench。调用可以是“make all”或“make arm bench”。

标签(实际上称为目标)并不是真正从 makefile 中的其他目标“调用”的。这需要思想的转变。 Makefile 不是程序化的。从本质上讲,它们是依赖树。因此,如果您希望在创建另一个目标时创建一个目标,则将其添加为依赖项;例如:

bench: arm src/main.c src/cpu/cpu.c src/include/common.c
    $(CC) src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o $@

如果我记得我的语法(这可能有效,也可能无效),您可以更清楚地表达为:

bench:: arm
bench:: src/main.c src/cpu/cpu.c src/include/common.c
    $(CC) $^ -Isrc -lrt -static -o $@

解决您的新生成文件:

首先,你已经写了两次all。删除一个。其次,不要bench 依赖于clean。链接后不会删除bench吗?此外,您“基于目标设置变量”的方法也行不通。请尝试以下方法:

all: bench-host

bench-host: CC=gcc
bench-arm: CC=arm-none-linux-gnueabi-gcc
bench-host bench-arm: src/main.c src/cpu/cpu.c src/include/common.c
    $(CC) $^ -Isrc -lrt -static -o $@

clean:
    @rm -f *.o
    @rm -f bench-*

【讨论】:

  • 我试过你的建议,我的makefile如下 CC=arm-none-linux-gnueabi-gcc all : bench arm : CC=arm-none-linux-gnueabi-gcc host : CC=gcc clean : rm -rf *.o rm bench bench : $(CC) src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench 现在当我运行 make arm ,它只显示CC=arm-none-linux-gnueabi-gcc
  • 如果你说“制作手臂”,它就是这样做的。它将成为arm 目标,仅此而已。输入“make”(隐式生成all),或输入“make arm bench”。
  • 这行得通!是否可以从 Makefiles 中的另一个标签调用标签?您能否也将此添加到您的答案中,以便我将其标记为已接受?
  • 最后一个问题.. 我仍然希望有一个目标来为我完成此任务,因此,我按照您的建议重写了我的 Makefile 如下all : bench host_helper : CC=gcc arm_helper : CC=arm-none-linux-gnueabi-gcc arm : arm_helper bench host : host_helper bench bench : clean $(CC) src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench 这会在 make arm 上显示以下消息 CC=arm-none-linux-gnueabi-gcc cc src/main.c src/cpu/cpu.c src/include/common.c -Isrc -lrt -static -o bench 为什么 CC 变量没有改变?
  • 这些 cmets 中不保留换行符。请通过编辑您的原始问题发布此问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多