用gcc编译生成静态链接库*.a文件的方法

本文详细介绍如何在Linux环境下创建静态库及动态链接库,包括使用gcc和ar命令的具体步骤。同时,文章还提供了实用示例,帮助读者理解整个过程。
1、用gcc的-c选项生成.o文件,如
gcc -c test1.c test2.c test3.c
编译后会生成test1.o test2.o test3.o三个目标文件。
2、然后用ar命令生成.a文件,如

ar crv test.a test1.o test2.o test3.o


我们知道静态库也称档案库,在此档案文件中实际上是收集了一系列的目标文件。这     
  些目标文件就是由cc(gcc)函数的源代码编译生成的。因此,静态库的生成方法实际上     
  可以分成两步:     
  1.将各函数代码所在的源文件编译成目录文件。例如,对于myfunc.c,可以用如下命令     
  将其编译成目标文件:     
                  gcc   -c   myfunc.c     
  当然在有多个源文件时,只需在gcc   命令行中将其分别列上就可以了。     
  经此一步我休养将能够得到各源文件的目标文件。对上例,将得到myfunc.o     
  2.将各目标文件收集起来放到一个静态库文件中。这主要借助于ar命令完成,如:     
                  ar   r  /usr/local/lib/libtest.a   myfunc.o     
    
  建立动态链接库、并不需要用到其他的工具,借助于gcc命令即可完成。此时需在命令     
  行中加上-K   PIC和-G这两个选项,如下我们可以建立libtest的动态版本:                   
                  gcc   -K   PIC   -G   -o   $HOME/lib/libtest.so   myfunc.c
     
    
  发信人:   hellguard   (小四),   信区:   Unix                   
  标     题:   顺便贴个生成Linux动态库的     
  发信站:   BBS   水木清华站   (Fri   Nov   12   10:49:03   1999)     
    
  本来格式很好看的,但因为要贴到这里所以     
  扭曲了不少,见谅见谅。这里给的是linux下的例子,     
  但是solaris下的也差不多,如果你发现不同,就给     
  个详细说明出来,好不好。     
    
  ldd   filename就可以看到程序用到哪些库。     
    
  ld   -o   OUTPUT   /lib/crt0.o   hello.o   -lc     
  ld将输出最终结果文件   OUTPUT   ,     
  用到/lib/crt0.o   hello.o以及libc.a     
  libc.a来自标准库搜索路径,请参看-l选项的讨论     
    
  ld的选项顺序任意,可以重复,后面的将覆盖前面的。     
    
  gcc   -c   -fPIC   linuxlib.c   -O3   -o   linuxlib.o     
  gcc   -shared   -Wl,-soname,liblinuxlib.so.1   \     
          -O3   -o   liblinuxlib.so.1.0   linuxlib.o     
  (     
  ld   -m   elf_i386   -shared   -o   liblinuxlib.so.1.0   \     
          -soname   liblinuxlib.so.1   linuxlib.o     
  这个语句产生的文件更小,不知道二者有何区别     
  -o   liblinuxlib.so.1.0   这个文件名任意,关键是后面     
  两个符号连接要正确     
  当然推荐使用有意义的带版本信息的名字,包括       
  -soname   liblinuxlib.so.1     
  )     
  ln   -sf   liblinuxlib.so.1.0   liblinuxlib.so.1     
  (       
          运行时,dynamic   linker根据   -soname   \     
          liblinuxlib.so.1   去寻找liblinuxlib.so.1     
  )     
  ln   -sf   liblinuxlib.so.1   liblinuxlib.so     
  (       
          编译的最后一个步骤,ld命令根据   -llinuxlib       
          选项去寻找liblinuxlib.so     
  )     
  export   LD_LIBRARY_PATH=.     
  (     
          编译时、运行时都需要这个变量的存在     
          编译时如果不存在这个变量,编译依旧通过,但     
          用ldd查看会发现没有动态连接信息     
          运行时如果不存在这个变量,将报告无法找到动态连接库     
    
          这个变量如果不用相对路径".",换了运行环境就比较麻烦     
          export   LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH     
  )     
  gcc   -L.   -lbsd   -llinuxlib   -O3   -o   linuxkiller   linuxkiller.c     
  (     
          -L.   指出除标准库搜索路径之外的库搜索路径,如果不指     
          定,将找不到liblinuxlib.so     
          这个选项并不能代替   LD_LIBRARY_PATH   变量,否则虽然编译通过,     
          但用ldd   linuxkiller的时候会发现没有动态连接信息     
  )     
    
  可以把自己的动态连接库放到/usr/lib或者/lib下去,或者     
  修改/etc/ld.so.conf     
  然后利用/sbin/ldconfig。具体请man   ldconfig     
    
  --     
    
    
  发信人:   hellguard   (小四),   信区:   Unix                   
  标     题:   Re:   help   :static   library----what's   wrong--Thanks.     
  发信站:   BBS   水木清华站   (Thu   Aug   16   14:22:39   2001)     
    
    
  【   在   hululu   (呼噜噜~回家中)   的大作中提到:   】     
  :   I   am   building   a   static   library.   But   I   do   not   know   what   is       
  :   wrong.   Below   is   a   sample:       
  :   tt.c:       
  :   #include   <stdio.h>       
  :   int   func(){       
  :   printf("func   test\n");       
  :   return   0;       
  :   }       
  :   ii.c:       
  :   #include   <stdio.h>       
  :   extern   int   func();       
  :   ...................     
  ★   生成静态链接库举例     
    
          1.   vi   demo.h     
                void   demo   (   void   );     
    
                vi   demo.c     
                #include   <stdio.h>     
                #include   "demo.h"     
                void   demo   (   void   )     
                {     
                        printf(   "hello   world\n"   );     
                        return;     
                }     
    
          2.   g++   -Wstrict-prototypes   -Wall   -Wunused   -O3   -c   demo.c   -o   demo.o     
                file   demo.o     
    
          3.   ar   -rsv   libdemo.a   demo.o     
                a   -   demo.o     
                file   libdemo.a     
                nm   -s   libdemo.a     
                ar   -tv   libdemo.a       
          4.   vi   scz.c     
                #include   <stdio.h>     
                #include   "demo.h"     
                int   main   (   int   argc,   void   *   argv[]   )     
                {     
                        demo();     
                        return   0;     
                }     
    

          5.   g++   scz.c   -L.   -ldemo   -Wstrict-prototypes   -Wall   -Wunused   -O3   -o   sc

转载http://blog.youkuaiyun.com/focusjava/article/details/12647353

<think>我们正在处理一个关于编译生成静态的问题。用户提供了几个引用,但其中大部分似乎与当前问题不直接相关。用户的核心需求是:如何将mysec.ssc和.c.ssc文件编译生成libmysec.a静态。 分析: 1. 文件扩展名.ssc不太常见,可能是特定领域的源文件(例如:Simulink、某些自定义工具等),但用户同时提到了.c.ssc,这可能是C源文件.c)和.ssc文件的组合?需要进一步明确。 2. 通常,静态生成过程是:将源文件编译成目标文件.o),然后将目标文件打包成静态.a)。 然而,由于扩展名特殊,我们需要推测: - 可能.ssc文件是某种特定领域语言的源文件,需要先转换成C代码或直接编译成目标文件? - 或者.ssc文件本身就是C源文件,只是扩展名不同?如果是这样,我们可以直接当作C文件处理。 由于用户没有提供更多上下文,我们只能假设: 1. .ssc文件可能是某种预处理文件,需要先转换为C文件,然后编译。 2. 或者,用户可能写错了扩展名,实际上应该是.c文件。 但根据用户引用的内容,引用[2]中出现了类似SNMP配置的文本,引用[3]是汇编或机器码,引用[4]是关于PE加载器的,引用[5]是关于Abaqus二次开发的。这些引用似乎与问题无关。 因此,我们只能基于常规的静态生成方法进行解答,并假设: - .ssc文件可能是C源文件(可能是某种工具生成的C代码,扩展名为.ssc),或者需要先转换为C文件。 - 或者是用户笔误,实际应为.c文件。 步骤: 1. 如果.ssc文件需要预处理为C文件,则先进行转换(但用户没有提供转换工具,所以暂时忽略这一步,假设可以直接编译)。 2. 使用编译器(如gcc)将每个源文件(包括.c和.ssc)编译成目标文件.o)。 3. 使用ar工具将目标文件打包成静态.a)。 具体步骤: 假设我们有两个文件:mysec.ssc 和 file.c.ssc(注意:file.c.ssc可能是另一个文件,这里我们假设文件名就是如此) 步骤1:编译文件为目标文件 ```bash gcc -c mysec.ssc -o mysec.o gcc -c file.c.ssc -o file.o ``` 注意:如果.ssc文件不是标准的C文件,上述命令可能失败。这时需要查看.ssc文件的内容,判断其语言类型,并选择合适的编译器。 步骤2:打包目标文件静态 ```bash ar rcs libmysec.a mysec.o file.o ``` 这样就会生成libmysec.a静态。 但是,如果.ssc文件不是C文件,而是其他语言(比如是某种脚本),则需要先转换成C文件或目标文件。由于没有具体信息,我们只能提供通用方法。 另外,用户提到“编译环境下”,所以我们假设是在Linux/Unix环境下使用gcc和ar工具。 如果.ssc文件需要特殊的编译器或转换工具,那么用户需要先进行转换。例如,如果.ssc是Simulink S-Function的源文件,可能需要使用Simulink的工具箱来编译。 因此,我们还需要提醒用户注意文件的实际类型。 总结回答结构: 1. 说明静态的常规生成步骤。 2. 针对.ssc文件可能存在特殊性的说明。 3. 提供通用步骤(假设.ssc可以当作C文件处理)。 4. 注意事项。 相关问题: 1. 如何编译非标准扩展名的源文件? 2. 静态与动态的区别是什么? 3. 如何验证生成静态是否正确? 考虑到用户可能是在特定领域(如网络安全)中,引用[2]看起来像SNMP配置,引用[3]像补丁代码,引用[4]关于PE加载器,可能与安全相关。因此,我们也可以推测这些.ssc文件可能是某种安全相关的源文件,但编译方法应该与普通C文件类似。 最终回答: </think>### 将 `.ssc` 文件编译静态方法 根据您的需求,编译 `mysec.ssc` 和 `.c.ssc` 文件生成 `libmysec.a` 静态的步骤如下(假设在 Linux 环境下使用 GCC 工具链): #### 步骤 1:预处理源文件(可选) 若 `.ssc` 文件包含特殊语法(如 SNMP 配置[^2]),需先转换为标准 C 文件: ```bash # 示例转换命令(具体工具需根据.ssc文件类型确定) ssc_compiler mysec.ssc -o mysec.c ssc_compiler file.c.ssc -o file.c ``` #### 步骤 2:编译为目标文件 ```bash gcc -c mysec.c -o mysec.o # 编译文件 gcc -c file.c -o file.o # 编译依赖文件 ``` **关键参数说明**: - `-c`:只编译链接 - `-fPIC`:若需位置无关代码(通常静态不需要) #### 步骤 3:打包为静态 ```bash ar rcs libmysec.a mysec.o file.o ``` **参数解析**: - `r`:替换已有文件 - `c`:创建新 - `s`:生成索引(加速链接) #### 步骤 4:验证静态 ```bash # 查看包含的符号 nm -gC libmysec.a # 检查文件类型 file libmysec.a # 应显示 "current ar archive" ``` ### 特殊场景处理 1. **Windows 交叉编译**(若目标为 Windows): ```bash x86_64-w64-mingw32-gcc -c mysec.c -o mysec.o x86_64-w64-mingw32-ar rcs libmysec.a mysec.o ``` 2. **PE 文件处理**(如涉及引用[4]的加载器): ```bash # 需要指定加载地址(示例) gcc -c mysec.c -o mysec.o -Wl,--image-base=0x10000000 ``` 3. **依赖模块定义**(参考引用[1]的 DEF 文件): 创建 `libmysec.def`: ```def LIBRARY libmysec EXPORTS mySecFunction1 mySecFunction2 ``` 编译链接 DEF 文件: ```bash dlltool -d libmysec.def -l libmysec.a ``` ### 验证与使用示例 编译测试程序: ```c #include "mysec.h" // 假设有对应头文件 int main() { mySecFunction(); return 0; } ``` 链接静态: ```bash gcc test.c -L. -lmysec -o test_program ``` ### 注意事项 1. **文件类型确认**: - 通过 `file mysec.ssc` 确认文件真实格式 - 若为二进制补丁文件(如引用[3]),需反汇编后重新编译 2. **性能优化**: - 添加编译优化标志 `-O2` - 使用 LTO 链接时优化: ```bash gcc -flto -c mysec.c ar rcs libmysec.a mysec.o ``` 3. **工程化管理**: 推荐使用 Makefile: ```makefile CC = gcc AR = ar OBJS = mysec.o file.o TARGET = libmysec.a all: $(TARGET) $(TARGET): $(OBJS) $(AR) rcs $@ $^ %.o: %.c $(CC) -c $< -o $@ ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值