C/C++工程管理:makefile模板

2021-03-30 09:28

阅读:597

标签:执行文件   包括   add   amp   linu   项目   file   imp   二进制文件   

C/C++工程,代码文件一旦多起来,需要考虑怎样有效的组织管理它们。多数情况下可以用CMake构建,少数时候例如嵌入式linux平台,用cmake也是完全没有问题的,但总是有工程师喜欢坚持用makefile,我不知道和u-boot使用makefile有没有关系,但如果坚持要用makefile,我认为要考虑如下2点:

  1. .o/.a/.so等,生成的各种二进制文件,不要放在.c/.cpp源码同级目录,而是放在独立的构建目录,并且目录应该自动创建。
  2. 分别指定C_SRCSCXX_SRCS很麻烦,应当支持让makefile自行过滤出来。

查找makefile的教程,关键字"万能通用makefile“,以及B站上排名第一的视频,大都在讲如何编一个可执行文件目标,很少有提及静态库动态库目标的;如果makefile解决的问题仅仅是可执行文件的构建,那么完全没必要用makefile,g++ *.cpp一把梭岂不是很好?

此外,有些人不知道Address Sanitizer这一内存问题排查利器的存在,它是可以在makefile中配置的。

针对以上问题,本人用一个实际项目fibercv的代码予以实践:fibercv的代码会构建静态库(libfibercv.a)、动态库(libfibercv.so)和可执行文件(demo),并且生成目录为obj目录。

C/C++代码的目录结构:

(base) home% tree
.
├── CMakeLists.txt
├── demo
│?? └── main.cpp
├── deps
│?? ├── glad
│?? │?? ├── glad.c
│?? │?? └── glad.h
│?? ├── KHR
│?? │?? └── khrplatform.h
│?? └── stb
│??     ├── stb_image.h
│??     └── stb_image_write.h
├── fibercv
│?? ├── fc_log.c
│?? ├── fc_log.h
│?? ├── fibercv.h
│?? ├── image.cpp
│?? ├── image.h
│?? ├── improc_private.cpp
│?? ├── improc_private.h
│?? ├── imshow.cpp
│?? └── imshow.h
├── makefile
├── mingren.jpg
├── readme.md

对应的万能通用makefile如下:

#CC := clang
#CXX := clang++
#CXXFLAGS = -Ideps/ -I./
#LDFLAGS = -lglfw
#SRCS = fibercv/image.cpp fibercv/imshow.cpp fibercv/improc_private.cpp fibercv/fc_log.c deps/glad/glad.c demo/main.cpp
#all:
#	clang++ $(CXXFLAGS) $(SRCS) $(LDFLAGS) -o demo


BUILD_DIR=obj

SRCS := fibercv/image.cpp fibercv/imshow.cpp fibercv/improc_private.cpp fibercv/fc_log.c deps/glad/glad.c
C_SRCS = $(filter %.c,$(SRCS))
CXX_SRCS = $(filter %.cpp,$(SRCS))

C_OBJS := $(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SRCS))
CXX_OBJS := $(patsubst %.cpp,$(BUILD_DIR)/%.o,$(CXX_SRCS))

CC = clang
CXX = clang++
AR = ar crs

ASAN_FLAGS :=-g -fno-omit-frame-pointer -fsanitize=address

INCLUDE = -I./deps
CFLAGS += -fPIC $(ASAN_FLAGS) $(INCLUDE)
CXXFLAGS += -fPIC $(ASAN_FLAGS) $(INCLUDE)
SHARE = -fPIC -shared
SO_LDFLAGS += -lglfw

FIBERCV_LIB:=$(BUILD_DIR)/libfibercv.a
FIBERCV_SO:=$(BUILD_DIR)/libfibercv.so
DEMO=$(BUILD_DIR)/demo

all: $(FIBERCV_LIB) $(DEMO)
#all: $(FIBERCV_SO) $(DEMO)

info:
	@echo "C_SRCS:" $(C_SRCS)
	@echo "CXX_SRCS:" $(CXX_SRCS)
	@echo "C_OBJS:" $(C_OBJS)
	@echo "CXX_OBJS:" $(CXX_OBJS)

#-----------------------
# fibercv static library
#-----------------------
$(FIBERCV_LIB): $(CXX_OBJS) $(C_OBJS)
	$(AR) $@ $^

$(BUILD_DIR)/%.o: %.cpp
	mkdir -p $(@D)
	$(CXX) $(CXXFLAGS) -c $^ -o $@

$(BUILD_DIR)/%.o: %.c
	mkdir -p $(@D)
	$(CC) $(CFLAGS) -c $^ -o $@

#-----------------------
# fibercv shared library
#-----------------------
$(FIBERCV_SO): $(CXX_OBJS) $(C_OBJS)
	$(CXX) $(SHARE) $^ $(SO_LDFLAGS) -o $@

#-----------------------
# demo executable
#-----------------------
DEMO_SRCS := demo/main.cpp
DEMO_CXXFLAGS := -I./
export PKG_CONFIG_PATH=/home/zz/soft/glfw3/lib/pkgconfig:$PKG_CONFIG_PATH
DEMO_LDFLAGS := -lfibercv -Lobj/ `pkg-config --libs glfw3` -ldl -lpthread
$(DEMO): $(DEMO_SRCS)
	$(CXX) $(DEMO_CXXFLAGS) $^ $(DEMO_LDFLAGS) -o $@

.PHONY:
clean:
	rm -f $(C_OBJS)
	rm -f $(CXX_OBJS)
	rm -f $(FIBERCV_LIB)
	rm -f $(FIBERCV_SO)
	rm -f $(DEMO)

参考

  • [linux从零到精通] gcc和Makefile,多文件编译神器是怎么练成的,解放程序员的双手就这么简单
  • Makefile基本模板(包括静态链接库、动态链接库、可执行文件)
  • Make 命令教程

C/C++工程管理:makefile模板

标签:执行文件   包括   add   amp   linu   项目   file   imp   二进制文件   

原文地址:https://www.cnblogs.com/zjutzz/p/13586041.html


评论


亲,登录后才可以留言!