c++ makefile编写
2017-11-04 15:02
190 查看
一、gcc命令从目的上看,gcc命令和makefile的功能是一样,即是把源文件编译后生成可执行文件或.o二进制文件。gcc命令中有许多的额外的参数,本文仅介绍以下几种最简单和常用的方法:有helloworld.c文件如下:
#include <stdio.h> int main() { printf("helloworld!\n"); return 0; }使用如下gcc命令,将在同一文件目录下生成a.out可执行文件,在terminal中运行该文件即可在屏幕中打印出helloworld!:
$ gcc helloworld.c使用如下gcc命令,将在同一文件目录下生成helloworld.o二进制文件,它可以被用来连接文件:
$ gcc -c helloworld.c如果要生成特定名称的可执行文件,可以使用如下gcc命令,它将生成helloworld可执行文件,区别于a.out可执行文件,在termianl执行它可以打印出helloworld!:
$ gcc helloworld.c -o helloworld以上三种gcc命令,主要区别是参数不同,-c和-o的区别在于,-c只编译不连接,故只生成.o的二进制文件,-o即指定名称输出可执行文件。对于单个或者几个的源文件,使用gcc命令即可,但是一旦文件具有依赖关系,gcc命令的执行顺序是需要规定的,否则无法顺序编译项目,这是gcc命令的缺点,而makefile区别于gcc命令的地方正在于它能规定好文件间的依赖关系,以及加入依赖的库文件和头文件。如果要引用其它目录下的头文件,其gcc命令如下,采用-I的参数:
$ gcc -I /ycl/include/ helloworld.c -o helloworld如果要引用其它的目录下的库文件,如libmlib.so,其gcc命令如下,采用-L的参数:
$ gcc -L /ycl/lib –lmlib helloworld.c -o helloworld二、makefile简要语法makefile的用处是告诉编辑器,本项目以怎样的规则进行编译和链接,运行make命令需要makfile文件作为支撑。要弄明白makefile,其关键是理解它的核心语法(源自博文http://blog.csdn.net/liang13664759/article/details/1771246 ):target ... : prerequisites ...command......target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。prerequisites就是,要生成那个target所需要的文件或是目标。command也就是make需要执行的命令。(任意的Shell命令)这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。示例代码如下:CXX = g++CXXFLAGS = -O2 -g -Wall -fmessage-length=0CFLAGS = `pkg-config --cflags lcm`LDFLAGS=`pkg-config --libs lcm`\-lpthreadOBJS = DSRC_module.o \LCMHandler.o \UDPHandler.oTARGET = DSRC_module$(TARGET): $(OBJS)$(CXX) -o $@ $^ $(LDFLAGS) DSRC_module.o: DSRC_module.cpp $(CXX) $(CFLAGS) -I. -o $@ -c $<LCMHandler.o: LCMHandler.cpp $(CXX) $(CFLAGS) -I. -o $@ -c $<UDPHandler.o: UDPHandler.cpp $(CXX) $(CFLAGS) -I. -o $@ -c $<all: $(TARGET)clean: rm -f $(OBJS) $(TARGET)示例代码中出现了变量,makefile中变量采用$(变量)的方法使用,如$(TARGET)即表示DSRC_module。该makefile的目的是生成名为DSRC_ module的可执行文件,即$(TARGET),它的依赖文件是$(OBJS)所代表的DSRC_module.o、LCMHandler.o、UDPHandler.o三个文件。由于这三个文件都未生成,故针对每一个文件都需要进行编译生成,所以有三个.o文件为目标的makefile语句。文中特殊字符说明如下:$@--目标文件,$^--所有的依赖文件,$<--第一个依赖文件。比如在如下的代码中,$@代表DSRC_module.cpp,$<代表第一个依赖文件,也就是DSRC_module.cpp。
DSRC_module.o: DSRC_module.cpp $(CXX) $(CFLAGS) -I. -o $@ -c $<三、makefile编写使用装用CDT插件的eclipse可以直接生成helloworld项目的makefile项目,makefile内容如下:
CXXFLAGS = -O2 -g -Wall -fmessage-length=0 OBJS = example.o LIBS = TARGET = example $(TARGET): $(OBJS) $(CXX) -o $(TARGET) $(OBJS) $(LIBS) all: $(TARGET) clean: rm -f $(OBJS) $(TARGET)其中CXXFLAGS是编译参数变量,CXX是makefile内置变量,CXX默认表示g++(C++编译器)。这个makefile的有两个功能:①编译代码,将example.c编译成example.o并链接成example可执行文件;②清除项目,当项目需要重新编译或整理时,使用make clean命令即可清除生的OBJS和TARGET变量中的名称。在上述代码中,之所以依赖文件没有.c文件,这是因为此处使用了makefile的自动推导功能,只要依赖关系中有.o文件,它会自动添加同名称的.c文件作为依赖文件,并由$(CXX) -o example.o可以自动推导出$(CXX) -o example.c。
$(TARGET): $(OBJS) $(CXX) -o $(TARGET) $(OBJS) $(LIBS)基于上述的makefile文件,如果此时需要添加新的.c和.h文件,则改变OBJS的内容即可,比如填加test.c文件,则代码如下(注意test.o前的不能加空格,需用tab键):
CXXFLAGS = -O2 -g -Wall -fmessage-length=0OBJS = example.o\test.oLIBS =TARGET = example$(TARGET): $(OBJS) $(CXX) -o $(TARGET) $(OBJS) $(LIBS)all: $(TARGET)clean:rm -f $(OBJS) $(TARGET)如果需要添加头文件,那么注意尽量不要使用makefile的自动推导功能,否则可能找不到头文件,则只需添加和修改如下代码:
CXXFLAGS = -O2 -g -Wall -fmessage-length=0 OBJS = example.cpp\ test.cpp
HEADER_DIR = -I/home/duser/dot3
LIBS =TARGET = example$(TARGET): $(OBJS) $(CXX) -o $(TARGET) $(OBJS) $(LIBS)all: $(TARGET)clean:rm -f $(TARGET)如果需要添加库文件,需要两个变量,LDFLAGS---相当于库所在路径,LIBS---要链接的库文件libtest.a。则只需添加和修改如下代码:
LDFLAGS += -L/lib libt.aLIB += -ltest$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $(TARGET) $(LDFLGS) $(LIBS) $(OBJS) -lpthread -ldl-lpthread 先找动态库.so 再找静态库.a-ldl 如果程序中使用dloopen dlsym dlclose dlerror 显示加载动态库,需要设置链接选项上面写法会找到不到头文件,可以添加以下内容:INCLUDE = -I/usr/local/mysql/include/%.o: %.cpp$(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@%.o: %.hxx.pb.cc$(CC) -c $(CFLAGS) $(INCLUDE) $< -o $@
相关文章推荐
- linux环境下c++的编写、调试以及makefile多文件连编需要注意的问题
- 小型C/C++项目的makefile编写
- 一个C++项目的Makefile编写-Tony与Alex的对话系列
- 【ZZ】一个C++项目的Makefile编写-Tony与Alex的对话系列
- Linux C/C++ 多目标文件的链接及其Makefile编写($<与$^)
- C/C++ 编写一个通用的Makefile 来编译.c .cpp 或混编
- C、C++的Makefile的编写以及动、静态库的制作调用(包括MAC地址的获取及MD5加密)
- 一个C++项目的Makefile编写-Tony与Alex的对话系列
- C++ 学习笔记(三) 编写makefile
- C和C++混合编程的Makefile的编写!
- [Linux-C++] Make 的使用和Makefile的编写
- C、C++的Makefile的编写以及动、静态库的制作调用(包括MAC地址的获取及MD5加密)
- C++ 学习笔记(三) 编写makefile(二)
- [Linux-C++] Makefile 编写
- [Linux-C++] Makefile编写
- 内核模块的基本编写以及Makefile的编写
- Linux下,使用Makefile文件编写一个简单的彩色进度条
- C++ 编写自己的异常类
- ADT+CDT VS +NDK +Eclipse 编写C++程序
- C#如何调用C++编写的DLL