懒人C工程Makefile

    159

懒人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

# lazy build C project Makefiles by impressionyang
# user config values
CC="/usr/bin/gcc"
# CC="E:\\impressionyang\\scoop\\apps\\mingw\\12.2.0\\bin\\gcc.exe"
PROJECT=test

# check operating system type
ifeq ($(OS), Windows_NT)
	OS_TYPE := WINDOWS
	SHELL := cmd
else
	UNAME_S := $(shell uname -s)
    ifeq ($(UNAME_S),Linux)
        OS_TYPE := LINUX
    endif
    ifeq ($(UNAME_S),Darwin)
        OS_TYPE := OSX
    endif
endif

$(info OS type = $(OS_TYPE))

# patern config
FILES_PATH  := ./
SRC_FILES_SUFFIX := %.c
HDR_FILES_SUFFIX := %.h

# define func to remove_same_str for debug: $(info get seen ${seen})
define remove_same_str =
  $(eval seen :=)
  $(foreach _,$1,$(if $(filter $_,${seen}),,$(if $_, $(eval seen += $_)))) 
  ${seen}
endef

# find recursive all files
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

# get source file and header file
FIND_ALL_FILES := $(foreach files_path,$(FILES_PATH), $(call rwildcard,$(files_path),*.*) ) 
SOURCES  := $(filter $(SRC_FILES_SUFFIX),$(FIND_ALL_FILES)) 
SOURCES  := $(SOURCES:$(LOCAL_PATH)/%=%)
HEADERS  := $(filter $(HDR_FILES_SUFFIX),$(FIND_ALL_FILES)) 
HEADERS  := $(HEADERS:$(LOCAL_PATH)/%=%)

# fillter out all include path
FIND_ALL_FILES_DIR := $(dir $(foreach files_path,$(FILES_PATH), $(call rwildcard,$(files_path),*/) ) )
GET_INC_DIRS := $(call remove_same_str,$(FIND_ALL_FILES_DIR))
INC_DIRS :=
INC_DIRS += $(foreach v, $(GET_INC_DIRS), $(if $(filter %/,$v) , $(eval INC_DIRS+=$v), ))
INC_DIRS := $(subst ./, -I./, $(INC_DIRS))
INC_DIRS := $(wordlist 1, $(words $(INC_DIRS)), $(INC_DIRS))

# debug print info, no need to be change
# $(info "INC_DIRS")
# $(info $(INC_DIRS))
# $(info "HEADERS")
# $(info $(HEADERS))
# $(info "SOURCES")
# $(info $(SOURCES))

# compile job
all : 
	$(CC) -fdiagnostics-color=always -g $(SOURCES) $(HEADERS) $(INC_DIRS) -o $(PROJECT)

# virtual clean job
.PHONY : clean
clean:
ifeq ($(OS_TYPE), WINDOWS)
	del $(PROJECT).exe
endif
ifeq ($(OS_TYPE), LINUX)
	rm $(PROJECT)
endif
ifeq ($(OS_TYPE), OSX)
	rm $(PROJECT)
endif
	

如何使用

基本上,只要如下几步就可以进行项目开发:

  1. 创建一个文件夹,命名为项目名称
  2. 然后把这个Makfile创建好,修改Makefile中的CC(编译器的路径,推荐使用MinGW)和PROJECT(项目名)字段就行
  3. 写C代码
  4. make就行啦

如果还想要使用VSCode的调试功能的话,就加上调试的luanch.json就行啦,具体的话以后有需要再增加文章说明。

总结

总之,这个Makefile就突出一个懒,所以它很多过程自动完成,所以他的缺点也很明显,目前没有自动连接库,这个以后会继续优化的。


impressionyang
消息盒子

# 暂无消息 #

只显示最新10条未读和已读信息