编译方法(gcc,Makefile,CMake)


前言

编译分四步
预处理:将不同文件中的源程序聚合到一起,并进行宏替换
编译:将高级语言(X=2)翻译成汇编语言或机器语言的过程
汇编:将汇编语言(MOV X,2)翻译成机器语言的过程
链接:将多个可重定位(内存的起始地址不固定)的机器代码文件链接到一起,解决外部内存地址问题


gcc

# gcc -E test.c -o test.i
-E 让编译器只对输入文件进行预处理

# gcc -S test.i -o test.s
-S 产生汇编语言文件,扩展名是.s

# gcc -c test.s -o test.o
-c 将汇编语言转化为机器语言

# gcc test.o -o test
-o 为产生的可执行文件指定文件名,若不加-o 则默认文件名为a.out

简单点一步到位
# gcc -c test.c -o test
直接生成一个test可执行程序
通过./test调用该程序

处理多源文件目录

(以下的树结构是通过tree命令实现的)
在这里插入图片描述
先给代码,可以自己动手试试

main.cc

#include <iostream>
#include "swap.h"
using namespace std;
int main()
{
        int a=1,b=10;
        cout<<"交换前"<<"a = "<<a<<" "<<"b = "<<b<<endl;
        swap(a,b);
        cout<<"交换后"<<"a = "<<a<<" "<<"b = "<<b<<endl;
        return 0;
}

swap.cc

#include "swap.h"
void swap(int &a,int &b)
{
        int tmp=a;
        a=b;
        b=tmp;
}

swap.h

#ifndef SWAP_H__
#define SWAP_H__
void swap(int&,int&);
#endif

命令行输入

I后面的参数是目录,因为源代码中我使用的是#include"swap.h"
需要指定目录才能让编译器找到头文件
# g++ main.cc src/swap.cc -Iinclude -o main

-I指定头文件路径。编译得到一个名字为main的可执行程序,输入./main运行结果如下。
在这里插入图片描述

生成静(动)态库文件进行编译

库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。unix系统的静态库文件和动态库文件后缀分别是.a和.so;windows静态库文件就是.lib文件,动态库文件就是.dll文件。
两种库的区别在于静态库被调用时直接加载到内存,而动态库再是在需要的时候加载到内存,不使用的时候再从内存释放。

静态库
(以下案例参照第一幅树状图)

//静态库在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中
# cd Test/src

//第一步生成.o汇编文件,
# g++ -c swap.cc -I../include

//第二步生成静态库libswap.a,静态库的命名 libxxx.a
# ar rs libswap.a swap.o

//回到Test目录
# cd ..

//第三步链接生成可执行文件
#-l 指定链接时需要的库,刚刚生成的libswap.a,swap是库名
#-L 链接src目录下的库文件
#-I 链接include目录下的头文件
# g++ main.cc -lswap -Lsrc -Iinclude -o static_main

生成静态库文件后能够直接运行

动态库

# cd Test/src
//第一步生成.o文件
#-fpic 创建与地址无关的编译程序(加上就完事了)
# g++ -c swap.cc -fpic -I../include

//第二步生成动库文件libswap.so
#-shared 表示生成的是动态库
# g++ -shared -o libswap.so swap.o

# cd ..

//第三步链接生成可执行文件
# g++ main.cc -lswap -Lsrc -Iinclude -o dynamic_main

最后命令行输入来运行,指定库文件搜索路径
# LD_LIBRARY_PATH=src ./dynamic_main

Makefile

直接看陈皓写的把,我写的不好
https://blog.csdn.net/haoel/article/details/2886

CMake

基本语法

项目构建工具cmake是makefile的上层工具,目的是为了产生可移植的makefile,并简化自己动手写makefile时的巨大工作量。
和makefile类似,要创建一个CMakeLists.txt

#基本语法:指令(参数 参数;参数)
#参数之间是空格或分号
#指令用大小写都行

#cmake最低版本需求,不加入此行会受到警告信息
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

#添加编译参数
ADD_COMPILE_OPTIONS(-phread -wall)

ADD_SUBDIRECTORY(src)#指明本项目包含一个子目录src

#生成库文件
#${SRC},这个命令的是对SRC这个变量取值
ADD_LIBRARY ( Test ${SRC})

#把当前目录(.)下所有源代码文件和头文件加入变量SRC_LIST
AUX_SOURCE_DIRECTORY(. SRC_LIST)

#编译SRC_LIST变量代表的所有源文件生成可执行程序 main
ADD_EXECUTABLE(main ${SRC_LIST})

#添加头文件搜索路径,相当于于指定g++编译器的参数-I
#dir是路径(绝对路径和相对路径都可)
INCLUDE_DIRECTORIES(dir);

#添加库文件的搜索路径,相当于g++的参数-L
LINK_DIRECTORIES(dir)

#指定项目名称
PROJECT(HELLO) 

#定义src变量,值为hello1.c、hello2.c
SET(src hello1.c hello2.c)

#指明可执行文件 main需要连接一个名为Test的链接库
#类似g++ -l参数
TARGET_LINK_LIBRARIES( main Test )

编译流程

1、编写CMakeLists.txt
2、执行命令cmake生成一个makefile文件
3、执行命令make

两种构建方式

在正式开始写CMakeLists.txt之前,介绍一下两种构建方式
1、内部构建
cmake在当前目录会产生其他文件,而且这些文件我们不需要,就显得很杂乱,所以不推荐使用

2、外部构建(一般使用这个)
这个是通过mkdir 一个 build 目录,(名字自拟,常使用的是build),与内部构建不同的是,外部构建会把生成的文件都放在build目录下,所以推荐使用这个。

实例编译

单目录源文件内部构建编译

在这里插入图片描述
三步走战略:
第一步:编写CMakeLists.txt
如果用g++来编译:g++ HelloWorld.cc -o HelloWorld

#必须的这一步 设置可接受的最低版本号
#版本号的可以通过cmake --version命令查看
cmake_minimum_required(VERSION 3.0)

#设置项目名称
project(HELLOWORLD)
#项目名称应该要和add_executable的第一个参数名相同,大小写无所谓

#g++ HelloWorld.cc -o HelloWorld
add_executable(HelloWorld HelloWorld.cc)

第二步:执行cmake .
注意这个cmake后的点,表示CMakeLists.txt是在当前目录下
在这里插入图片描述
现在我们得到了一个我们需要的Makefile文件和其他我们不需要的东西,所以采用外部构建的方式是非常有必要的。

第三步
执行make
在这里插入图片描述
bingo,已经成功生成了一个HelloWorld可执行程序了。

多目录源文件外部构建编译

在这里插入图片描述
第一步:写CMakeLists.txt
如果用g++来编译:g++ main.cc src/swap.cc -Iinclude -o main

cmake_minimum_required(VERSION 3.0)

project(SWAP)

#g++ -Iinclude
//#include_directories(include),下面是绝对路径,这是相对路径,都是可以的
include_directories(${CMAKE_SOURCE_DIR}/include)

#g++ main.cc src/swap.cc -o main
add_executable(swap main.cc src/swap.cc)

第二步:cmake
mkdir build,在build目录下执行cmake(后面两个.),因为CMakeLists.txt在上一级目录。
在这里插入图片描述
第三步:make
在这里插入图片描述
基本的Cmake使用方法就介绍到这,可能以后会补充。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值