繁体   English   中英

我的makefile尝试编译目录

[英]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 -xmake --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)

为了清楚起见,你应该使用的东西列出多个标识符时: SRCSOBJS OBJS应该只是包含路径的目标文件列表。 我不明白为什么您坚持要从源文件和对象文件列表中剥离路径。 Gnu Make通用规则可轻松为不同的输出源和/或对象目录指定不同的编译选项。 您可以利用此优势从相同的来源创建不同的目标,例如32位和64位版本,并使它们共存而不会发生冲突。

最终目标应该很简单:

$(PROJ_NAME): $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM