发现了一个通用的Makefile

即使有子文件夹也能处理。

Makefile:

.PHONY: clean all

# annotation when release version
DEBUG       :=
TARGET_PROG := main.out

# project directory
DEBUG_DIR   := ./debug
RELEASE_DIR := ./release
BIN_DIR     := $(if $(DEBUG), $(DEBUG_DIR), $(RELEASE_DIR))

# shell command
CC    := gcc
CXX   := g++
RM    := rm -rf
MKDIR := mkdir -p
SED   := sed
MV    := mv

# init sources & objects & depends
sources_all := $(shell find . -name "*.c" -o -name "*.cpp" -o -name "*.h")
sources_c   := $(filter %.c, $(sources_all))
sources_cpp := $(filter %.cpp, $(sources_all))
sources_h   := $(filter %.h, $(sources_all))
objs        := $(addprefix $(BIN_DIR)/,$(strip $(sources_cpp:.cpp=.o) $(sources_c:.c=.o)))
deps        := $(addprefix $(BIN_DIR)/,$(strip $(sources_cpp:.cpp=.d) $(sources_c:.c=.d)))

# create directory
$(foreach dirname,$(sort $(dir $(sources_c) $(sources_cpp))),  $(shell $(MKDIR) $(BIN_DIR)/$(dirname)))

# complie & link variable
CFLAGS     := $(if $(DEBUG),-g -O, -O2)
CFLAGS     += $(addprefix -I ,$(sort $(dir $(sources_h))))
CXXFLAGS    = $(CFLAGS)
LDFLAGS    :=
LOADLIBES  += #-L/usr/include/mysql
LDLIBS     += #-lpthread -lmysqlclient

# add vpath
vpath %.h $(sort $(dir $(sources_h)))
vpath %.c $(sort $(dir $(sources_c)))
vpath %.cpp $(sort $(dir $(sources_cpp)))

# generate depend files
# actually generate after object generated, beacasue it only used when next make)
ifneq "$(MAKECMDGOALS)" "clean"
sinclude $(deps)
endif

# make-depend(depend-file,source-file,object-file,cc)
define make-depend
  $(RM) $1;                                       $4 $(CFLAGS) -MM $2 |                           $(SED) ‘s,\($(notdir $3)\): ,$3: ,‘ > $1.tmp;   $(SED) -e ‘s/#.*//‘                                    -e ‘s/^[^:]*: *//‘                              -e ‘s/ *\\$$//‘                                 -e ‘/^$$/ d‘                                    -e ‘s/$$/ :/‘ < $1.tmp >> $1.tmp;        $(MV) $1.tmp $1;
endef

# rules to generate objects file
$(BIN_DIR)/%.o: %.c
    @$(call make-depend,$(patsubst %.o,%.d,[email protected]),$<,[email protected],$(CC))
    $(CXX) $(CFLAGS) -o [email protected] -c $<

$(BIN_DIR)/%.o: %.cpp
    @$(call make-depend,$(patsubst %.o,%.d,[email protected]),$<,[email protected],$(CXX))
    $(CXX) $(CXXFLAGS) -o [email protected] -c $<

# add-target(target,objs,cc)
define add-target
  REAL_TARGET += $(BIN_DIR)/$1
  $(BIN_DIR)/$1: $2
    $3 $(LDFLAGS) $$^ $(LOADLIBES) $(LDLIBS) -o [email protected]
endef

# call add-target
$(foreach targ,$(TARGET_PROG),$(eval $(call add-target,$(targ),$(objs),$(CXX))))

all: $(REAL_TARGET)

clean:
    $(RM) $(BIN_DIR)

看看示例工程的编译过程:

编译完成后,我们看看是运行效果:

示例工程见:百度网盘\软件源码\testGeneralMakefile.tar.gz

完。

时间: 2025-01-02 13:50:07

发现了一个通用的Makefile的相关文章

一个通用的Makefile (转)

据http://bbs.chinaunix.net/thread-2300778-1-1.html的讨论,发现还是有很多人在问通用Makefile的问题,这里做一个总结.也作为以后的参考. 笔者在写程序的时候会遇到这样的烦恼:一个项目中可能会有很多个应用程序,而新建一个应用程序则所有的Makefile都要重写一遍,虽然可以部分的粘帖复制,但还是感觉应该找到更好的解决途径:另外当一个应用程序中包含多个文件夹时通常要在每个目录下创建一个Makefile,当有数十个文件夹时,要创建如此多的Makefi

Linux C编程学习4---多文件项目管理、Makefile、一个通用的Makefile

GNU Make简介 大型项目的开发过程中,往往会划分出若干个功能模块,这样可以保证软件的易维护性. 作为项目的组成部分,各个模块不可避免的存在各种联系,如果其中某个模块发生改动,那么其他的模块需要相应的更新.如果通过手动去完成这个工作的话,对于小型的项目可能还行,但是对于比较大型的项目就几乎是不可能的. 因此Linux 系统提供了一个自动维护和生成目标程序的工具 make,它可以根据各个模块的更改情况去重新编译连接目标代码 Make 工具的作用就是实现编译连接过程的自动化.它定义了一种语言,用

编写一个通用的Makefile文件

1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe 1.2体验在VC下程序的编译 a.先编译,在链接 b.修改了哪个文件,就单独编译此文件,在链接 c.修改了哪个头文件,就单独编译使用该头文件的源文件,在链接 1.3在linux下实现上述要求 2.编写一个测试的Makefile 2.1直接编译链接 1 gcc -o test a.c b.c 缺点:改变其中一

一个通用的Makefile

一 makefile的作用 Makefile是用于自动编译和链接的,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是所有的文件都需要重新编译,Makefile中记录有文件的信 息,在make时会决定在链接的时候需要重新编译哪些文件.Makefile的宗旨就是:让编译器知道要编译一个文件需要依赖其他的哪些文件.当那些依赖文件有了改变,编译器会自动发现最终的生成文件已经过时,而应该重新编译相应的模块. makefile带来的好处就是—"自动化编译",一旦写好,只需要

一个通用的Makefile框架

先做一个简单的记录,后续有时间再慢慢完善补充细节. 先上一个整体图片: 其中,最重要的文件就是:program_template.mk. 下面是program_template.mk最重要的内容: $(1)_COBJS = $$(patsubst $$($(1)_SDIR)%.c,$$($(1)_BIN)/%.o,$$($(1)_CSRCS)) $(1)_OBJS = $$($(1)_COBJS) $(1)_COBJDEPS = $$(patsubst $$($(1)_SDIR)%.c, $$(

我所使用的一个通用的Makefile模板

话不多说,请看: 我的项目有的目录结构有: dirls/ ├── include │   └── apue.h ├── lib │   ├── error.c │   ├── error.o │   └── Makefile ├── src │   ├── dirls.c │   ├── dirls.out │   └── Makefile └── test_client 而我的Makefile模板代码如下: SRCS = $(wildcard *.c ../lib/*.c) #wildcard

C/C++ 编写一个通用的Makefile 来编译.c .cpp 或混编

1.虽然能编译出程序,但是会提示错误.目前暂未解决 make: sinclude: Command not foundmake: *** [test] Error 127 2. 后续主要要修改的部分: 1> PROGRAM := hello # 设置运行程序名 2> SRCDIRS := .  # 源程序位于当前目录下 3> SRCEXTS := .c .cpp  # 源程序文件有 .c 和 .cpp 两种类型 4> CFLAGS := -g # 为 c 目标程序包含 gdb 调试

一个通用的c/c++Makefile模版

一个codeproject上发现的通用c/c++的Makefile模版,比较简单好用,共享之 ############################################################################# # # Generic Makefile for C/C++ Program # # License: GPL (General Public License) # Author: whyglinux <whyglinux AT gmail DOT

如何编写一个工程文件夹下通用的Makefile

新建工程文件夹,在里面新建 bsp.imx6ul.obj 和project 这 3 个文件夹,完成以后如图所示: 新建的工程根目录文件夹 其中 bsp 用来存放驱动文件:imx6ul 用来存放跟芯片有关的文件,比如 NXP 官方的 SDK库文件:obj 用来存放编译生成的.o 文件:project 存放 start.S 和 main.c 文件,也就是应用文件:将十二章实验中的 cc.h.fsl_common.h.fsl_iomuxc.h 和 MCIMX6Y2.h 这四个文件拷贝到文件夹 imx6