1.将.c 文件编译成.o文件

gcc -c test1.c test2.c test3.c

2.然后用ar命令生成.a文件,ar crv test.a test1.o test2.o test3.o

3.在windows环境,我们有集成开发环境(IDE),使得我们对编译器了解的很少。当我们专向linux时需要在命令行下编译自己的程序需要对编译器的
命令行参数比较熟悉。而如果是做嵌入开发构建自己的操作系统时失去了系统平台,需要我们对编译的过程以及可执行文件的内部结构有所了解。本文讲述了如何编
译可执行文件、静态库、动态库,如何优化编译器,如何编译无操作系统环境下的程序(自己的OS)等。


               
               
               
1.分析普通的helloworld程序
    先书写一下一个简单的helloworld程序如下:
/* hello.c */
int main(int argc, char * argv[])
{
    return 0
}
    编译程序:
gcc -o hello hello.c
    等价的编译方法:
gcc -c hello.c
gcc -o hello.my -nostartfiles hello.o /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o
    我在redflag workstation 5.0版本下用3.4.3版本GCC编译器编译出来的大小都是3589字节,并且用diff命令比较为相同的文件。由此证明gcc在编译并链接 hello.c文件时先将hello.c编译成hello.o,然后将它与crt1.o、crti.o、crtn.o链接在一起。
    如果要写一个没有main函数的程序,就需要自己实现crt1.o。程序入口为符号“_start”处。代码如下:
/* nomain.c */
void _start(void)
{
    _exit(0);
}
gcc -o nomain -nostartfiles hello.c
2.编译和使用库
    除了直接编译代码外还会使用到函数库。库有静态库和动态库之分。静态库是以.a结尾的文件,例如:libXXX.a;动态库是以.so结尾的文件,例如: libXXX.so。XXX之后或者.so和.a之后会跟版本号,例如:libc-2.3.4.so,或者libuuid.so.1.2。
    加入函数库的代码如下:
/* test.h */
int test1 (void);
/* test.c */
#include stdio.h>
#include "libtest.h"
int test1 (void)
{
    printf("test1 function is called.\n");
    return 0;
}
    当要编译成静态库的时候使用如下命令生成libtest.a:
gcc -c test.c
ar -r libtest.a test.o
    当要编译成动态链接库的时候使用如下命令生成libtest.so
gcc -c -fpic test.c
gcc -shared test.o -o libtest.so

gcc -fpic -shered test.c -o libtest.so
    当需要调用该库时使用如下代码。
/* calllib.c */
#include "test.h"
int main (int argc, char * argv[])
{
    test1();
}
    按如下方式编译:
gcc -o calllib.static calllib.c libtest.a

gcc -o calllib.dynamic calllib.c libtest.so

gcc -o calllib calllib.c -ltest
    前提是libtest.a或libtest.so在当前编译的目录。
    使用ldd显示calllib.static依赖的库只有libc和ld-linux,但calllib.dynamic就多了一个libtest.so。
3.库文件和头文件
    在程序中,使用#include stdio.h>类似的头文件stdio.h在编译器的头文件路径中,#include "abc.h"中的stdio.h文件则应该在当前目录。通过对编译器指定参数-IPATH>来指定头文件所在目录,可以用 #include >来引用。例如:gcc -I./include hello.c,将从当前目录下的include目录下去寻找头文件。
    同理,程序中调用的库函数在编译时也需要指定路径,同时指定库。使用-LPATH>参数指定库文件的目录,-lFILE>指定包含的库文件。例如,要使用libXXX.so库,参数为-lXXX。
    一般一个库编译完成后有库文件和头文件。如果要使用这个库,可以将库文件目录和头文件目录分别用-I和-L参数指定,也可以将他们拷贝到编译器的include和lib目录下。
4.缩小程序体积
    代码如下:
/* nomain.c */
void _start(void)
{
    asm("movl , eax\n"
        "movl {fckeditor}, ebx\n"
        "int {fckeditor}x80"
    );
}
使用如下方法能使可执行文件体积最小(手工方法除外)。
gcc -o nomain -s -O3 nomain.c
objcopy -R .comment -R .data
    由此得到可执行文件的体积为352字节。
    GCC能编译出2种格式的可执行体:a.out格式、elf格式。其中.o目标文件、.a静态库文件
Appendix.1 常用命令
ldd:显示可执行文件或者库文件依赖的库文件。
objdump:显示elf可执行文件的内部信息。
    -h:显示
    -t:显示符号信息
    -T:显示动态符号信息。(例如引用动态链接库中的函数名称)
    -r:显示重定位入口信息。
    -R:显示动态重定位入口信息。(例如:动态链接库中的变量或者函数地址)
    -s:显示所有section内容。
    -S:反汇编代码段。
objcopy:copy elf文件内容
    -R:删除某个section
    -j:仅仅复制指定的section

转载于:https://www.cnblogs.com/angelpan1014/archive/2012/10/21/2733057.html

.cpp 编译成.a或是 .so相关推荐

  1. 【转】matlab函数编译成dll供Cpp调用的方法

    转自:https://www.cnblogs.com/vincenzo/archive/2009/09/09/1563467.html 以前做过matlab7与c++的混合编程:将m函数编译成dll给 ...

  2. as 怎么将多个cpp文件代码编译成so_一段C代码,是如何编译运行的?

    想一下, 我们想把源文件放到内存中执行,应该怎么做? 直觉上我们需要将源代码翻译成机器语言,以某种结构组织代码和数据.再让CPU去按这种结构读取指令.如果是多个源文件, 我们可能还需要按某种方式将它们 ...

  3. matlab将cpp编译为dll,Matlab函数编译成dll供Cpp调用的方法图解教程

    曾经实现过将matlab函数编译成dll供Cpp调用,这篇文章的目的是对新增的面向对象的的扩展mwArray进行讲解,matlab很容易和C/C++联合起来使用. 以前做过matlab7与c++的混合 ...

  4. as 怎么将多个cpp文件代码编译成so_你编写的Java代码是咋跑起来的?

    如果你是一名 Java 开发人员,你肯定指定 Java 代码有很多种不同的运行方式.比如说可以在开发工具(IDEA.Eclipse等)中运行,可以双击执行 jar 文件运行,也可以在命令行中运行,甚至 ...

  5. iOS架构-c++工程在Mac下编译成.a库并调用(12)

    请先了解:xcode生成静态库文件.a 前言: 有时侯需要使用c++的一些代码库,这里先讲一下用Xcode 建C++ 工程,并将代码编译成.a库,提供给demo使用.这里只是简单的介绍,以后会继续介绍 ...

  6. 关于模板函数/模板类编译成DLL

    ]关于模板函数/模板类编译成DLL Posted on 2011-08-16 08:48 单鱼游弋 阅读( 353) 评论( 0) 编辑 收藏 要编译成DLL,就要声明和实现分开. 首先文件组织是这样 ...

  7. Python 2.7 cython cythonize py 编译成 pyd 谈谈那些坑(转载)

    转自:https://www.cnblogs.com/ibingshan/p/10334471.html Python 2.7 cython cythonize py 编译成 pyd 谈谈那些坑 前言 ...

  8. cpp 编译dll_GCC编译基础

    资料准备: ❝ 为了方便演示和讲解,在这里提前准备好几个简单的文件:test.cpp test.h main.cpp 文件内容如下: ❞ main.cpp #include "test.h& ...

  9. python编译成c代码_python如何调用c编译好可执行程序

    以下总结出几种在Python 中调用 C/C++ 代码的方法 -------------------------------------------------------------------- ...

最新文章

  1. 2021年信号与系统作业统计处理
  2. FLEX SharedObject介绍及应用
  3. 【RecyclerView】 十一、RecyclerView 数据更新 ( 删除单条数据 | 批量删除数据 )
  4. CentOS7中怎样修改主机名和hosts文件(配置IP和主机名的对应管理)
  5. 系兄弟就来砍我 有向图单源最短路
  6. .NET Core开发日志——OData
  7. 华为发布智简全光网战略,携手上下游重新定义光产业
  8. Spring Boot和Vue的学习(一)--开发环境的安装
  9. 移动项目工作笔记0001---使用uni-app开发移动端应用
  10. 高人,不断地在营销, 有收入就是高人
  11. 复制数据库(本地到阿里云)
  12. 复杂对象ibatis插入,属性为list,怎么一次性插入
  13. 数据结构与算法笔记一:稀疏数组的应用
  14. 韩顺平Linux操作系统视频教程
  15. 三因子两水平doe_温故而知新 | DOE实验设计学习系列之(三):多因子DOE的魅力 (附视频)...
  16. 圣笛数控联手国促会数外委打造OID物联新高地
  17. 产品可用性原则:网页设计点睛秘笈
  18. Cardboard Talk01 HeadTracker
  19. html中屏幕文字轮播怎么做,如何制作网页滚动文字(html)(一)
  20. codevs【1569】最佳绿草

热门文章

  1. 【虚拟化实战】存储设计之七Block Size
  2. 中小企业应如何选择合适的数据保护工具?
  3. 五、oracle 表的管理
  4. Utils.toDip()的用法
  5. SVN 提交出错:Attempted to lock an already-locked dir
  6. Android studio 查找文件在电脑路径位置
  7. android 判断手机为小米
  8. GNU (内部)make函数
  9. (一)Linux基础(1)
  10. windows下安装配置mongodb