稍微理解和修改这个makefile
我一直在编辑这个makefile,但主要是尝试和错误 基本上,我在同一个目录中有稍微理解和修改这个makefile,makefile,Makefile,我一直在编辑这个makefile,但主要是尝试和错误 基本上,我在同一个目录中有n.c文件。我希望使用我的makefile hacks编译和链接第一个文件(具有固定名称),在链接步骤中包含不同的.o文件,并且只使用LIBS(不使用其他.o文件)编译和链接所有其他文件 这是“主”生成文件: MAKEFILE_BASE = ./Build-Assets/Makefile MAKEFILE_CONTROLLERS = ./Controllers/Makefile .PHONY: default cl
n
.c文件。我希望使用我的makefile hacks编译和链接第一个文件(具有固定名称),在链接步骤中包含不同的.o文件,并且只使用LIBS
(不使用其他.o文件)编译和链接所有其他文件
这是“主”生成文件:
MAKEFILE_BASE = ./Build-Assets/Makefile
MAKEFILE_CONTROLLERS = ./Controllers/Makefile
.PHONY: default clean release release-clean
default: release
clean: release-clean
release:
$(MAKE) -f $(MAKEFILE_CONTROLLERS) # This generates the .o files, and it works well
$(MAKE) -f $(MAKEFILE_BASE).Release
release-clean:
$(MAKE) -f $(MAKEFILE_BASE).Release clean
这就是“Makefile.Release”,它处理这些.c文件的编译/链接
TARGET = $(notdir $(shell pwd))
LIBS = -lm -lev3dev-c -pthread
D_BIN = Build-Assets
ifeq ($(OS),Windows_NT)
LIBS := $(LIBS) -lws2_32
D_BIN := $(D_BIN)/mingw
endif
D_H = ../../source/ev3
CFLAGS = $(addprefix -I, $(D_H)) -O2 -std=gnu99 -W -Wall -Wno-comment
ifeq ($(OS),Windows_NT)
CC = gcc
else
CC = arm-linux-gnueabi-gcc
endif
ifeq ($(OS),Windows_NT)
E_BIN = .exe
else
E_BIN =
endif
F_BIN = $(TARGET)$(E_BIN)
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard *.c))) $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard Controllers/*.c)))
.PHONY: default all clean
default: $(F_BIN)
all: default
$(OBJECTS): $(D_BIN)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PRECIOUS: $(F_BIN) $(OBJECTS)
$(F_BIN): $(OBJECTS)
$(info VAR is $@)
$(CC) $(OBJECTS) -Wall $(LIBS) -o $@
clean:
-rm -f $(D_BIN)/*.o
-rm -f $(F_BIN)
关于“目标名称作为目录名称的位置”,如下所示:
TARGET = $(notdir $(shell pwd))
这将运行shell命令pwd
获取当前目录的完整路径,然后使用notdir
剥离父目录。然后链接可执行文件的规则使用以下内容:
F_BIN = $(TARGET)$(E_BIN)
...
$(F_BIN): $(OBJECTS)
关于为什么会出现多个主要错误,这是因为您将新的.c
文件与新的main
一起添加到同一目录中,而不是使用makefile列出要编译和链接的特定源文件集,它使用通配符来获取所有源文件:
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard *.c))) $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard Controllers/*.c)))
这些$(通配符*.c)
函数将扩展到这些目录中的所有*.c
文件,包括您添加的任何新文件。然后它们都将链接到目标中,这将为您提供两个不同的对象文件,其中包含main
您必须更改此选项,以便仅列出所需的文件,或将文件放在其他位置,或使用make的过滤功能将文件从列表中删除,或诸如此类的操作。有一个严重的术语问题,使您很难理解您要做的事情。编译文件使用编译器将单个源文件.c
转换为单个目标文件.o
。无法执行对象文件,它们是构建的中间步骤。链接文件使用编译器(通常)将一个或多个对象文件转换为可运行的可执行文件。如果您可以编辑您的问题,将其改写为使用正确的术语,这将非常有用,这样我们就可以理解您正在尝试执行的操作。当您将一组对象文件链接到可执行文件中时,只有一个对象文件(从一个源文件构建)可以具有main()
函数。如果您试图将包含main()
的多个对象文件(来自源文件)链接到一个可执行文件中,您将得到有关main
的多个定义的错误。我已编辑了该问题。谢谢
OBJECTS = $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard *.c))) $(addprefix $(D_BIN)/, $(patsubst %.c, %.o, $(wildcard Controllers/*.c)))