gcc动态编译和静态编译方法

一.单个源.cpp文件生成可执行程序
下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码:

 /* helloworld.cpp */
#include <iostream>
int main()
{
std::cout << "hello, world" ;
return();
}

*****  c++ helloworld.cpp -o hello -Wall
编译器c++ 通过检查命令行中指定的文件的后缀名可识别其为 C++ 源代码文件,同时打印提示信息。

编译器默认的动作:编译源代码文件生成对象文件(object file)

链接对象文件和 libstdc++ 库中的函数得到可执行程序。然后删除对象文件。

由于命令行中未指定可执行程序的文件名,编译器采用默认的 a.out。

程序可以这样来运行: 
***** ./hello
hello, world
程序c++/g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。

通过遵循源码的命名规范并指定对应库的名字,用 gcc 默认编译c文件,通过扩展来编译链接 C++ 程序也是可行的,

如下例所示: 
***** gcc helloworld.cpp  -lstdc++  -o  helloworld
选项 -l (ell) 通过添加前缀 lib 和后缀 .a 将跟随它的名字变换为库的名字 libstdc++.a,而后它在标准库路径中查找该库。

gcc 的编译过程和输出文件与 c++/g++ 是完全相同的。

二.预编译处理和生成汇编代码
编译预处理 选项 -E 使 c++ 将源代码用编译预处理器处理后不再执行其他动作。

下面的命令预处理源码文件 helloworld.cpp 并将结果显示在标准输出中:

***** c++ -E helloworld.cpp

预处理后的版本将超过 12000 行。这主要是因为头文件 iostream 被包含进来,

而且它又包含了其他的头文件,除此之外,还有若干个处理输入和输出的类的定义。

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

例如:

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

生成汇编代码 选项 -S 指示编译器将程序编译成汇编语言,输出汇编语言代码而后结束。

下面的命令将由 C++ 源码文件生成汇编语言文件 helloworld.s:

***** g++ -S helloworld.cpp 生成的汇编语言依赖于编译器的目标

三.多个源文件生成可执行程序de动态编译
如果多于一个的源码文件在 g++ 命令中指定,它们都将被编译并被链接成一个单一的可执行文件。

下面是一个名为 speak.h 的头文件;

它包含一个仅含有一个函数的类的定义: (示例来自:c++primer plus)

 /* stack.h */

 #ifndef STACK_H_ #define STACK_H_

 typedef unsigned long Item;

 class Stack 

 { 

 private:

    enum {MAX=};

    Item items[MAX]; 

    int top;

 public:  

 Stack(); 

    bool isempty() const; 

    bool isfull() const;

    bool push(const Item & item);

    bool pop(Item & item); };

 #endif

下面列出的是文件 stack.cpp 的内容:

/* stack.cpp */
#include"stack.h" Stack::Stack() {  top=; } bool Stack::isempty() const {   return top==; } bool Stack::isfull() const {   return top==MAX; } bool Stack::push(const Item&item) {   if(top<MAX)   {     items[top++]=item;      return true;    }   else return false; } bool Stack::pop(Item&item) {   if(top>)   {     item=items[--top];     return true;   }     else return false; }

文件 hellospeak.cpp 内是一个使用 stack 类的程序:

/* stacker.cpp*/
// stacker.cpp -- testing the Stack class
#include <iostream>
#include <cctype> // or ctype.h
#include "stack.h"
int main()
{
using namespace std;
Stack st; // create an empty stack
char ch;
unsigned long po;
cout << "Please enter A to add a purchase order,\n"
<< "P to process a PO, or Q to quit.\n";
while (cin >> ch && toupper(ch) != 'Q')
{
while (cin.get() != '\n')
continue;
if (!isalpha(ch))
{
cout << '\a';
continue;
}
switch(ch)
{
case 'A':
case 'a': cout << "Enter a PO number to add: ";
cin >> po;
if (st.isfull())
cout << "stack already full\n";
else
st.push(po);
break;
case 'P':
case 'p': if (st.isempty())
cout << "stack already empty\n";
else {
st.pop(po);
cout << "PO #" << po << " popped\n";
}
break;
}
cout << "Please enter A to add a purchase order,\n"
<< "P to process a PO, or Q to quit.\n";
}
cout << "Bye\n";
return ;
}

下面这条命令将上述两个源码文件编译链接成一个单一的可执行程序: 
***** c++ stack.cpp stacker.cpp -o stacks
源文件生成对象文件
选项 -c 用来告诉编译器编译源代码但不要执行链接,输出结果为对象文件,后缀变为 .o。

例如,下面的命令将编译源码文件 hellospeak.cpp 并生成对象文件 hellospeak.o: 
***** c++ -c stacker.cpp
命令 g++ 也能识别 .o 文件并将其作为输入文件传递给链接器。

下列命令将编译源码文件为对象文件并将其链接成单一的可执行程序: 
***** c++ -c stacker.cpp 
***** c++ -c stack.cpp 
***** c++ stacker.o  stack.o -o stacks
选项 -o 不仅仅能用来命名可执行文件。它也用来命名编译器输出的其他文件。

四.多个源文件生成可执行程序de静态编译
创建静态库 
静态库是编译器生成的一系列对象文件的集合。

链接一个程序时用库中的对象文件还是目录中的对象文件都是一样的。

库中的成员包括普通函数,类定义,类的对象实例等等。

静态库的另一个名字叫归档文件(archive),管理这种归档文件的工具叫 ar 。 
在上面的例子中,我们先创建两个对象模块,然后用其生成静态库。

源码文件 stack.cpp 是我们要加入到静态库中的第一个对象文件的源码。
源码文件 stacker.cpp 是我们要加入到静态库中的第二个对象文件的源码。
下面的命令序列将源码文件编译成对象文件,命令 ar 将其存进库中: 
***** c++ -c stack.cpp
***** c++ -c stacker.cpp
***** ar -r lib.a stack.o stacker.o
程序 ar 配合参数 -r 创建一个新库 lib.a 并将命令行中列出的对象文件插入。

采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,

而如果库存在的话,将用新的模块替换原来的模块。

如果有第三个.cpp文件(main函数),或者没有也可以直接编译前面的.cpp
该程序可以下面的命令来编译和链接: 
***** c++ stacker.cpp lib.a -o main

刚刚学会的编译方式还是蛮好用的。

PS: powershall也是蛮好用的毕竟不是黑漆漆的界面了233333.

gcc编译C++程序的更多相关文章

  1. GCC编译C程序源代码

    编译简单的 C 程序 C 语言经典的入门例子是 Hello World,下面是一示例代码: #include <stdio.h>  int main(void)  {     printf ...

  2. gcc 编译 c++ 程序(转载)

    单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个简单的 C++ 程序的代码: /* helloworld.cpp */ #include <iostream& ...

  3. MAC中使用Vim和GCC编译C程序

    1.打开终端 2.输入以下命令进入vim编辑器: vim a.c 3.进入编辑器后按i进入insert模式,然后键入以下代码: #include<stdio.h> int main(){ ...

  4. 【LinuxC】GCC编译C程序,关闭随机基址

    1.编译.链接和运行程序 C代码示例: #include <stdio.h> #include <stdlib.h> int main() { printf("hel ...

  5. 转:gcc编译C++程序

    转:http://blog.csdn.net/liujiayu2/article/details/49864381 单个源文件生成可执行程序 下面是一个保存在文件 helloworld.cpp 中一个 ...

  6. windows10 gcc编译C程序(分步编译)

    下面演示gcc对C源程序的分步编译过程: 1. 编译(Compile) gcc hello.cpp -c # 生成hello.o,目标文件名字和源文件名字一样,VC编译会生成.ojb文件,gcc编译器 ...

  7. windows10 gcc编译C程序(简单编译)

    参考:http://c.biancheng.net/view/660.html gcc可以一次性完成C语言源程序的编译,也可以分步骤完成:下面先介绍一次性编译过程. 1.生成可执行程序 cd xxx ...

  8. gcc编译C源文件

    gcc编译C程序的主要过程是:预处理---编译---汇编---连接,其中:(以名为hello.c的源文件为例) 预处理:对各种预处理指令(#开头,如#include,#define)进行处理,以及删除 ...

  9. GCC编译过程与动态链接库和静态链接库

    1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...

随机推荐

  1. SQL替换语句之批量修改、增加、删除字段内容

    语法 REPLACE ( original-string, search-string, replace-string ) 用法 update 表的名称 set 替换字段=REPLACE(替换字段,原 ...

  2. 《TCP/IP详解卷1:协议》第6章 ICMP:Internet控制报文协议-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  3. AngularJS开发指南8:AngularJS模块的详解

    在讲angularjs的模块之前,我们先介绍一下angular的一些知识点: AngularJS是纯客户端技术,完全用Javascript编写的.它使用的是网页开发的常规技术(HTML,CSS,Jav ...

  4. HOW TO REMOTELY DEBUG APPLICATION RUNNING ON TOMCAT FROM WITHIN INTELLIJ IDEA

    This post would look into how to tackle and debug issues in scenarios where they only occur in produ ...

  5. MyEclipse8.5快速搭建SSH框架

    来源于:http://jingyan.baidu.com/article/a378c960a78125b3282830cc.html MyEclipse8.5快速搭建SSH框架 使用版本: Strut ...

  6. 【POJ 1062】昂贵的聘礼(最短路)

    Dijkstra最短路,每次限制一个等级差,再更新答案. #include <cstdio> #define N 105 #define INF 1e9 int m, n; int p[N ...

  7. LinkedHashMap实现LRU算法

    LinkedHashMap特别有意思,它不仅仅是在HashMap上增加Entry的双向链接,它更能借助此特性实现保证Iterator迭代按照插入顺序(以insert模式创建LinkedHashMap) ...

  8. 学习笔记 --- 最大流Dinic算法

    为与机房各位神犇同步,学习下网络流,百度一下发现竟然那么多做法,最后在两种算法中抉择,分别是Dinic和ISAP算法,问过 CA爷后得知其实效率上无异,所以决定跟随Charge的步伐学习Dinic,所 ...

  9. make_pair

    Utilities <utility> 由短小精干的类和函数构成,执行最一般性的工作. 这些工具包括: general types 一些重要的C函数 numeric limits Pair ...

  10. 初学structs2,简单配置

    一.structs2-demo1项目下新建structs.xml文件,文件名必须是structs 二.package节点配置及其子节点配置 <!--name:单纯给包起个名字,保证和其他包不重名 ...