目录
一、编译简单C++工程demo
本文编写的工程如下:
Myclass的头文件.h/
#pragma once
#include <iostream>
using namespace std;
class Myclass {
public:
Myclass();
~Myclass();
void MyPrint();
};
//
///Myclass的源文件cpp///
#include "Myclass.h"
Myclass::Myclass()
{
}
Myclass::~Myclass()
{
}
void Myclass::MyPrint()
{
std::cout << "hello This is sub print" << endl;
}
//
///数据管理文件DataMange.h
#pragma once
#include <iostream>
using namespace std;
class DataMange {
public:
DataMange();
~DataMange();
void DataMangePrint();
};
///
///数据管理文件DataMange.cpp
#include "DataMange.h"
DataMange::DataMange()
{
}
DataMange::~DataMange()
{
}
void DataMange::DataMangePrint()
{
std::cout << endl;
std::cout << "hello This is sub2 print" << endl;
for (int i=0; i < 5;i++)
{
std::cout << "DataMangePrint " << i << std::endl;
}
}
///
///工程文件入口test1.cpp
#include <iostream>
#include "Myclass.h"
int main()
{
std::cout << "hello word" << std::endl;
Myclass obj;
obj.MyPrint();
return 0;
}
将上述代码拷贝到linux系统下,linux下的目录结构体如下:
上面的DataManage文件夹下面有DataMange.h和DataMange.cpp
编译有分步编译和直接编译。
1、分步编译
(1)生成.o文件,执行指令如下:
/Public/test1$ g++ -c ./Myclass.cpp ./DataManage/DataMange.cpp ./test1.cpp -I ./ -I ./DataManage/
生成的文件如下:
(2)生成可执行目标文件.out
指令如下:
g++ ./Myclass.o ./DataMange.o ./test1.o -I ./ -I ./DataMange/ -o main
生成的文件如下:
(3)直接运行目标文件,输入命令:./main
结果如下:
2、直接生成目标文件
(1)直接生成目标执行文件.out,输入如下命令:
g++ ./Myclass.cpp ./DataManage/DataMange.cpp ./test1.cpp -I ./ -I ./DataManage/ -o main
(2)直接运行目标文件。
二、编译库
1、编译静态库.a
编译DataManage文件下的类函数为静态库.a
(1)生成.o文件
输入命令:g++ -c ./DataManage/DataMange.cpp -I ./DataManage/
(2)生成libDataMange.a文件
输入命令:ar crv libDataMange.a DataMange.o
(3)运用.a文件
链接静态库.a生成可执行文件main,
g++ -o main Myclass.cpp test1.cpp -L ./ libDataMange.a
或者输入命令:
g++ Myclass.cpp test1.cpp -L ./ libDataMange.a -o main
上述的执行过程的如下:
2、编译动态库
(1)生成DataManage的动态库.so
输入命令:g++ -fPIC -shared -o libData.so ./DataManage/DataMange.cpp -I ./DataManage/
(2)使用动态库,生成可执行文件
输入命令:g++ -o main Myclass.cpp -I. test1.cpp -L. ./libData.so
或者输入命令:g++ -o main Myclass.cpp -I. test1.cpp ./libData.so
(3)查看动态库是否正确链接到库,输入命令:ldd main
(4)运行,输入命令:./main
上述的执行过程如下:
三、g++编译命令简述
1、编译过程
g++是GNU的c++编译器,在执行编译代码时,对应4个编译过程:
(1)预处理(完成代码中的宏替换,查找相关库文件)生存.i文件,对应编译参数-E。
eg: g++ -E main.cpp
(2)编译(将预处理后文件转换成汇编语言).s文件,对应编译参数-S。
eg:g++ -S main.cpp //直接生成.s汇编文件
eg:g++ -S main.i //将预处理产生的i文件编译生成.s文件
(3)汇编(将汇编语言文件转换成目标代码,即机器代码).o文件,对应编译参数-c
eg:g++ -c main.cpp
(4)链接(链接目标代码或静态库、动态库等[连接器ld])生成可执行程序,对应编译参数-o
eg:g++ main.o -o main
2、编译参数
(1) -I ./ 指的是头文件地址
(2)-L / 指的是库文件地址
关于g++编译时的地址符号可参考:linux 下 g++编译程序时,-I(大写i) 与-L(大写l)-l(小写l) 的作用_lin_008的博客-CSDN博客_linux 动态编译-l的作用
(3)生成带有调试信息的文件
eg:g++ -g main.cpp -o main //直接生成输出文件,-g1,-g2,-g3,g3生成的文件调试信息最多, //默认g2
关于g++的编译参数可参考Linux下,g++的常用编译参数,调试信息,优化,指定库,头文件目录,库目录,警告信息处理,编译标准,输出名称,宏,多文件的编译_优秀的邓宗磊的博客-CSDN博客_g++ 编译指定头文件
编译参数也可参考:
g++编译过程和动态链接库_weixin_34080903的博客-CSDN博客
(4) 打印所有警告
参数: -Wall ,允许发出GCC能够提供的所有有用的警告
demo程序如下:
#include <iostream>
using namespace std;
int nGlobal = 0;
int Recursive(int n1)
{
if (n1 == 1)
{
return 1;
}
int tmp = n1;
return Recursive(n1-1)*n1;
}
class A
{
public:
A(int var1,int var2):b(var1),a(var2){};
int a;
int b;
};//成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关
int main()
{
Recursive(6);
return 0;
}
(5)将所有警告当作编译错误
参数:-Werror, 把所有警告转换为错误,以在警告发生时中止编译过程,注意需要先设置 -Wall。
附加知识:
编译过程详细介绍可参考:
10分钟搞懂g++编译过程_至绽至强的博客-CSDN博客_g++编译
编译静态库和动态库也可参考上面的链接。
编译参考可参考:
GCC/G++详细使用手册_编译(告警、优化、调试选项)_gc++_mw_nice的博客-CSDN博客
类成员初始化顺序问题参考: