懒人C工程Makefile
引言
在工作的一段时间里面, 因为平时写项目的时候有一些功能需要紧急调试,但是调试的代码呢又想单独的分出来进行归档,然后又不想使用IDE进行创建,同时还想跨平台使用(windows/Linux),所以还是继续折腾Makdfile吧。
需求
首先因为是懒人需求,也就是不想老是每次都编辑Makefile文件进行项目文件的管理,所以就想整个项目只有一个Makefile文件,然后仅需要修改项目名称和编译器的路径(甚至编译器路径仅需要自己配一次,以后直接复制该Makefile文件修改项目名称即可),也就是修改有限的两行代码。
Makefile的功能需求很简单,使用Makefile来进行C项目的编译工作,自动收集.c文件和.h文件按,并且自动完成头文件目录的包含,最后进行编译和清除生成的文件。
环境上,目前使用的是VSCode作为文本编辑器,所以需要使用VSCode的调试功能工作进行内存查看,所以需要编译出来的可执行文件可以被追溯源代码(如果使用Makefile的自动推导功能一般不能被MinGW的GDB进行追溯)。然后因为想快平台,环境就是用MinGW即可。
Makefile文件内容
既然需求已经明确,所以直接给出第一版代码,未来的代码更新会在GitHub上同步,传送门https://github.com/impressionyang/lazy_single_makefile_for_c_project
1# lazy build C project Makefiles by impressionyang
2# user config values
3CC="/usr/bin/gcc"
4# CC="E:\\impressionyang\\scoop\\apps\\mingw\\12.2.0\\bin\\gcc.exe"
5PROJECT=test
6
7# check operating system type
8ifeq ($(OS), Windows_NT)
9 OS_TYPE := WINDOWS
10 SHELL := cmd
11else
12 UNAME_S := $(shell uname -s)
13 ifeq ($(UNAME_S),Linux)
14 OS_TYPE := LINUX
15 endif
16 ifeq ($(UNAME_S),Darwin)
17 OS_TYPE := OSX
18 endif
19endif
20
21$(info OS type = $(OS_TYPE))
22
23# patern config
24FILES_PATH := ./
25SRC_FILES_SUFFIX := %.c
26HDR_FILES_SUFFIX := %.h
27
28# define func to remove_same_str for debug: $(info get seen ${seen})
29define remove_same_str =
30 $(eval seen :=)
31 $(foreach _,$1,$(if $(filter $_,${seen}),,$(if $_, $(eval seen += $_))))
32 ${seen}
33endef
34
35# find recursive all files
36rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
37
38# get source file and header file
39FIND_ALL_FILES := $(foreach files_path,$(FILES_PATH), $(call rwildcard,$(files_path),*.*) )
40SOURCES := $(filter $(SRC_FILES_SUFFIX),$(FIND_ALL_FILES))
41SOURCES := $(SOURCES:$(LOCAL_PATH)/%=%)
42HEADERS := $(filter $(HDR_FILES_SUFFIX),$(FIND_ALL_FILES))
43HEADERS := $(HEADERS:$(LOCAL_PATH)/%=%)
44
45# fillter out all include path
46FIND_ALL_FILES_DIR := $(dir $(foreach files_path,$(FILES_PATH), $(call rwildcard,$(files_path),*/) ) )
47GET_INC_DIRS := $(call remove_same_str,$(FIND_ALL_FILES_DIR))
48INC_DIRS :=
49INC_DIRS += $(foreach v, $(GET_INC_DIRS), $(if $(filter %/,$v) , $(eval INC_DIRS+=$v), ))
50INC_DIRS := $(subst ./, -I./, $(INC_DIRS))
51INC_DIRS := $(wordlist 1, $(words $(INC_DIRS)), $(INC_DIRS))
52
53# debug print info, no need to be change
54# $(info "INC_DIRS")
55# $(info $(INC_DIRS))
56# $(info "HEADERS")
57# $(info $(HEADERS))
58# $(info "SOURCES")
59# $(info $(SOURCES))
60
61# compile job
62all :
63 $(CC) -fdiagnostics-color=always -g $(SOURCES) $(HEADERS) $(INC_DIRS) -o $(PROJECT)
64
65# virtual clean job
66.PHONY : clean
67clean:
68ifeq ($(OS_TYPE), WINDOWS)
69 del $(PROJECT).exe
70endif
71ifeq ($(OS_TYPE), LINUX)
72 rm $(PROJECT)
73endif
74ifeq ($(OS_TYPE), OSX)
75 rm $(PROJECT)
76endif
77
如何使用
基本上,只要如下几步就可以进行项目开发:
- 创建一个文件夹,命名为项目名称
- 然后把这个Makfile创建好,修改Makefile中的
CC
(编译器的路径,推荐使用MinGW)和PROJECT
(项目名)字段就行 - 写C代码
make
就行啦
如果还想要使用VSCode的调试功能的话,就加上调试的luanch.json
就行啦,具体的话以后有需要再增加文章说明。
总结
总之,这个Makefile就突出一个懒,所以它很多过程自动完成,所以他的缺点也很明显,目前没有自动连接库,这个以后会继续优化的。
评论