博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
利用makefile文件编译c++源文件
阅读量:7188 次
发布时间:2019-06-29

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

一、基础知识介绍

在Linux下,要想编译c++项目,并生成可执行文件,需要使用到makefile文件。
c++从代码到可执行文件,经历了编译和链接两阶段。

编译阶段:编译时,编译器检查语法、函数的申明等是否正确。对于函数申明,一般是你需要告诉编译器头文件的所在位置。如果所有的检查都正确,编译器就可以编译出相应的中间文件(即.o文件)。一般来说,每个源文件都应该对应于一个.o文件。链接阶段:根据编译结果(即.o文件)生成可执行文件。

如下图所示:

20170707233901025

这里写图片描述

注意:在Linux下,可以通过“ldd 可执行文件名” 查看编译链接此可执行文件时,用到了那些系统库。

二、编写makefile文件

#定义变量,使用变量:$(变量名)CC=g++#定义变量srcs,表示需要编译的源文件,需要表明路径,如果直接写表示这些cpp文件和makefile在同一个目录下,如果有多个源文件,每行以\结尾SRCS=main.cpp\        udp.cpp#定义变量OBJS,表示将原文件中所有以.cpp结尾的文件替换成以.o结尾,即将.cpp源文件编译成.o文件OBJS=$(SRCS:.cpp=.o)#定义变量,表示最终生成的可执行文件名EXEC=maincpp#start,表示开始执行,冒号后面的$(OBJS)表示要生成最终可执行文件,需要依赖那些.o文件的start:$(OBJS)        #相当于执行:g++ -o maincpp .o文件列表,-o表示生成的目标文件        $(CC) -o $(EXEC) $(OBJS)#表示我的.o文件来自于.cpp文件.cpp.o:        #如果在依赖关系中,有多个需要编译的.cpp文件,那么这个语句就需要执行多次。-c $

注意:上述文件中的cpp文件表示是c++源文件,如果是c源文件,一般文件名为”文件名.c“,如果要利用上述makefile文件编译链接c源文件,只需要将上述makefile文件中的cpp修改成c,g++修改成gcc即可。

上述makefile文件配置中,如果某个cpp文件被修改过,那么在执行make时,将会只编译修改过的cpp文件,但链接时,还是需要用到所有的.o中间文件。

三、生成一个so库文件

比如,我们在实际开发过程中,写了一个公共的功能,那么这个公共的功能如何在所有需要用到的项目中使用,一般有两种方式,一种是源码共享,即将源码提供给使用方;另外一种是提供一个类似于Linux提供的库文件的so文件。这里我们就来用C语言编写并生成一个so库文件。
假如我们需要打包成库文件的源码为mylib.c,里面提供了一个比较大小的函数,如下所示:

mylib.c:int max(int x,int y){    if(x>y){        return x;    }    return y;}

修改makefile文件:

#c编译器,g++是c++的编译器CC=gcc#假设我们的源文件名为mylib.c的c语音编写的SRCS=mylib.cOBJS=$(SRCS:.c=.o)#这里的命名有一个规则,以lib开头,以.so结尾,必须这样EXEC=libmylib.sostart:$(OBJS)        #-shared表示最终链接成so共享文件        $(CC) -o $(EXEC) $(OBJS) -shared.c.o:        #-fPIC表在编译时生成和位置无关的代码        $(CC) -o $@ -c $< -fPICclean:        rm -rf $(OBJS)

当执行完make操作后,会在目录下生成一个叫libmylib.so的文件,如果要让其他项目使用这个so文件,还必须为这个so文件编写头文件,比如mylib.h

mylib.h#ifndef MYLIB_H#define MYLIB_H#ifdef __cplusplus //表示是一个c++程序extern "C"{#endifint max(int x,int y);#ifdef __cplusplus}#endif#endif

使用库函数,比如代码为main.cpp

main.cpp#include 
#include "mylib.h" //注意,这个引号里的文件名应该包括其路径,直接这样写表示其和当前main.cpp文件在同一个路径下using namespace std;int main(){ int x=max(23,54); cout<
<

为main.cpp编写makefile文件

makefile:CC=g++SRCS=main.cppOBJS=$(SRCS:.cpp=.o)EXEC=maincppstart:$(OBJS)        #-L../表示需要链接库的地址,可以是相对路径或者绝对路径,-lmylib为需要使用的库,注意这里的mylib是指libmylib.so文件,去掉前面的lib和.so后缀名后的名字        $(CC) -o $(EXEC) $(OBJS) -L../ -lmylib.cpp.o:        $(CC) -o $@ -c $

经过上述步骤后,执行make指令最后生成maincpp可执行文件。

但在执行./maincpp时提示找不到libmylib.so库文件。用 “ldd 可执行文件” 时,也显示这个自定义的so库文件找不到。

其实在上述makefile的$(CC) -o $(EXEC) $(OBJS) -L../ -lmylib部分时,只是指明了链接时的库文件路径,而没有指明运行时库文件路径。在使用库文件(so文件)时,需要指明链接时的so文件路径和运行时的so文件路径。-L表示的是链接时库文件的路径。

转自:

转载地址:http://qqykm.baihongyu.com/

你可能感兴趣的文章
python2.x之list和tunple及dict
查看>>
后缀表达式太有才了
查看>>
Atom Plugins
查看>>
1.8 字典 1.9 字典练习 2.0/2.1 流程控制-if条件判断
查看>>
软件包安装
查看>>
CentOS6下配置Tomcat7以非root用户在80端口自启动(JSVC)
查看>>
elasticsearch5.0.0中聚合和脚本的变化
查看>>
修改 Docker 中 MySQL 容器的编码
查看>>
HeadFirst设计模式篇七:模板方法模式
查看>>
给自己的区块链添加POW-工作量证明
查看>>
unix ‘’ “” 等笔记
查看>>
子域名间 的session共享
查看>>
webpack使用的一些看法
查看>>
大数据学习系列----文章汇总
查看>>
ios开发:使用sqlite存储数据
查看>>
C++ map下标访问的问题
查看>>
go filepath Abs
查看>>
透视JVM之垃圾回收
查看>>
【MySQL】replace into
查看>>
jxl 操作模板,自适应高度HssfCellStyle 自适应。
查看>>