博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GNU make使用(一)
阅读量:5229 次
发布时间:2019-06-14

本文共 3923 字,大约阅读时间需要 13 分钟。

[时间:2017-01] [状态:Self]

[关键词:makefile,gcc,编译,动态库,静态库,可执行文件,shell命令]

引言

前段时间在Linux下编写一个可测试的程序发现,我对makefile实践太少各种别扭吧。因此参考网上的一篇文章,自己尝试下常用的可执行文件、静态库、动态库的自动编译,以及调用,作为后续开发的参考。

本文主要包括三部分:

  • 可执行文件的Makefile
  • 静态库*.a的Makefile
  • 动态库*.b的Makefile

这是我对Makefile学习总结的第二篇文章,其他的可参考。

本文主要参考,感谢@竹林听雨的分享。

在Linux下编译时常用的命令有:

  • make : 编译整个工程
  • make install : 输出编译之后的结果,可能是系统目录,也可能是自定义目录
  • make clean : 清除编译过程中的中间文件,比如.o,.s等
  • make distclean : 恢复编译前的环境,注意本文中使用make veryclean

1. 可执行文件的Makefile

代码如下:

#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件SOURCE  := $(wildcard *.c) $(wildcard *.cpp)OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))#目标文件名,输入任意你想要的执行文件名TARGET  := exe_check#编译参数CC      := g++LIBS    :=LDFLAGS :=DEFINES :=INCLUDE := -I.CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H#下面的基本上不需要做任何改动了.PHONY : everything objs clean veryclean rebuildeverything : $(TARGET)all : $(TARGET)objs : $(OBJS)rebuild: veryclean everythingclean :    rm -fr *.so    rm -fr *.overyclean : clean    rm -fr $(TARGET)#这里是实际完成编译的命令$(TARGET) : $(OBJS)    $(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)

如果你是直接拷贝这个makefile的话,麻烦检查下上面的shell命令前空白必须是Tab键,不能是空格。

2. 静态库的Makefile和调用示例

Makefile文件如下,主要使用ar/ranlib打包命令:

#共享库文件名,lib*.aTARGET  := libtest.a#编译参数CC      := g++AR      = arRANLIB  = ranlibLIBS    :=LDFLAGS :=DEFINES :=INCLUDE := -I.CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H#下面的基本上不需要做任何改动了#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件SOURCE  := $(wildcard *.c) $(wildcard *.cpp)OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))#头文件,自动查找.h文件HEADER := $(wildcard *.h).PHONY : everything objs clean veryclean rebuild installeverything : $(TARGET)all : $(TARGET)objs : $(OBJS)rebuild: veryclean everything             clean :    rm -fr *.overyclean : clean    rm -fr $(TARGET)install :    test -f ./sample/lib && echo ' ' || mkdir ./sample/lib    cp $(TARGET) ./sample/lib/    test -f ./sample/include/ && echo ' ' || mkdir ./sample/include    cp $(HEADER) ./sample/include/$(TARGET) : $(OBJS)    $(AR) cru $(TARGET) $(OBJS)    $(RANLIB) $(TARGET)

由于一般动态库或者静态库需要安装,这里添见了install标签。

调用静态库的话,需要使用下面makefile,这里仅给出相对可执行文件的makefile差别,如下:

#compile and lib parameter#编译参数CC      := g++LIBS    := -ltestLDFLAGS := -L./lib/DEFINES :=INCLUDE := -I. -I./includeCFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H

主要加入了静态库所在的目录及-l命令。

3. 动态库的Makefile及调用示例

Makefile如下,直接调用g++编译成动态库:

#共享库文件名,lib*.soTARGET  := libtest.so#编译参数CC      := g++LIBS    :=LDFLAGS :=DEFINES :=INCLUDE := -I.CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_HSHARE   := -fpic -shared -o  #下面的基本上不需要做任何改动了#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件SOURCE  := $(wildcard *.c) $(wildcard *.cpp)OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))#头文件,自动查找.h文件HEADER := $(wildcard *.h).PHONY : everything objs clean veryclean rebuild installeverything : $(TARGET)all : $(TARGET)objs : $(OBJS)    $(CC) -c -fPIC $(SOURCE)rebuild: veryclean everything         clean :    rm -fr *.o    veryclean : clean    rm -fr $(TARGET)install :    test -d ./sample/lib && echo ' ' || mkdir ./sample/lib    cp $(TARGET) ./sample/lib/    test -d ./sample/include/ && echo ' ' || mkdir ./sample/include    cp $(HEADER) ./sample/include/$(TARGET) : objs    $(CC) $(CXXFLAGS) $(SHARE) $@ $(OBJS) $(LDFLAGS) $(LIBS)

这里就是需要关注下-fPIC-fpic的不同使用位置,否则可能会出现编译错误。

调用动态库的示例代码的Makefile跟可执行文件的主要区别如下:

#目标文件名,输入任意你想要的执行文件名TARGET  := shared_check#编译参数CC      := g++LIBS    := -ltestLDFLAGS := -L./lib/DEFINES :=INCLUDE := -I. -I./includeCFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H

4. 小结

简单整理完了,直接看Makefile确实不是很难,但是其中涉及比较多的shell命令,比如wild、test、patsubst以及gcc编译指令,这方面有待加强。

不做实际验证才不会明白其中有各种坑的。简单过一遍GNU Makefile还是很有帮助的。

本文所有涉及的Makefile及源码可以从我的git下载,url:https://git.oschina.net/Tocy/SampleCode.git。相关文件位于makefile-template文件夹下。

转载于:https://www.cnblogs.com/tocy/p/makefile-reference-1.html

你可能感兴趣的文章
Pat1128:N Queens Puzzle
查看>>
占位 SC
查看>>
《算法心得:高效算法的奥秘(原书第2版)》
查看>>
知道力——彻底超越执行力的25条职场新思维
查看>>
序号的结构层次顺序
查看>>
AC自动机
查看>>
LCA算法解析-Tarjan&倍增&RMQ
查看>>
BZOJ4241 历史研究 莫队 堆
查看>>
BZOJ1191 [HNOI2006]超级英雄Hero 二分图匹配
查看>>
进制转换2016/3/5
查看>>
片段缓存
查看>>
【转】浅谈JavaScript中forEach与each
查看>>
linux指定目录安装软件后,程序找不到共享库问题
查看>>
php连接、操作mysql数据库
查看>>
hello world!
查看>>
hdu1246
查看>>
android开发中如何结束所有的activity
查看>>
面向对象的一个例子
查看>>
公交线路查询接口文档
查看>>
一个类似抖音 APP 拍摄按钮效果的控件
查看>>