在linux环境下编译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),链接对象文件和 libstd c++ 库中的函数得到可执行程序。然后删除对象文件。由于命令行中未指定可执行程序的文件名,编译器采用默认的 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++ -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

原文地址:https://www.cnblogs.com/wangshaowei/p/10242066.html

时间: 2024-11-05 18:41:09

在linux环境下编译C++ 程序的相关文章

Ubantu Linux 环境下编译c++程序

先在文件中新建一个a.cpp文件,在里面编写程序, 然后打开终端输入下面命令即可; $ g++ a.cpp -o b ///编译a.cpp 然后把编译之后的.exe文件存入b中 $ ./b ///执行当前目录下的b,就是运行程序的意思; 这是简单的编译运行,接着就是调试了(个人建议直接用输出对应变量的方法比较好),下面记录一些基本命令 $ g++ a.cpp -o b -g /// $ gdb /// $ file b ///对应文件b $ l ///查看b中的内容, l(list); $ b

在linux环境下编译运行OpenCV程序的两种方法

原来以为在Ubuntu下安装好了OpenCV之后,自己写个简单的程序应该很容易吧,但是呢,就是为了编译一个简单的显示图片的程序我都快被弄崩溃了. 在谷歌和上StackOverFlow查看相关问题解答之后,我下面就介绍Command Line和CMake两种方式. 首先我先粘上我测试的代码吧,文件名为Test.c 1 #include <highgui.h> 2 3 int main(int argc,char ** argv) { 4 5 IplImage* img = cvLoadImage

在虚拟机linux环境下编译windows版adb fastboot

原文出自:http://blog.chinaunix.net/uid-20546441-id-1746200.html 我根据虚拟机编译遇到的问题进行一些添加 [前提条件] Linux Android源码完整 虚拟机磁盘空间100G左右(60G用来存放代码和编译后的文件) swap 30G左右,若太小会导致在编译后提示缺失文件 [具体步骤] 理论上,只要下一个windows版本的SDK,里面就自带了fastboot和adb工具. 但我最近确实遇到了一个需要在linux下编译出windows版本的

linux环境下编译运行OpenCV程序的两种方法

一.命令行Command Line 1 g++ opencv_test.cpp -o opencv_test `pkg-config --cflags --libs opencv` 2 ./opencv_test test.jpg 备注:pkg-config选项--cflags 它是用来指定程序在编译时所需要头文件所在的目录--libs 则是指定程序在链接时所需要的动态链接库的目录 二.CMake工具编译 在程序同目录下创建CMakeLists.txt 1 #文件地址(下载源码安装包中):/op

linux环境下编译带中文的java源文件unmappable character for encoding UTF8

添加-encoding gbk即可编译成功 javac -encoding gbk -cp .:activemq-all-5.11.1.jar  JMSConsumer.java linux下独立运行java程序 http://os.51cto.com/art/201104/256055.htm

[转载]Linux 环境下编译 0.11版本内核 kernel

最近在看<linux内 核0.11完全注释>一书,由于书中涉及汇编语言的地方众多,本人在大学时汇编语言学得一塌糊涂,所以实在看不下去了,头都大了只好匆匆看了个头尾(前面 几章和最后一章).看来即使有<九阴真经>这样的武功秘籍,内功不够也是修炼不出来神马来的.于是索性下了个0.11版本的kernel下来尝试编译一 把. linux-0.11.tar.gz 下载地址: 下面开始工作: 1. tar xvfz linux-0.11.tar.gz 2. cd linux-0.11 3. m

Linux环境下编写C程序

一:gcc编译链接用法:gcc [选项] 文件...选项:-pass-exit-codes 在某一阶段退出时返回最高的错误码--help 显示此帮助说明--target-help 显示目标机器特定的命令行选项--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]显示特定类型的命令行选项(使用'-v --help'显示子进程的命令行参数)--version 显示编译器版本信息

Linux环境下编译安装PHP

继上一篇文章Mysql,这一章讲如何部署php服务. 三.php安装 1.首先安装GD库和GD库关联程序 (用来处理和生成图片). yum install \libjpeg-devel \libpng-devel \freetype-devel \zlib-devel \gettext-devel \libXpm-devel \libxml2-devel \fontconfig-devel \openssl-devel \bzip2-devel 2.解压安装gd库到/opt tar xzvf g

linux环境下编译问题

最近项目刚开始起动,一些底层库编写用到boost,在编译过程中遇到一些奇怪问题,在此记录下 1.库的连接顺序问题,比如a依赖b,连接的时候要先连接a,eg -L  -a -b; 2.boost库的问题,库里面用到boost,生成库文件没有问题,但是到工程文件生成引用到库文件的时候,提示: undefined reference to `boost::system::get_system_category()' undefined reference to `boost::system::get_