当前位置:首页 » 编程软件 » gccstatic编译

gccstatic编译

发布时间: 2022-07-25 18:53:48

1. gcc 在编译时如何去寻找所需要的头文件

当我们给

$ gcc -o foo.o foo.c

gcc怎么知道去哪里找foo.c里面所include的header文件,连结数据库与系统定义呢? 总共有下列来源指定gcc去那找。
当初在编译时指定的(在~gcc/gcc/collect2.c:locatelib()
写在specs内的
后来用-D -I -L指定的
gcc环境变量设定(编译的时候)
ld.so的环境变量(这是run time的时候)


prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.9.5/

里面有个很重要的specs这个档案 gcc根据这个档,做一些内定的动作。 通常系统上的specs内定装起来是在

/usr/lib/gcc-lib/xxxx-gnulibc/version/

specs档看起来是像这样

*asm:
%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}

*asm_final:
%|

*cpp:
%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:
-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}

*cc1:
%(cc1_cpu) %{profile:-p}

*cc1plus:

*endfile:
%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s

*link:
-m elf_i386 %{shared:-shared} %{!shared: %{!ibcs: %{!static:
%{rdynamic:-export-dynamic} %{!dynamic-linker:-dynamic-linker
/lib/ld-linux.so.2}} %{static:-static}}}

*lib:
%{shared: -lc --version-script libgcc.map%s} %{!shared: %{mieee-fp:-lieee}
%{pthread:-lpthread} %{profile:-lc_p} %{!profile: -lc}}

*libgcc:
-lgcc

*startfile:
%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:%{profile:gcrt1.o%s}
%{!profile:crt1.o%s}}}} crti.o%s %{!shared:crtbegin.o%s}
%{shared:crtbeginS.o%s}

*switches_need_spaces:

*signed_char:
%{funsigned-char:-D__CHAR_UNSIGNED__}

*predefines:
-D__ELF__ -Dunix -Di386 -D__i386__ -Dlinux -Asystem(posix)

*cross_compile:
0

*version:
egcs-2.91.66

*multilib:
. ;

*multilib_defaults:

*multilib_extra:

*multilib_matches:

*linker:
collect2

*cpp_cpu_default:
-D__tune_i386__

*cpp_cpu:
-Asystem(unix) -Acpu(i386) -Amachine(i386) %{!ansi:-Di386}
-D__i386 -D__i386__ %{march=i486:-D__i486 -D__i486__}
%{march=pentium|march=i586:-D__pentium -D__pentium__ }
%{march=pentiumpro|march=i686:-D__pentiumpro -D__pentiumpro__ }
%{m386|mcpu=i386:-D__tune_i386__ } %{m486|mcpu=i486:-D__tune_i486__ }
%{mpentium|mcpu=pentium|mcpu=i586:-D__tune_pentium__ }
%{mpentiumpro|mcpu=pentiumpro|mcpu=i686:-D__tune_pentiumpro__ }
%{!mcpu*:%{!m386:%{!m486:%{!mpentium*:%(cpp_cpu_default)}}}}

*cc1_cpu:
%{!mcpu*: %{m386:-mcpu=i386} %{mno-486:-mcpu=i386 -march=i386}
%{m486:-mcpu=i486} %{mno-386:-mcpu=i486 -march=i486}
%{mno-pentium:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium}
%{mno-pentiumpro:-mcpu=pentium} %{mpentiumpro:-mcpu=pentiumpro}}

在shell下用这行,-E 表示只做到preprocess就好

$ echo 'main(){}' | gcc -E -v -

你会看到gcc去读specs档

Reading specs from /usr/lib/gcc-lib/i386-linux/2.95.2/specs
gcc version 2.95.2 20000220 (Debian GNU/Linux)
/usr/lib/gcc-lib/i386-linux/2.95.2/cpp -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=95 -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -
GNU CPP version 2.95.2 20000220 (Debian GNU/Linux) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/include
End of search list.
The following default directories have been omitted from the search path:
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include
End of omitted list.
# 1 ""
main(){}

所以有内定的定义,(就是用在#if defined #ifndef #define这些东西, 如果有定义这个字符串,就去编译等等。) -Dxxxx -Dxxxx -Axxxx。 还有内定的include文件的搜寻路径

/usr/include
/usr/local/include
/usr/lib/gcc-lib/i386-linux/2.95.2/include
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../include/g++-3
/usr/lib/gcc-lib/i386-linux/2.95.2/../../../../i386-linux/include

但是如果装gcc的时候,是有给定的prefix的话,那么就是

/usr/include
prefix/include
prefix/xxx-xxx-xxx-gnulibc/include
prefix/lib/gcc-lib/xxxx-xxx-xxx-gnulibc/2.8.1/include

所以header file的搜寻会从-I开始然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC_INCLUDE_PATH 再找上述的内定目录
函式库
当我们用到数学函式cos(),cos这个symbol,gcc并不晓它到底是什么东西, 是变量,是函式,要预留多少空间给他等等,完全没有任何讯息,你必须标头 档要#include ,gcc才知道。而且因为specs这个档里面只有要 link -lc也就是只有libc.so这个档内的symbol会被搜寻, 像printf scanf等都在这里面,可是像cos()等就没有了, 所以函式库的选项要多加 -lm ,这时ld才会来找libm这个函式库,
编译的时候,gcc会去找-L,再找gcc的环境变量LIBRARY_PATH,再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的, gcc环境变量与pass给ld的机制在~gcc/gcc/collect2.c下找得到。 这上面只是搜寻路径而已,如果要不加-lm 也能正确的主动搜寻某个特定的lib,例如libm, 就要去在specs这个档案改一下,把math这个函式库加进自动联结函式库 之一。就不用写-lm了。
RUN TIME的时候, 如果编译时没有指定-static这个选项,其实可执行文件并不是真的可执行, 它必须在执行(run time)时需要ld.so来做最后的连结动作,建造一个可执行的 image丢到内存。如果是静态连结,编译时ld会去找libm.a的档 。如果是动态连结去找libm.so。 所以每次有新改版程序, 或新加动态函式库如果不在原本的/etc/ld.so.conf搜寻路径中,都要把路径 加进来,然后用

ldconfig -v

会重建cache并且显示它所参照的函式库。Run Time时ld.so才找得到lib"执行"。 ld与ld.so不一样喔。
一些重要的程序

ld :Link Editor 连结各obj写进一个可执行档(executable)。
ldd :秀出一个执行文件用了那些动态函式库。
ld.so :Dynamic Linker, 动态连结的话,是由ld.so完成执行时期symbol的
:参照与连结。
ld-linux.so :ELF文件的动态连结,跟ld.so一样。只是ld.so是给a.out format的。
:新的glicb2的ld-linux.so.2已经跟ld.so.2结合成单一程序了。
ldconfig :根据/etc/ld.so.conf内的目录,做出动态连结所需的cache档。

ld 就是负责各个函式库文件的信息写进最后可执行档(executable),所以它叫做 link editor,编译时根据flags -L搜寻需要的lib,gcc也会把他的设定pass下来。 ld.so ld-linux.so.2是负责最后动态连结,叫做dynamic linker, RUN Time 执行程序时,它根据这个顺序搜寻函式库。
LD_LIBRARY_PATH 或LD_AOUT_LIBRARY_PATH环境变量所指的路径
ldconfig所建立的cache
/lib /usr/lib内的档
来找程序所需要的动态函式库
ldconfig会根据/etc/ld.so.conf这个档的设定,加上内定的两个目录 /lib /usr/lib来设定ld.so要用到所需要的连结 以及连结的cache到/etc/ld.so.cache。 所以如果换了新的函式库,新的kernel,内部的标头档可能会有变化, 都要跟着改变让gcc正确的找到,喔不,应该是cpp, ld, ld.so能正确的找到。 不然编出来的执行档可能是错误的,执行时还可能segmentation fault。

2. 如何编译生成和调用静态库

如何编译动态库
gcc test1.c test2.c -shared -fPIC -o libtest.so
使用动态库
gcc main.c -L. -ltest -o a.out
(
-L : 表示需要库的路径
-l:表示需要库的名称,如libtest.so,名称则为test
)
(ps:执行a.out时有可能提示找不到libtest.so文件,这时需要把库文件放入到/lib等目录下,或者添加环境变量LD_LIBRARY_PATH,包含有库文件的路径即可)

如何编译静态库
gcc -c test1.c test2.c
ar -r libtest.a test1.o test2.o
使用静态库
gcc main.c -static -L. -ltest -o a.out

-static:可强制编译时使用静态库,如果不使用这个参数,而静态库与动态库同名的话,会优先使用动态库

3. gcc如何编译多文件

你这里有几处问题。

fun.h 加头文件卫士,头文件中声明全局变量要用static修饰。

#ifndefFUN_H
#defineFUN_H
staticintg=10;
voidfun();
#endif

其他文件中引用这个文件的变量,extern int g;

mian.c

#include<stdio.h>
#include"fun.h"
externintg;
voidmain()
{
printf("%d ",g++);
fun();
}

4. GCC怎样进行静态编译

-static 前提是GTK提供了静态库否则没戏
a有可能是导出库,先编译 再检查依赖 用Dependency Walker 缺啥 打包啥

5. 请问linux下,gcc编译程序的过程(从读取源文件到制作可执行程序中间所有过程,越详细越好)

gcc -S *.c 预处理+反汇编

6. 如何用gcc编译包含大数组的程序,x86

static char buff[3G];是不行的
char buff[3G];就能编译通过了

此时gcc不可以用-static选项, 要加-O2
5分钟后运行看看

7. gcc -Wall -static这句在单独编译一个c文件时可以在gcc后面加。那现在在一个比较复杂

写入makefile

8. gcc -shared gcc -static 这两个命令分别起什么作用

其中后面的都是gcc的命令参数,第一个表示的是调用动态库,第二个static表示的是编译的时候禁止调用动态库,此时就是说完全编译出的东西是比较大的,

9. linux命令gcc–static式什么意思

gcc 空格 -static 吧?

-static 是让 gcc 进行静态编译,也就是把所有都需要的函数库都集成进编译出来的程序上,这个程序就可以不依赖外部的函数库运行了。

10. 怎么在命令行里用gcc去编译连接一个程序

你的说法本身就有问题,gcc编译的时候只能去链接 其他依赖文件和库(静态库/动态库)

动态库:.so结尾,在运行时加载。
静态库:.a结尾,在编译时加载。

例如编译hello.c 输出hello可执行文件

链接静态库:
gcc hello.c -L /home/lib -static -l mylib -o hello
-L参数可以向gcc的库文件搜索路径中添加新目录
-static选项强制使用静态链接库
-l mylib -l后面是要静态连接的库(libhellos.a)

链接动态库:
gcc -o hello hello.c -L. -lhello
-L后面的点为当前目录
-lhello 是去链接libhello.so

热点内容
手机存储卡怎么设置 发布:2025-03-18 01:04:26 浏览:211
背算法好处 发布:2025-03-18 01:02:18 浏览:55
win7添加删除在哪个文件夹 发布:2025-03-18 01:02:13 浏览:703
苹果写源码 发布:2025-03-18 00:50:47 浏览:361
生存源码 发布:2025-03-18 00:50:46 浏览:349
bika安卓怎么下载 发布:2025-03-18 00:43:49 浏览:217
mysql删除数据库所有表 发布:2025-03-18 00:43:41 浏览:397
加减法括号的运算法则 发布:2025-03-18 00:35:44 浏览:553
怎么修改手机配置 发布:2025-03-18 00:34:51 浏览:750
安卓应用名称怎么修改 发布:2025-03-18 00:30:46 浏览:662