Linux 环境下使用g++编译C++
单个源文件生成可执行程序
下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码:
/* helloworld.cpp */
#include <iostream>
int main(int argc,char *argv[])
{
std::cout << "hello, world" << std::endl;
return(0);
}
程序使用定义在头文件 iostream 中的 cout,向标准输出写入一个简单的字符串。该代码可用以下命令编译为可执行文件:
$ g++ helloworld.cpp
编译器 g++ 通过检查命令行中指定的文件的后缀名可识别其为 C++ 源代码文件。编译器默认的动作:编译源代码文件生成对象文件(object file),链接对象文件和 libstdc++ 库中的函数得到可执行程序。然后删除对象文件。由于命令行中未指定可执行程序的文件名,编译器采用默认的 a.out。程序可以这样来运行:
$ ./a.out
hello, world
更普遍的做法是通过 -o 选项指定可执行程序的文件名。下面的命令将产生名为 helloworld 的可执行文件:
$ g++ helloworld.cpp -o helloworld
在命令行中输入程序名可使之运行:
$ ./helloworld
hello, world
程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。通过遵循源码的命名规范并指定对应库的名字,用 gcc 来编译链接 C++ 程序是可行的,如下例所示:
$ gcc helloworld.cpp -lstdc++ -o helloworld
选项 -l (ell) 通过添加前缀 lib 和后缀 .a 将跟随它的名字变换为库的名字 libstdc++.a。而后它在标准库路径中查找该库。gcc 的编译过程和输出文件与 g++ 是完全相同的。
在大多数系统中,GCC 安装时会安装一名为 c++ 的程序。如果被安装,它和 g++ 是等同,如下例所示,用法也一致:
$ c++ helloworld.cpp -o helloworld
多个源文件生成可执行程序
如果多于一个的源码文件在 g++ 命令中指定,它们都将被编译并被链接成一个单一的可执行文件。下面是一个名为 speak.h 的头文件;它包含一个仅含有一个函数的类的定义:
/* speak.h */
#include <iostream>
class Speak
{
public:
void sayHello(const char *);
};
下面列出的是文件 speak.cpp 的内容:包含 sayHello() 函数的函数体:
/* speak.cpp */
#include "speak.h"
void Speak::sayHello(const char *str)
{
std::cout << "Hello " << str << "\n";
}
文件 hellospeak.cpp 内是一个使用 Speak 类的程序:
/* hellospeak.cpp */
#include "speak.h"
int main(int argc,char *argv[])
{
Speak speak;
speak.sayHello("world");
return(0);
}
下面这条命令将上述两个源码文件编译链接成一个单一的可执行程序:
$ g++ hellospeak.cpp speak.cpp -o hellospeak
PS:这里说一下为什么在命令中没有提到“speak.h“该文件(原因是:在“speak.cpp“中包含有”#include”speak.h”“这句代码,它的意思是搜索系统头文件目录之前将先在当前目录中搜索文件“speak.h“。而”speak.h“正在该目录中,不用再在命令中指定了)。
源文件生成对象文件
选项 -c 用来告诉编译器编译源代码但不要执行链接,输出结果为对象文件。文件默认名与源码文件名相同,只是将其后缀变为 .o。例如,下面的命令将编译源码文件 hellospeak.cpp 并生成对象文件 hellospeak.o:
$ g++ -c hellospeak.cpp
命令 g++ 也能识别 .o 文件并将其作为输入文件传递给链接器。下列命令将编译源码文件为对象文件并将其链接成单一的可执行程序:
g++−chellospeak.cppg++−chellospeak.cpp g++ -c speak.cpp
$ g++ hellospeak.o speak.o -o hellospeak
选项 -o 不仅仅能用来命名可执行文件。它也用来命名编译器输出的其他文件。例如:除了中间的对象文件有不同的名字外,下列命令生将生成和上面完全相同的可执行文件:
$ g++ -c hellospeak.cpp -o hspk1.o
$ g++ -c speak.cpp -o hspk2.o
$ g++ hspk1.o hspk2.o -o hellospeak
编译预处理
选项 -E 使 g++ 将源代码用编译预处理器处理后不再执行其他动作。下面的命令预处理源码文件 helloworld.cpp 并将结果显示在标准输出中:
$ g++ -E helloworld.cpp
本文前面所列出的 helloworld.cpp 的源代码,仅仅有六行,而且该程序除了显示一行文字外什么都不做,但是,预处理后的版本将超过 1200 行。这主要是因为头文件 iostream 被包含进来,而且它又包含了其他的头文件,除此之外,还有若干个处理输入和输出的类的定义。
预处理过的文件的 GCC 后缀为 .ii,它可以通过 -o 选项来生成,例如:
$ gcc -E helloworld.cpp -o helloworld.ii
生成汇编代码
选项 -S 指示编译器将程序编译成汇编语言,输出汇编语言代码而後结束。下面的命令将由 C++ 源码文件生成汇编语言文件 helloworld.s:
$ g++ -S helloworld.cpp
1
生成的汇编语言依赖于编译器的目标平台。
创建静态库
静态库是编译器生成的一系列对象文件的集合。链接一个程序时用库中的对象文件还是目录中的对象文件都是一样的。库中的成员包括普通函数,类定义,类的对象实例等等。静态库的另一个名字叫归档文件(archive),管理这种归档文件的工具叫 ar 。
在下面的例子中,我们先创建两个对象模块,然后用其生成静态库。
头文件 say.h 包含函数 sayHello() 的原型和类 Say 的定义:
/* say.h */
#include <iostream>
void sayhello(void);
class Say {
private:
char *string;
public:
Say(char *str)
{
string = str;
}
void sayThis(const char *str)
{
std::cout << str << " from a static library\n";
}
void sayString(void);
};
下面是文件 say.cpp 是我们要加入到静态库中的两个对象文件之一的源码。它包含 Say 类中 sayString() 函数的定义体;类 Say 的一个实例 librarysay 的声明也包含在内:
/* say.cpp */
#include "say.h"
void Say::sayString()
{
std::cout << string << "\n";
}
Say librarysay("Library instance of Say");
源码文件 sayhello.cpp 是我们要加入到静态库中的第二个对象文件的源码。它包含函数 sayhello() 的定义:
/* sayhello.cpp */
#include "say.h"
void sayhello()
{
std::cout << "hello from a static library\n";
}
下面的命令序列将源码文件编译成对象文件,命令 ar 将其存进库中:
$ g++ -c sayhello.cpp
$ g++ -c say.cpp
$ ar -r libsay.a sayhello.o say.o
程序 ar 配合参数 -r 创建一个新库 libsay.a 并将命令行中列出的对象文件插入。采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。
下面是主程序 saymain.cpp,它调用库 libsay.a 中的代码:
/* saymain.cpp */
#include "say.h"
int main(int argc,char *argv[])
{
extern Say librarysay;
Say localsay = Say("Local instance of Say");
sayhello();
librarysay.sayThis("howdy");
librarysay.sayString();
localsay.sayString();
return(0);
}
该程序可以下面的命令来编译和链接:
$ g++ saymain.cpp libsay.a -o saymain
程序运行时,产生以下输出:
hello from a static library
howdy from a static library
Library instance of Say
Local instance of Say
本文来自:http://wiki.ubuntu.org.cn/Compiling_Cpp
ps:如果一个文件夹下有多个cpp文件需要编译的话,除了采用makefile的方式之外,还可以使用“g++ *.cpp -o hello”,“hello为编译生成的可执行文件的名字”,编译时要确保cpp文件和他们各自所引用的头文件在同一个目录下。
Linux 环境下使用g++编译C++的更多相关文章
- Linux环境下使用VSCode编译makefile文件的注意事项
Linux环境下使用VSCode编译makefile文件的注意事项 首先安装C/C++的两个依赖 在debug,launch会自动的生成下方的launch.json launch.json { // ...
- Linux环境下使用gcc编译,gdb反汇编C语言程序
使用虚拟机 VMware Workstation 10 Linux环境:Ubuntu 14.04 LTS Server amd64 我把过程截图如下. 首先是hello world程序: 备注: ...
- Linux环境下的Nginx编译与安装
1.新建文件夹: mkdir -p /zuker cd /zuker 2.编译: yum -y install gcc-c++ make wget autoconf libjpeg libjpeg-d ...
- 编写第一个Linux环境下程序的编译,下载记录
跟着韦东山学习Linux: 今天系统系统性的学了代码的编译下载,条记录一下: 一,代码:001_led_on.S,就把下面代码编译后Bin文件下载进2440处理器. /* * 点亮LED1: gpf4 ...
- 多线程编程之Linux环境下的多线程(一)
一.Linux环境下的线程 相对于其他操作系统,Linux系统内核只提供了轻量级进程的支持,并未实现线程模型.Linux是一种“多进程单线程”的操作系统,Linux本身只有进程的概念,而其所谓的“线程 ...
- Linux 环境下 C++ 的开发编译
Linux环境下C++程序的开发编译学习笔记 环境:vmware 运行下的Ubuntu 16.04 姓名:谢津 时间:2018/5/24 内容:1)vim的安装及配置:2)第一个C++程序的编写与编译 ...
- linux环境下安装git(采用github下载git源码编译)
[目的]:linux环境下 安装配置git成功 [准备条件]linux系统,git包 1.先行下载git包 -- 从github上https://github.com/git/git/releases ...
- PCL库在Linux环境下的编译安装
PCL库在Linux环境下的编译安装 PCL库的源码库:https://github.com/PointCloudLibrary/pcl 下载完了之后解压下来 编译库的几个步骤 mkdir build ...
- Linux环境下段错误的产生原因及调试方法小结(转)
最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且 项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation F ...
随机推荐
- 《Spring_Four》第三次作业——基于Jsoup的大学生考试信息展示系统的原型设计与开发
<Spring_Four团队>第三次团队项目——基于Jsoup的大学生考试信息展示系统的原型设计与开发 一.实验目的与要求 (1)掌握软件原型开发技术: (2)学习使用软件原型开发工具:本 ...
- 详细分析MySQL事务日志(redo log和undo log) 表明了为何mysql不会丢数据
innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过程,其实它 ...
- python 网络编程 tcp和udp 协议
1. 网络通信协议 osi七层,tcp\ip五层 tcp\ip五层 arp协议:通过IP地址找到mac地址 2.tcp和udp的区别 tcp协议:面向连接,消息可靠,相对udp来讲,传输速度慢,消息是 ...
- 169. Majority Element (Array)
Given an array of size n, find the majority element. The majority element is the element that appear ...
- Python练习-迭代-2018.11.28
#遍历list L=['a','b','c','d'] l=[] a=0 for n in L: l.insert(a,n) a=a+1 print(l) #遍历dict里的key,导出为list L ...
- 450. Delete Node in a BST 删除bst中的一个节点
[抄题]: Given a root node reference of a BST and a key, delete the node with the given key in the BST. ...
- 未渲染的dom结构,绑定事件,jquery
使用事件委托 $(document).on('click','selector',function(){ ... }); 示例 $(document).on("click", &q ...
- Django实现微信消息推送
一 所需准备条件 微信公众号的分类 微信消息推送 公众号 已认证公众号 服务号 已认证服务号 企业号 基于:微信认证服务号 主动推送微信消息.前提:关注服务号环境:沙箱环境 沙箱环境地址: https ...
- adb、monkey常用命令
adb.monkey常用命令 1.查看连接设备 adb devices 2.连接android模拟器 adb connect 127.0.0.1:62001 3.安装软件 adb install 这个 ...
- Idea+maven+testNG+Selenium+ReportNG自动化框架搭建
1.Idea创建一个空的Maven项目 创建后默认项目目录如图所示 2.配置pom.xml文件 <?xml version="1.0" encoding="UTF- ...