[英]My makefile tries to compile a directory
make
的输出如下
gcc -Wall -Wextra -std=c99 -o bin/test src/obj/ src/obj/main.o src/obj/test.o
/usr/bin/ld: cannot find src/obj/: File format not recognized
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
如您所见,执行的compile命令正在尝试将src / obj /编译为目标文件。 我最好的猜测是,它以某种方式被列在OBJ变量中。
编辑:这是现在工作的makefile。 经过一些调试后,我进行了以下更改。
这没用。 文件路径在编译时就已经混在一起。 所以这...
# object directory
OBJ_DIR=$(SRC_DIR)/obj
# souce files
SRC=$(wildcard $(SRC_DIR)/*.c)
# object files
OBJ=$(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC)) # still directories in OBJ list causing problems
变成这个...
# object directory
OBJ_DIR=obj
# souce files
SRC=$(patsubst $(SRC_DIR)/%.c,%.c,$(wildcard $(SRC_DIR)/*.c))
# object files
OBJ=$(patsubst %.c,%.o,$(SRC))
和这个...
# rule that individual objects rely on .c versions and .h files
# needs to compile to .o files, then compile to executable
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
# actual compile commands
$(PROJ_NAME): $(OBJ_DIR)/$(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ_DIR)/$(OBJ)
变成这个...
# rule that individual objects rely on .c versions and .h files
# needs to compile to .o files, then compile to executable
%.o: $(SRC_DIR)/%.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
# actual compile commands
$(PROJ_NAME): $(SRC_DIR)/$(OBJ_DIR)/$(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(SRC_DIR)/$(OBJ_DIR)/$(OBJ)
本质上,使用patsubst
可以确保列表中的所有文件都没有附加到它们的路径,然后在需要时手动指定完整路径。
论文两行
$(PROJ_NAME): $(OBJ_DIR)/$(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ_DIR)/$(OBJ)
可能是错误的,因为$(OBJ)
已经包含$(OBJ_DIR)
所以用
$(PROJ_NAME): $(OBJ)
@echo OBJ= $(OBJ) at= $@ caret= $^
$(COMPILE.c) $(CFLAGS) -o $@ $^
代替。 了解有关GNU make内置规则的更多信息(您可以通过make -p
获得它们)。 如果满意,请删除调试@echo
行。
正如我评论的那样,将remake用作remake -x
或make --trace
以了解发生了什么(假设GNU make和Linux)。
您可能需要使用strip功能删除开头和结尾的空格,例如
OBJ= $(strip $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC)))
确保OBJ_DIR
定义(以及Makefile
其他定义)不包含尾随空格。 不要在其中添加评论:
#be sure that following line does not have comments or trailing spaces
OBJ= $(strip $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC)))
将#
注释放在定义make变量的行中是一个非常不好的习惯。 您应该在定义行之前或之后放置注释行。
我用包含ac
文件的src
目录尝试了您的makefile。
似乎$(OBJ_DIR)/$(OBJ)
扩展为src/obj/ src/obj/ao
。 变量$(OBJ)
可能包含空字符串或空格
您的问题肯定与宏定义末尾的注释有关。 只能在宏行上使用#
来在宏定义的末尾嵌入空格,否则您会由于误入歧途而造成不必要的晦涩后果。
这里还有一些提示和备注:
您可以使用:=
运算符在分析时评估宏,这可能更适合$(wildcard..)
和$(shell...)
扩展。
SRCS:=$(wildcard $(SRC_DIR)/*.c)
为了清楚起见,你应该使用的东西列出多个标识符时: SRCS
和OBJS
。 OBJS
应该只是包含路径的目标文件列表。 我不明白为什么您坚持要从源文件和对象文件列表中剥离路径。 Gnu Make通用规则可轻松为不同的输出源和/或对象目录指定不同的编译选项。 您可以利用此优势从相同的来源创建不同的目标,例如32位和64位版本,并使它们共存而不会发生冲突。
最终目标应该很简单:
$(PROJ_NAME): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.