我的makefile尝试编译目录

时间:2015-04-16 07:57:56

标签: c makefile

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

如您所见,执行的编译命令正在尝试将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我确保列表中的所有文件都没有附加到它们的路径,然后在需要时手动指定完整路径。

3 个答案:

答案 0 :(得分:3)

这两行

 $(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&amp; 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 变量的行中是一个非常糟糕的习惯。 您应该在定义行之前或之后放置注释行。

答案 1 :(得分:1)

我尝试使用包含src文件的a.c目录的makefile。

$(OBJ_DIR)/$(OBJ)似乎扩展为src/obj/ src/obj/a.o。变量$(OBJ)可能包含空字符串或空格

答案 2 :(得分:0)

您的问题肯定与宏定义结束时的注释有关。 #只应在宏行上使用,以便在宏定义的末尾嵌入空格,这是错误的,并且会产生不必要的模糊后果。

以下是一些提示和评论:

您可以使用:=运算符在解析时评估宏,这可能更适合$(wildcard..)$(shell...)扩展。

SRCS:=$(wildcard $(SRC_DIR)/*.c)

为清楚起见,您应该为事物列表使用复数标识符:SRCSOBJSOBJS应该只是包含路径的目标文件列表。我不明白为什么你坚持从源和对象文件列表中剥离路径。 Gnu Make通用规则可以轻松地为不同的输出源和/或对象目录指定不同的编译选项。您可以利用此功能从相同的源生成不同的目标,例如32位和64位版本,并让它们共存而不会发生冲突。

最终目标应该很简单:

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