linux下使用g++编译cpp工程的方法

C++编程中相关文件后缀

linux下使用g++编译cpp工程的方法

1.单个源文件生成可执行程序

下面是一个保存在文件 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

2.多个源文件生成可执行程序

如果多于一个的源码文件在 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“正在该目录中,不用再在命令中指定了)。

3.源文件生成对象文件

选项 -c 用来告诉编译器编译源代码但不要执行链接,输出结果为对象文件。文件默认名与源码文件名相同,只是将其后缀变为 .o。例如,下面的命令将编译源码文件 hellospeak.cpp 并生成对象文件 hellospeak.o:

$ g++ -c hellospeak.cpp

命令 g++ 也能识别 .o 文件并将其作为输入文件传递给链接器。下列命令将编译源码文件为对象文件并将其链接成单一的可执行程序:

$ g++ -c hellospeak.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

4.编译预处理

选项 -E 使 g++ 将源代码用编译预处理器处理后不再执行其他动作。下面的命令预处理源码文件 helloworld.cpp 并将结果显示在标准输出中:

$ g++ -E helloworld.cpp

本文前面所列出的 helloworld.cpp 的源代码,仅仅有六行,而且该程序除了显示一行文字外什么都不做,但是,预处理后的版本将超过 1200 行。这主要是因为头文件 iostream 被包含进来,而且它又包含了其他的头文件,除此之外,还有若干个处理输入和输出的类的定义。

预处理过的文件的 GCC 后缀为 .ii,它可以通过 -o 选项来生成,例如:

$ gcc -E helloworld.cpp -o helloworld.ii

5.生成汇编代码

选项 -S 指示编译器将程序编译成汇编语言,输出汇编语言代码而後结束。下面的命令将由 C++ 源码文件生成汇编语言文件 helloworld.s:

$ g++ -S helloworld.cpp

生成的汇编语言依赖于编译器的目标平台。

6.创建静态库

静态库是编译器生成的一系列对象文件的集合。链接一个程序时用库中的对象文件还是目录中的对象文件都是一样的。库中的成员包括普通函数,类定义,类的对象实例等等。静态库的另一个名字叫归档文件(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

总结

到此这篇关于linux下使用g++编译cpp工程的文章就介绍到这了,更多相关linux g++编译cpp内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2020-03-26

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,向标准输出写入一个简单的

linux 下 g++编译程序时-I(大写i) 与-L(大写l)-l(小写l) 的作用详解

作为一个linux入门级使用者,gcc/g++ 的简单操作已经用过多次, 但是有时稍微复杂一点的程序就会使用到库.在遇到问题的时候我查了挺多前辈总结的资料,也留个脚本希望对朋友们有个帮助.如果也能处理你的问题,我会感到很开心,嘻嘻. 例如:libz.so g++ -o compress  compress.cpp  -I/home/include/  -L/lib/  -lz (1) -I (大写i) 编译程序按照-I指定的路进去搜索头文件. -I/home/include/表示将-I/home

详解 linux c++的编译器g++的基本使用

linux c++的编译器g++基本使用 g++是 linux下c++的编译器,在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件 2.将预处理后的文件不转换成汇编语言,生成文件.s 3.有汇编变为目标代码(机器代码)生成.o的文件 4.连接目标代码,生成可执行程序 g++ 编译c++经常使用的参数: -c 只编译,不连接.例如: g++ -c helloworld.cpp 只生成helloworld.o不连接 -o 指定输出文件名.例如:g++ -c helloworld.cpp

Linux环境g++编译GDAL动态库操作方法

一.编译步骤 解压下载的GDAL源程序,并在命令行中切换到解压目录. tar -xzvf gdal-2.1.3.tar.gz cd gdal-2.1.3 GDAL可通过configure来实现一些自定义配置,可通过./configure –h命令来查看.--prefix=path表示设置GDAL的make install后的build目录,里面有生成的头文件和动态库.输入如下命令: ./configure --prefix=/root/Test/gdalbuild 这时可以发现目录中新生成了GD

Linux下g++编译与使用静态库和动态库的方法

在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库(*.a)与动态库(*.so)的生成与使用方式是不同的.刚开始可能会不适应,但是用多了应该会习惯这种使用,因为步骤上并没有VS下配置那么繁琐. 下面就分别总结下linux下生成并使用静态库与动态库的方法:(由于是C++项目,所以编译器用的g++,但是与gcc的使用是相通的) 首先是准备工作,把我们需

Linux静态库与动态库实例详解

Linux静态库与动态库实例详解 1. Linux 下静态链接库编译与使用 首先编写如下代码: // main.c #include "test.h" int main(){ test(); return 0; } // test.h #include<iostream> using namespace std; void test(); // test.c #include "test.h" void test(){ cout<< &quo

深入探讨Linux静态库与动态库的详解(一看就懂)

库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 一.静态库和动态库的区别1. 静态函数库这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大--空间,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了.当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译.2. 动态函数库这类库的名字一般是libxxx.so;相对于静态

xcode 详解创建静态库和动态库的方法

xcode 创建静态库和动态库 1.linux中静态库和动态库区别: 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行.库分静态库和动态库两种. 静态库:这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大,因为整个函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了.当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译. 动态库:这类库的名字一般是lib

LINUX下PHP程序实现WORD文件转化为PDF文件的方法

本文实例讲述了LINUX下PHP程序实现WORD文件转化为PDF文件的方法.分享给大家供大家参考,具体如下: <?php set_time_limit(0); function MakePropertyValue($name,$value,$osm){ $oStruct = $osm->Bridge_GetStruct("com.sun.star.beans.PropertyValue"); $oStruct->Name = $name; $oStruct->V

linux下查看内存条数及每根内存大小的实现方法(推荐)

在linux系统中,查看内存条个数,及每根内存的大小,可以使用dmidecode命令. 如下: #dmidecode | grep -A16 "Memory Device$" 输出结果: Memory Device #存储设备 Array Handle: 0x1000 #阵列处理 Error Information Handle: Not Provided #错误信息的处理:不提供 Total Width: 72 bits #总宽度: 72位 Data Width: 64 bits #

Linux下手动编译安装PHP扩展的例子分享

开发和部署的过程中可能会经常出现需要额外安装PHP扩展的情况,下边以PDO_MYSQL为例,介绍下手动编译安装PHP扩展: 先到http://pecl.php.net/找需要的版本,我用的是稳定的版本.要先看看说明,特别是要注意mysql的php的版本. 复制代码 代码如下: wget http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz tar xzvf PDO_MYSQL-1.0.2.tgz cd PDO_MYSQL-1.0.2 /usr/local/php

Java版C语言版简单使用静态语言实现动态数组的方法

动态语言相对于静态语言的一个优势,就是数组可以不需要预先确定大小,对于一些数组长度不确定的场景下是非常有用的.像PHP,只需要声明一下数组 $arr = array() 然后就可以直接 $arr[] = 1,$arr[] = 2,$arr[] = 3...这样一直加元素了,删除一个元素就直接使用unset($arr[1]),元素的空间就被释放了,而C和JAVA原生的数组就没有这么方便,声明的时候就必须先预先确定长度,由编译器分配相应的内存空间.不过通过一些巧妙的做法,也是可以实现一样的功能的,这

Linux下nginx编译安装教程和编译参数详解

一.必要软件准备1.安装pcre 为了支持rewrite功能,我们需要安装pcre 复制代码 代码如下: # yum install pcre* //如过你已经装了,请跳过这一步 2.安装openssl 需要ssl的支持,如果不需要ssl支持,请跳过这一步 复制代码 代码如下: # yum install openssl* 3.gzip 类库安装 复制代码 代码如下: yum install zlib zlib-devel 4.安装wget 下载nginx使用,如果已经安装,跳过这一步 复制代码