一、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=0
CFLAGS = `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=0OBJS =        example.oLIBS =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=0OBJS =        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.a
LIB += -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 $@

全局搜索配置,自己的项目要在自己用户下,重新设置,不要影响全局用户;

配置好后,make file加入-I,-L指定到自己目录


export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.275.b01-0.el7_9.x86_64/jre
export PATH=$JAVA_HOME/bin:$JRE_HOME/lib:$PATH
export LANG="zh_CN.UTF-8"
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/data/local/include
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/data/local/include
export LD_LIBRARY_PATH=/data/local/lib:/data/local/lib64:$LD_LIBRARY_PATH
export MAVEN_HOME=/data/test/apache-maven-3.6.3
export PATH=$MAVEN_HOME/bin:/data/local/bin:/usr/local/bin/:$PATH

c++ makefile编写相关推荐

  1. [动态库]动态库生成和使用以及Makefile编写

    转自:https://www.cnblogs.com/ljtknowns/p/5647793.html 文件目录结构如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc ...

  2. linux环境cpp/c文件的makefile编写(caffe举例)

    编译单个cpp文件 方法一.g++ 文件名.cpp,生成一个名为 "文件名.out" 的可执行文件 方法二.g++ -c 文件名.cpp -o 新文件名.o:生成一个被命名成 &q ...

  3. linux 生成和使用动态链接库和静态链接库的Makefile编写

    引用 Jesse Rei 的 linux 生成和使用动态链接库和静态链接库的Makefile编写 生成和使用动态链接库和静态链接库的Makefile编写 1. 概述 介绍linux下生成和使用动态链接 ...

  4. Linux C编程Makefile编写初步-转

    Linux C编程Makefile编写初步 假设我们有下面这样的一个程序,源代码如下:  /* main.c */  #include "mytool1.h"  #include  ...

  5. Ubuntu下使用gcc和makefile编写c语言程序

    文章目录 前言 一.gcc编写c语言程序 1.hello world的输出 2.简单程序的编译与运行 3.windows环境下的编译运行结果对比 二.makefile编写c语言程序 总结 前言 本文通 ...

  6. Linux下的makefile编写 ——陈皓《跟我一起写Makefile》学习笔记(一)

    Linux下的makefile编写 前言 本人记笔记习惯使用OneNote,在学习LinuxC++过程中发现deepin上没有大佬开发或者移植,本人技术也不精,所以决定写博客记笔记(只是习惯问题,并没 ...

  7. 嵌入式(十四)——Makefile编写及多级目录

    文章目录 工程管理器make 1.1 什么是工程 1.2 工程管理器的作用 1.3 makefile文件 真目标和伪目标 1.4 执行顺序: 1.5 多级目录的Makefile编写 隔断 多级目录下的 ...

  8. 简单Makefile编写教程

    Makefile编写 1. make和Makefile的介绍 1.1 make工具 利用make工具可以自动完成编译工作.这些工作包括: 如果仅仅修改了某几个源文件,则只重新编译这几个源文件: 如果某 ...

  9. Linux下Makefile编写语法

    原创 Linux下Makefile编写语法 2016-07-29 08:31:53 Datrilla 阅读数 1386更多 分类专栏: Linux Makefile 版权声明:本文为博主原创文章,遵循 ...

  10. Makefile 编写入门

    Makefile编写规则: 刚开始跟这些Makefile的时候发现会报错误Makefile:2: missing separator. Stop. 在make命令后出现这种错误提示,是提示第2行没有分 ...

最新文章

  1. 02、在层级未知情况下通过递归查找子物体
  2. FutureTask 实现预加载数据 在线看电子书、浏览器浏览网页等
  3. linux 查看磁盘空间 文件 文件夹 大小
  4. Minor GC、Major GC和Full GC之间的区别(转)
  5. [SpringMVC]定义多个前缀映射的问题
  6. 移动端-ibokan
  7. Eclipse导入GitHub项目两处报错处理
  8. cesium获取模型实时坐标_Cesium 顶点着色器中解算模型坐标
  9. 组态软件运行在云服务器是上,如何将本地组态画面发布到云服务器
  10. 域名实名认证多长时间_域名如何选择有利于网站优化?
  11. udp helper 的使用
  12. 【BZOJ】3396: [Usaco2009 Jan]Total flow 水流 (最大流)
  13. 1、JavaWbe基本概念
  14. python代码设计测试用例_《带你装B,带你飞》pytest成神之路2- 执行用例规则和pycharm运行的三种姿态...
  15. 企鹅号一万阅读能有多少收益?企鹅号平台补贴怎么获得
  16. 推荐 5 个精选公众号
  17. 使用Python制作专属微信小客服
  18. TL437x-EVM评估板测试手册(2)
  19. 解决anaconda下Spyder的tensorflow不能用karas的原因,用anaconda安装最新的TensorFlow版本
  20. pe系统下读不到服务器硬盘,WinPE系统里找不到硬盘怎么办 WinPE系统里找不到硬盘解决【详解】...

热门文章

  1. 客流量统计分析系统应用解决方案
  2. 正交幅度调制(QAM)
  3. mdui前端插件,有菜单对话框等
  4. 【备忘】Java菜鸟到大牛学习路线之实战篇
  5. Android应用源码英语四级单选助手答题类app源码下载
  6. rtmp代理php源码_RTMP直播系统(示例代码)
  7. UOS安装谷歌浏览器并设置中文
  8. ps一点通精品知识库
  9. 计算机系统基础(1)
  10. 阮一峰ES6之Generator函数理解