linux环境下编译C++ 程序
GCC(GNU Compiler Collection)是Linux下最主要的编译工具,GCC不仅功能非常强大,结构也异常灵活。它可以通过不同的前端模块来支持各种语言,如:Java、Fortran、Pascal、Modula-3和Ada。
安装Gcc和g++:
yum -y install gcc automake autoconf libtool make
安装g++:
yum install gcc gcc-c++
g++是GCC中的一个工具,专门来编译C++语言的。
GCC的参数有:( 也是分步实现)
-E
让GCC在预处理结束后停止编译。g++ -E hello.cpp -o hello.i
Shell-c
将hello.i
编译成目标代码g++ -c hello.i -o hello.o
Shell将目标文件连接成可执行文件
g++ hell.o -o hello
Shell可以一步实现
g++ hello.cpp -o hello
Shell
假如有两个以上源文件应该一下编译
一步就实现:
g++ foo1.cpp foo2.cpp -o foo
也可以分步实现:
g++ -c foo1.cpp -o foo1.o
g++ -c foo2.cpp -o foo2.o
g++ foo1.o foo2.o -o foo
GCC一些常用选项
1、产生警告信息的选项大多数以-W
开头 其中有-Wall
g++ -Wall hello.cpp -o hello
2、将所有的警告当成错误的选项-Werror
g++ -Werror hello.cpp -o hello
3、寻找头文件选项
-I
(linux默认路径:头文件在/usr/include/
下),不在这个路径下就要用-I
指定。gcc foo.cpp -I/home/include -o foo
Shell4、 库依赖选项
-L
(linux默认路径:库文件在/usr/lib/
下),不在这个路径下就要用-L
指定。g++ foo.cpp -L/home/lib -lfoo -o foo
Shell
库就是将源文件编译之后生成的目标文件的集合。库命名以lib开头。库有静态库(通常以.a
结尾)和动态库(通常以.so
结尾)默认情况下,g++以动态库形式连接。如果要静态库连接则要用-static
指定(g++ foo.cpp -L/home/lib -static -lfoo -o foo
)
单个源文件生成可执行程序
下面是一个保存在文件 helloworld.cpp
中一个简单的 C++ 程序的代码: 单个源文件生成可执行程序。
/* helloworld.cpp */
#include <iostream>
int main(int argc,char *argv[])
{
std::cout << "hello, world" << std::endl;
return(0);
}
程序使用定义在头文件 iostream
中的 cout
,向标准输出写入一个简单的字符串。该代码可用以下命令编译为可执行文件:
[root@localhost cpp]# g++ helloworld.cpp
[root@localhost cpp]# ll
total 16
-rwxr-xr-x. 1 root root 9136 Mar 8 03:31 a.out
-rw-rw-r--. 1 yiibai yiibai 138 Mar 8 03:24 helloworld.cpp
[root@localhost cpp]#
编译器 g++ 通过检查命令行中指定的文件的后缀名可识别其为 C++ 源代码文件。
编译器默认的动作: 编译源代码文件生成对象文件(object file),链接对象文件和 libstd c++ 库中的函数得到可执行程序。然后删除对象文件。由于命令行中未指定可执行程序的文件名,编译器采用默认的a.out
。程序可以这样来运行:
[yiibai@localhost cpp]$ ./a.out
hello, world
[yiibai@localhost cpp]$
更普遍的做法是通过 -o
选项指定可执行程序的文件名。下面的命令将产生名为 helloworld
的可执行文件:
[yiibai@localhost cpp]$ g++ helloworld.cpp -o helloworld
[yiibai@localhost cpp]$ ll
total 28
-rwxr-xr-x. 1 root root 9136 Mar 8 03:31 a.out
-rwxrwxr-x. 1 yiibai yiibai 9136 Mar 8 03:32 helloworld
-rw-rw-r--. 1 yiibai yiibai 138 Mar 8 03:24 helloworld.cpp
[yiibai@localhost cpp]$
在命令行中输入程序名可使之运行:
[yiibai@localhost cpp]$ ./helloworld
hello, world
[yiibai@localhost cpp]$
程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。通过遵循源码的命名规范并指定对应库的名字,用 gcc 来编译链接 C++ 程序是可行的,如下例所示:
[yiibai@localhost cpp]$ gcc helloworld.cpp -lstdc++ -o helloworld
选项 -l (ell)通过添加前缀 lib 和后缀 .a
将跟随它的名字变换为库的名字libstdc++.a
。而后它在标准库路径中查找该库。gcc 的编译过程和输出文件与 g++ 是完全相同的。
在大多数系统中,GCC 安装时会安装一名为 c++ 的程序。如果被安装,它和 g++ 是等同,如下例所示,用法也一致:
[yiibai@localhost cpp]$ 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
提示: 这里说一下为什么在命令中没有提到“
speak.h
“文件(原因是:在“speak.cpp
“中包含有”#include"speak.h
““这句代码,它的意思是搜索系统头文件目录之前将先在当前目录中搜索文件“speak.h
“。而”speak.h
“正在该目录中,不用再在命令中指定了)。
源文件生成对象文件
选项 -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
编译预处理
选项 -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
生成的汇编语言依赖于编译器的目标平台。
创建静态库
静态库是编译器生成的一系列对象文件的集合。链接一个程序时用库中的对象文件还是目录中的对象文件都是一样的。库中的成员包括普通函数,类定义,类的对象实例等等。静态库的另一个名字叫归档文件(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");
源码文件 syshello.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 SayLocal instance of Say
linux环境下编译C++ 程序的更多相关文章
- Ubantu Linux 环境下编译c++程序
先在文件中新建一个a.cpp文件,在里面编写程序, 然后打开终端输入下面命令即可; $ g++ a.cpp -o b ///编译a.cpp 然后把编译之后的.exe文件存入b中 $ ./b ///执行 ...
- 在linux环境下编译C++ 程序
单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: 单个源文件生成可执行程序 /* helloworld.cpp */ #include ...
- Linux环境下编译并执行ava helloworld程序
原文:http://blog.lupaworld.com/home-space-uid-24466-do-blog-id-2578.html 已经学会怎样在Windows下怎样编辑,编译和运行Java ...
- 在虚拟机linux环境下编译windows版adb fastboot
原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html 我根据虚拟机编译遇到的问题进行一些添加 [前提条件] Linux Android ...
- 如何在VS2010环境下编译C++程序
原文:http://blog.csdn.net/gupengnina/article/details/7441203 用 Visual Studio 编写 Visual C++ 程序的第一步是选择项目 ...
- Linux环境下Android JNI程序的编译
尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8993493 在android开发中,有时候需要编写一些C/C++代码,这时候 ...
- 在linux环境下编译运行OpenCV程序的两种方法
原来以为在Ubuntu下安装好了OpenCV之后,自己写个简单的程序应该很容易吧,但是呢,就是为了编译一个简单的显示图片的程序我都快被弄崩溃了. 在谷歌和上StackOverFlow查看相关问题解答之 ...
- [学习笔记]Linux环境下部署 .Net5 程序
公司的项目需要部署到一台公网的linux服务器,以便同事们测试小程序. 目标服务器是新搭建的CentOS 8虚拟机,以非docker的方式部署.现记录过程便于日后部署至项目甲方的服务器上,因为甲方的 ...
- Linux环境下编译JDK
环境准备 操作系统,ubuntu-14.04.6-desktop-amd64.iso,下载地址:http://59.80.44.100/releases.ubuntu.com/14.04/ubuntu ...
随机推荐
- C++中的“error:LNK2005 已经在*.obj中定义”异常问题
C++中的“error:LNK2005 已经在*.obj中定义”异常问题 异常现象如下:
- TFS 如何強制撤銷被簽出的文件
我们在使用TFS (Team Foundation Server) 源代码管理的时候,源代码管理会在每个PC上创建一个工作区,然后这个工作区域映像到服务器上的源码文件夹,我们在正常签入,签出的时候,我 ...
- SQL server经验分享:SQLSERVER 被标记为“可疑”的数据库处理方法
--MyDB为修复的数据名USE MASTER GO SP_CONFIGURE 'ALLOW UPDATES',1 RECONFIGURE WITH OVERRIDE GO ALTER DATABAS ...
- linux系统编程之文件与IO(二):系统调用read和write
read系统调用 一旦有了与一个打开文件描述相连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节 函数原型: #include &l ...
- C#文件监控对象FileSystemWatcher实例,通过监控文件创建、修改、删除、重命名对服务器数据进行实时备份
先上图,简单的windorm界面:此为最初的版本,后续会增加监听多个源目录的功能.log功能.进度条展示功能等. 1.初始化监听 /// <summary> /// 初始化监听 /// & ...
- 基于C#语言MVC框架Aspose.Cells控件导出Excel表数据
控件bin文件下载地址:https://download.csdn.net/download/u012949335/10610726 @{ ViewBag.Title = "xx" ...
- C#多线程编程系列(五)- 使用任务并行库
目录 1.1 简介 1.2 创建任务 1.3 使用任务执行基本的操作 1.4 组合任务 1.5 将APM模式转换为任务 1.6 将EAP模式转换为任务 1.7 实现取消选项 1.8 处理任务中的异常 ...
- From Alpha to Gamma (I)
What we think of as conventional alpha-blending is basically wrong. --Tom Forsyth 前段时间在Amazon上淘的三本二手 ...
- python 返回数组的索引
使用python里的index nums = [1, 2, 3, 4, 5, 6, 1, 9] print nums.index(max(nums)) print nums.index(1) 该方法同 ...
- C++实现文件自校验的一种方法
#include <iostream> #include <stdio.h> extern long FileSizeof(char *); int main() { if(F ...