首页 > 解决方案 > 将参数传递给 Makefile 时出现问题

问题描述

我的 Makefile 看起来像这样:

OBJ = $(SRC:.c=.c.o)    #yes it it should be renamed to .c.o, not .o
LIBS = -lchecl -lchecs -lchengine-dev -lglfw -lm -lGL -lGLEW -lcheio -lopenal -lfreetype
EXE = test
VER = -std=c99
MODE = -g
OPT = -O0 
ERR = -Wall -Wuninitialized -Werror=implicit-function-declaration -Wextra -Wno-unused-parameter -Wno-incompatible-pointer-types -Werror=int-conversion -Wduplicated-cond -Wlogical-op -Wrestrict -Wnull-dereference -Wjump-misses-init -Wdouble-promotion -Wshadow -Wformat=2
LFLAGS = -o
CFLAGS = $(ERR) $(VER) $(OPT) -c $(MODE) `pkg-config --cflags freetype2`

run: $(EXE)
    ./$(EXE)


$(EXE): $(OBJ)
    gcc $(LFLAGS) $(EXE) $(OBJ) $(LIBS)

%.o: %.c
    gcc -c $(CFLAGS) $*.c
    mv "$$(basename $*.o)" "$$(dirname $*)"

cleanall:
    rm $(OBJ)
    rm $(SRC)

我正在传递这样的SRC变量:

files=$(find . -type f -name '*.c.c')
make run SRC="$files"

但这会产生以下错误:

make: *** No rule to make target 'src/setup.c
./states/mainMenuState.c
...
(a list of all source files)'

但是,如果我手动将 的值复制$files到 Makefile 中,然后写入SRC = 源文件,它编译得很好。如果我写而不是OBJ = $(SRC:.c.c=.c.o) OBJ = $($(SRC):.c.c=.c.o)它似乎可以编译但没有正确链接,因为那时我得到了这个错误:

//usr/local/lib/libchengine-dev.so: undefined reference to `vector_find'
//usr/local/lib/libchengine-dev.so: undefined reference to `che_init'
//usr/local/lib/libchengine-dev.so: undefined reference to `vector_destruct'

标签: bashmakefile

解决方案


SRC在 的定义中使用OBJ。但这不可能是你真正的makefile,因为它不起作用。因此,您的真实 makefile 与您向我们展示的内容必须有所不同,而这种差异对于您遇到的问题至关重要。正如 Renaud 所说,请提供 MCVE。

我创建了一个简单的makefile:

OBJS := $(SRC:.c=.c.o)

all: $(OBJS)

%.c.o : %.c
        : $< $@

然后运行它:

files=$(find -name \*.c)
make SRC="$files"

它工作得很好:

: foo.c foo.c.o
: bar.c bar.c.o
: biz.c biz.c.o
: baz.c baz.c.o

您可以通过不在$files变量中包含换行符来解决 GNU make 4.1 中的问题。例如,您可以更改设置方式:

files=$(find . -type f -name '*.c.c' -printf '%p ')

所以它使用空格分隔符而不是换行符。


推荐阅读