首页 > 其他分享 >gcc

gcc

时间:2022-10-31 15:37:57浏览次数:57  
标签:gcc 路径 LIBRARY 编译 PATH 预处理


gcc生成静态链接库

gcc -c file1.c
gcc -c file2.c
ar crv my_library.a file1.o file2.o
注意,用gcc链接静态库的时候,-l要放在xxx.c后面
-I -l -L
系统头文件路径是:/usr/include,如果引用的头文件不在系统路径下,那么需要用-Ipath来指明头文件的目录。
静态链接库的系统路径是:/lib, /usr/lib, /usr/local/lib,引用系统路径下的库文件只要加上-lxxx即可(如果库名是libxxx.a,那么为-lxxx)。
如果保存静态库的路径不是系统路径,那么需要使用-Lpath来指明库的路径

静态库链接时搜索路径:
1) ld会去找GCC命令中的参数-L
2) 再找gcc的环境变量LIBRARY_PATH
3) 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的

gcc生成动态链接库

gcc -fPIC -shared file1.c file2.c -o my_library.so
动态库如果没有保存在系统库的路径下,那么应用程序在运行时需要通过export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path来指定动态库的路径

动态库链接时搜索路径:
1) 编译目标代码时指定的动态库搜索路径
2) 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3) 配置文件/etc/ld.so.conf中指定的动态库搜索路径
4) 默认的动态库搜索路径/lib
5) 默认的动态库搜索路径/usr/lib

有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径
LIBRARY_PATH和LD_LIBRARY_PATH是在链接的时候gcc查找的库文件路径,当程序在运行时查找库文件需通过LD_LIBRARY_PATH或RUN_LIBRARY_PATH指定

强制链接时使用静态链接库

默认情况下,gcc在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话,可以在编译时加上-static选项来强制使用静态链接库。
如:gcc -L/path/lib -static -lxxx test.c -o test

gcc参数

warn选项

-Werror
make all warning into errors
-Wall(打开大部分检查,不是所有)
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid
(or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings
described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
-Wall turns on the following warning flags:

-Waddress -Warray-bounds (only with -O2) -Wc++0x-compat -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat -Wmain (only for C/ObjC and unless -ffreestanding)
-Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreorder -Wreturn-type -Wsequence-point -Wsign-compare (only in C++) -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs
-Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wvolatile-register-var

-Wextra
This enables some extra warning flags that are not enabled by -Wall.
(This option used to be called -W. The older name is still supported, but
the newer name is more descriptive.)

-g

生成可执行文件中包含gdb调试信息,发生异常时会产生core文件。

-O[level]

指定优化等级,level数字越大优化程序越高,需要的编译时间也越长。默认是-O0,许多程序员喜欢用-O2,因为他在优化长度,编译时间和代码之间取得一个比较理想的平衡点。

-DMACRO

以字符串”1”定义MACRO宏
如果在源代码中使用

#ifdef MACRO

#endif

则源代码会根据gcc编译选项编译

-DMACRO=DEFN

以字符串”DEFN”定义MACRO宏

-fPIC

-fPIC作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任何位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

-shared

编译源代码为动态链接库,如gcc -fPIC -shared test.c -o libtest.so

-E -S -c -o

-E 仅预处理 gcc -E test.c -o test.i
-S 仅预处理和编译 gcc -S test.c -o test.s
-c 预处理、编译和汇编 gcc -c test1.c test2.c生成各自的目标文件test1.o test2.o
-o output_filename 生成指定文件,如果没有指定,生成a.out

-Lpath -Ipath -l

如果代码中只使用c的标准库(libc.a libc.so),不需要指定选项
如果使用了非标准库,且该库文件及库的头文件位于默认目录,需要使用-lxxx,例如使用了libm.a或libm.so,需要指定-lm
如果使用了非标准库,且该库文件及库的头文件不在默认目录,需要使用-Ipath指定库的头文件所在目录,-Lpath指定库文件所在位置,-lxxx指定使用的库


gcc编译属性

unused
它用于函数和变量,表示该函数或变量可能不使用,可以在编译时防止编译器产生“变量未使用”这样的警告信息

pack
不进行对齐

align
使用指定的字节数对齐

force
# define force __attribute((force))
表示所定义的变量类型是可以做强制类型转换的,在进行Sparse分析的时候,是不用报告警信息的。


预编译

预编译又称预处理,主要做些代码替换的工作。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换。预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。下面是部分预处理指令:

#             空指令,无任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,相当于#elseif
#endif 结束一个#if……#else条件编译块
#error 停止编译并显示错误信息

文件包含

‘#include’预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。
在程序中包含头文件有两种格式:

#include <my.h>
#include "my.h"

为了避免那些只包含一次的头文件被包含多次,可以在头文件中用编译条件来进行控制

#ifndef MY_H
#define MY_H
...
#endif

宏最常见的用法是定义代表某个值的全局符号。宏的第二种用法是定义带参数的宏,这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。
#define指令
#运算符
‘#’运算符把跟在其后的参数转换成一个字符串。有时把这种用法的#称为字符串化运算符。例如:

#define PASTE(n) "adhfkj"#n
main()
{
printf("%s\n",PASTE(15));
}

输出应该是adhfkj15

##运算符
‘##’运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号

#define NUM(a,b,c) a##b##c
#define STR(a,b,c) a##b##c

main()
{
printf("%d\n",NUM(1,2,3));
printf("%s\n",STR("aa","bb","cc"));
}

最后程序的输出为:
123
aabbcc\


条件编译指令

条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件
#if
#endif
#ifdef和#ifndef
#else
#elif


error

​#error [message]​​​ //message为用户自定义的错误提示信息,可缺省。
使编译器显示一条错误信息,然后停止编译。


其他一些标准指令

#line指令可以改变编译器用来指出警告和错误信息的文件号和行号。
#pragma指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息


标签:gcc,路径,LIBRARY,编译,PATH,预处理
From: https://blog.51cto.com/u_15854579/5809887

相关文章

  • 为什么有时候某函数明明只写了一次,gcc和ld却报错 “multiple definition” ?
    最主要的可能:你在头文件里写了非staticinline的函数定义(注意定义和声明的区别)有函数体的函数->定义,而非声明有初始化的全局变量->定义,而非声明原因:1.有可能是......
  • 使用最新版 gcc cmake
    debian获取最新的包(容器里测试常用)echo'debhttp://deb.debian.org/debiantestingmain'>>/etc/apt/sources.listaptinstall-ybuild-essentialgccg++cmake......
  • gcc 安装
    cgo:Ccompiler"gcc"notfound:exec:"gcc":executablefilenotfoundin%PATH%问题描述场景描述win10系统搭建的golang开发环境,版本是goversiongo1.17.2wind......
  • gcc基本操作
    25P-gcc编译4步骤26P-gcc编译常用参数当头文件和源码不在一个目录下时,需要指定头文件下图是头文件和源码在同一个目录下将hello.h放入新建的文件夹hellodir之后,编译会失败g......
  • gcc常用选项
    选项名作用 -c 通知GCC取消连接步骤,即编译源码并在最后生成目标文件。-Dmacro定义指定的宏,使它能够通过源码中的#ifdef进行检验。-E不经过编译预处理......
  • gcc链接脚本与__attribute__((unused, section(".xxxx")))
    默认的链接脚本gcc中​​typeattribute((unused,section(".xxxx")))name=val;​​可以让name存储到指定的段中。指定链接脚本:gcchello.c-Wl,-Ts.lds通过​​-Txx......
  • linux下使用gcc编译含gets()函数的程序
    网上有很多关于gets()会导致栈溢出之类的废话也许会有初学者望着千篇一律的回答茫然无错,以为真的就只能使用fgets()了 首先你要了解gets()函数有极大的风险其次,在gcc......
  • linux—— 使用gcc解析程序四个阶段
    (文章目录)一、gcc1.gcc的安装yum-yinstallgcc-c++autoconfpcrepcre-develmakeautomakeyum-yinstallwgethttpd-toolsvim2.gcc的默认使用[yzq@VM-8-8......
  • (一)GCC
    1.GCC简介GCC原名为GNUC语言编译器(GNUCCompiler)GCC(GNUCompilerCollection,GNU编译器套件)是由GNU开发的编程语言译器。GNU编译器套件包括C、C++、Objective-C、......
  • GCC 选项 “-Wl,-rpath=“ 转载文章
    -Wl,-rpath=<your_lib_dir> 为程序添加一个运行时库文件搜索路径。-Wl:这个是gcc的参数,表示编译器将后面的参数传递给链接器ld。-rpath:添加一个文件夹作为运行时库的搜索......