通用Makefile的编写和在项目工程中使用Makefile(包括动态库、静态库的链接、整个工程联合编译)
2017-12-03 14:51
375 查看
一、通用Makefile文件的编写
(1)、什么是通用Makefile?
这里的通用Makefile指的是它既能编译可执行文件、也能编译动态链接库、又能编译静态库,只需要更改很少的内容即可。
(2)、写一个通用Makefile
上面就是一个通用的Makefile模板,我们可以通过它可以写出对可执行程序编译的Makefile,也可以写出对动态链接库编译的Makefile,当然也可以用它写出对静态库编译的Makefile。
下面,我们通过一个工程实例,用通用Makefile模板来编写一下不同功能的Makefile
二、整个项目工程都包括什么?
之前讲过Makefile的编写规则,我们知道了简单的Makefile如何编写,那在编写软件项目时,一个Makefile往往不够用了。
举个项目工程实例:
一个工程目录下一般有7个目录,一个联合编译Makefile文件:
<1>、bin目录:一般存放可执行程序
<2>、etc目录:存放配置文件
<3>、lib目录 :存放所有的库文件,包括动态库和静态库
<4>、inc目录:存放所有的公共头文件,一般是动态库和静态库对应的头文件
<5>、src目录:存放项目源码文件和编译它的Makefile文件
<6>、static目录:存放静态库源文件和编译它的Makefile文件
<7>、dynamic目录:存放动态库源文件和编译它的Makefile文件
三、用(一)中的Makefile模板为src、static、dynamic目录下的源文件编写不同的Makefile文件
(1)、为static目录,即静态链接库源代码目录。在此目录下要生成静态链接库文件libstatic_test.a
Makefile文件:
(2)、为dynamic目录,即动态链接库源代码目录,在此目录下生成动态链接库 libdynamic_test.so
Makefile文件:
(3)、为src目录,即工程源代码目录。在此目录下要通过链接动态链接库libdynamic_test.so和静态库libstatic_test.a 来生成可执行文件main
Makefile文件:
以上三步完成后,整个工程的目录树是这样的:
四、编写联合编译Makefile文件
按照以前的思路,我们需要去每个目录下分别执行每个Makefile,最后生成可执行文件。
这个方法太麻烦了,现在有一个更好的方法:编写联合编译Makefile文件,它和src、bin等在一个目录下。在上面的图中有一个单独的Makefile文件未被标识,它就是联合编译Makefile文件。
联合编译Makefile文件:
因为联合编译Makefile文件在工程目录下,所以在工程目录下执行make命令:
执行安装命令,将可执行文件main安装到bin目录:
执行可执行程序:
好,这样整个工程就编译完成了,生成的可执行文件在bin目录下!
最后,我们再来看一下当前的工程目录树结构:
(1)、什么是通用Makefile?
这里的通用Makefile指的是它既能编译可执行文件、也能编译动态链接库、又能编译静态库,只需要更改很少的内容即可。
(2)、写一个通用Makefile
#-------------------------配置区域----------------------- #DIR指的是.o文件和.c文件所在的目录 DIR= #BIN指的是最终生成的目标对象名(包括路径),它可以是可执行程序、动态链接库或静态链接库 BIN=$(DIR)/ #SHARE特指链接生成动态链接库对象时的编译选项 SHARE=--share #CFLAG即compile flag,表示在编译时所加入的选项参数 #参数包括 #-Wall : 编译后显示所有警告信息 #-g : 编译时加入调试信息,以便之后可以用gdb调试 #-fPIC : 编译动态链接库时加入的选项 #-I./inc: -I选项指定从哪个目录寻找头文件,在这指定之后,在源文件中包含头文件就可以使用<>,这里./inc即为指定的目录 CFLAG= #LFLAG即library flag,表示链接生成可执行程序时所要链接的所有库的选项参数 #-L./lib : -L指示动态/静态链接库所在的目录,这里./lib即所在的目录 #-l : -l指示动态/静态链接库的名字,注意: 这里的库名字并不包括前缀(lib)和后缀(.a或.so) #$(SHARE) : 取SHARE变量对应的动态链接库链接选项--share LFLAG= #CC即编译链接命令gcc -o 用于编译或者链接动态库以及可执行程序 CC=gcc -o #AR即ar -cr ,ar -cr是专门链接生成静态库的命令 #-c : 即create,创建静态库 #-r : 即replace,当静态库改变时,替代原有静态库 AR=ar -cr #最终用的是哪个链接命令 #链接生成动态库和可执行程序用CC #链接生成静态库用AR CO=$(CC) #-------------------------以下为通用不变区域----------------------- #SRC指的是指定目录下的所有.c文件名,OBJ指的是指定目录下的所有.o文件名 SRC=$(wildcard $(DIR)/*.c) OBJ=$(patsubst %.c, %.o, $(SRC)) #链接命令 all:$(BIN) $(BIN):$(OBJ) $(CO) $@ $^ $(LFLAG) #编译命令 $(DIR)/%.o:$(DIR)/%.c $(CC) $@ -c $< $(CFLAG) #清除无用文件 .PHONY:clean clean: rm $(OBJ) $(BIN)
上面就是一个通用的Makefile模板,我们可以通过它可以写出对可执行程序编译的Makefile,也可以写出对动态链接库编译的Makefile,当然也可以用它写出对静态库编译的Makefile。
下面,我们通过一个工程实例,用通用Makefile模板来编写一下不同功能的Makefile
二、整个项目工程都包括什么?
之前讲过Makefile的编写规则,我们知道了简单的Makefile如何编写,那在编写软件项目时,一个Makefile往往不够用了。
举个项目工程实例:
一个工程目录下一般有7个目录,一个联合编译Makefile文件:
<1>、bin目录:一般存放可执行程序
<2>、etc目录:存放配置文件
<3>、lib目录 :存放所有的库文件,包括动态库和静态库
<4>、inc目录:存放所有的公共头文件,一般是动态库和静态库对应的头文件
<5>、src目录:存放项目源码文件和编译它的Makefile文件
<6>、static目录:存放静态库源文件和编译它的Makefile文件
<7>、dynamic目录:存放动态库源文件和编译它的Makefile文件
三、用(一)中的Makefile模板为src、static、dynamic目录下的源文件编写不同的Makefile文件
(1)、为static目录,即静态链接库源代码目录。在此目录下要生成静态链接库文件libstatic_test.a
Makefile文件:
#------------------------------配置区域---------------------------- DIR=./static #静态库名以lib为前缀,.a为后缀 BIN=$(DIR)/libstatic_test.a SHARE=--share CFLAG= LFLAG= CC=gcc -o AR=ar -cr #编译静态库用ar -cr命令 CO=$(AR) #-------------------------以下为通用不变区域----------------------- SRC=$(wildcard $(DIR)/*.c) OBJ=$(patsubst %.c, %.o, $(SRC)) all:$(BIN) $(BIN):$(OBJ) $(CO) $@ $^ $(LFLAG) $(DIR)/%.o:$(DIR)/%.c $(CC) $@ -c $< $(CFLAG) .PHONY:clean clean: rm $(OBJ) $(BIN)
(2)、为dynamic目录,即动态链接库源代码目录,在此目录下生成动态链接库 libdynamic_test.so
Makefile文件:
#------------------------------配置区域---------------------------- DIR=./dynamic #动态库名以lib为前缀,以.so为后缀 BIN=$(DIR)/libdynamic_test.so SHARE=--share #动态链接库编译时需要-fPIC选项 CFLAG=-fPIC #链接动态库需要--share选项 LFLAG=$(SHARE) CC=gcc -o AR=ar -cr #编译动态链接库用gcc -o命令 CO=$(CC) #-------------------------以下为通用不变区域----------------------- SRC=$(wildcard $(DIR)/*.c) OBJ=$(patsubst %.c, %.o, $(SRC)) all:$(BIN) $(BIN):$(OBJ) $(CO) $@ $^ $(LFLAG) $(DIR)/%.o:$(DIR)/%.c $(CC) $@ -c $< $(CFLAG) .PHONY:clean clean: rm $(OBJ) $(BIN)
(3)、为src目录,即工程源代码目录。在此目录下要通过链接动态链接库libdynamic_test.so和静态库libstatic_test.a 来生成可执行文件main
Makefile文件:
#-------------------------配置区域----------------------- #源码所在的目录 DIR=./src #在源码所在目录下生成可执行文件main BIN=$(DIR)/main SHARE=--share #显示所有编译警告,并指示公共头文件(静态库和动态库的头文件)所在目录 CFLAG= -Wall -I../inc #在../lib目录中链接两个外部库文件 LFLAG=-L../lib -ldynamic_test -lstatic_test CC=gcc -o AR=ar -cr #使用gcc -o 链接命令 CO=$(CC) #-------------------------以下为通用不变区域----------------------- #SRC指的是指定目录下的所有.c文件名,OBJ指的是指定目录下的所有.o文件名 SRC=$(wildcard $(DIR)/*.c) OBJ=$(patsubst %.c, %.o, $(SRC)) #链接命令 all:$(BIN) $(BIN):$(OBJ) $(CO) $@ $^ $(LFLAG) #编译命令 $(DIR)/%.o:$(DIR)/%.c $(CC) $@ -c $< $(CFLAG) #清除无用文件 .PHONY:clean clean: rm $(OBJ) $(BIN)
以上三步完成后,整个工程的目录树是这样的:
四、编写联合编译Makefile文件
按照以前的思路,我们需要去每个目录下分别执行每个Makefile,最后生成可执行文件。
这个方法太麻烦了,现在有一个更好的方法:编写联合编译Makefile文件,它和src、bin等在一个目录下。在上面的图中有一个单独的Makefile文件未被标识,它就是联合编译Makefile文件。
联合编译Makefile文件:
test: make -C ./dynamic #make -C:进入指定的目录下执行make命令 make -C ./static #将静态、动态库文件拷贝到lib目录下 cp ./static/libstatic_test.a ./lib cp ./dynamic/libdynamic_test.so ./lib make -C ./src install: #为lib目录下的动态链接库文件在/usr/lib目录下创建软连接,这里使用的必须是绝对路径 sudo ln -s /home/sunxiwang/03AgainStudyLinux/workspace/04makefile/03makefile/lib/libdynamic_test.so /usr/lib/libdynamic_test.so #将最后生成的可执行文件main拷贝到./bin目录下 mv ./src/main ./bin clean: make clean -C ./dynamic #make clean -C: 进入指定目录下执行make clean命令 make clean -C ./static make clean -C ./src
因为联合编译Makefile文件在工程目录下,所以在工程目录下执行make命令:
执行安装命令,将可执行文件main安装到bin目录:
执行可执行程序:
好,这样整个工程就编译完成了,生成的可执行文件在bin目录下!
最后,我们再来看一下当前的工程目录树结构:
相关文章推荐
- gcc编译步骤 动态库、静态库的使用、gdb调试、Makefile编写
- gcc链接g++编译生成的静态库和动态库的makefile示例
- ubuntu下使用VScode打开本地使用makefile编译的工程(包括命令行参数的配置)
- gcc链接g++编译生成的静态库和动态库的makefile示例
- 用于编译可执行程序,静态库,动态库的通用的Makefile
- g++ 编译链接C++代码, 生成与使用静态库和动态库
- makefile 编写,编译动态库,编译静态库
- g++ 编译链接C++代码, 生成与使用静态库和动态库
- 编译静态库和动态库的Makefile文件
- Linux编译链接问题----静态库和动态库
- 静态编译动态编译;静态链接动态链接;静态库和动态库
- linux下静态库、动态库的编译和使用
- 如何使用自己的makefile编译android ndk项目
- GCC 编译动态链接库和静态链接库 + 大型工程Makefile编写 + Linux环境变量的设置和查看方法
- linux下静态库、动态库的编译和使用 .
- makefile编译静态库和动态库
- 静态库/动态库的编译和使用方法学习记录
- 静态编译动态编译;静态链接动态链接;静态库和动态库
- linux 静态库与动态库的编译和使用
- 在Linux下如何使用GCC编译程序、简单生成静态库及动态库。