makefile to compile all c files

Note: this answer assumes that you are using GNU make. If it is not the case there are probably a few things to adapt. I will not answer your last question about cross-platform portability. First because it is a complex question, second because I do not have a Windows box and cannot do any tests with this OS. But if you know a portable way to detect the OS, look at the last note. Meanwhile, the following should work under Windows.

The most straightforward and standard way to use GNU make in your case is probably something like:

MKDIR   := md
RMDIR   := rd /S /Q
CC      := gcc
BIN     := ./bin
OBJ     := ./obj
INCLUDE := ./include
SRC     := ./src
SRCS    := $(wildcard $(SRC)/*.c)
OBJS    := $(patsubst $(SRC)/%.c,$(OBJ)/%.o,$(SRCS))
EXE     := $(BIN)/main.exe
CFLAGS  := -I$(INCLUDE)
LDLIBS  := -lm

.PHONY: all run clean

all: $(EXE)

$(EXE): $(OBJS) | $(BIN)
    $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)

$(OBJ)/%.o: $(SRC)/%.c | $(OBJ)
    $(CC) $(CFLAGS) -c $< -o $@

$(BIN) $(OBJ):
    $(MKDIR) $@

run: $(EXE)
    $<

clean:
    $(RMDIR) $(OBJ) $(BIN)

Explanations:

  1. The wildcard make function is used to discover the list of C source files.
  2. The patsubst make function is used to transform C source file names into object file names.
  3. The .PHONY special target tells make that all its prerequisites are phony: they are not real files and must be considered by make even if a file with this name already exists by accident.
  4. $(OBJ)/%.o: $(SRC)/%.c | $(OBJ) is a pattern rule, a generic rule that works for all your similar object-building rules. This one tells make how to produce each ./obj/xxx.o object file by compiling the corresponding ./src/xxx.c C source file.
  5. The … | $(OBJ) part of the pattern rule tells make that $(OBJ) is an order-only prerequisite. Make will build it if it does not exist already. Else it will not consider its last modification time to decide if the target must be rebuilt or not. Directories are almost always listed as order-only prerequisite because their last modification time is not relevant. Here, it is used to tell make that the $(OBJ) directory must be built before any object file can be built. Same for $(BIN) in the $(EXE): $(OBJS) | $(BIN) rule.
  6. $@, $< and $^ are 3 of the make automatic variables. In the recipes of a rule they expand respectively as the target, the first regular prerequisite and all regular (non order-only) prerequisites of the rule.
  7. CC, CFLAGS and LDLIBS are standard make implicit variables used respectively to define the C compiler, the C compiler options and the -lxxx linker options.
  8. The := variable assignment is preferable in this specific case over the = assignment for performance reasons. See the GNU make documentation for a detailed explanation.

Note: as you have an include directory I guess that you also have custom header files. They should be listed as prerequisites of the relevant object files such that make knows that an object file must be rebuilt if the header files it depends on change. You can do this by adding rules without a recipe anywhere after the pattern rule:

$(OBJ)/Distances.o: $(INCLUDE)/foo.h $(INCLUDE)/bar.h

If a header file is included by all C source files of your project, simply add:

$(OBJS): $(INCLUDE)/common.h

And if there is a kind of pattern for the header files (for instance if each $(SRC)/xxx.c includes $(INCLUDE)/xxx.h) you can also add a pattern rule to declare this kind of dependency:

$(OBJ)/%.o: $(INCLUDE)/%.h

Note: if you know a way to set a make variable (e.g. OS) to the name of the current OS you can probably modify what precedes to make it portable using GNU make conditionals. For instance, you could replace the two first lines by:

OS := $(shell <the-command-that-returns-the-current-OS-name>)

ifeq ($(OS),Windows)
MKDIR   := md
RMDIR   := rd /S /Q
else ifeq ($(OS),GNU/Linux)
MKDIR   := mkdir -p
RMDIR   := rm -rf
else ifeq  ($(OS),pokemon)
MKDIR   := bulbasaur
RMDIR   := charmander
endif


$@ 目标文件
$< 第一个依赖文件
$^ 所有的依赖文件

【转】https://stackoverflow.com/questions/53136024/makefile-to-compile-all-c-files-without-needing-to-specify-them/53138757

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值