GCC编译选项-包含的头文件

本文深入探讨了C语言编程中头文件管理、源文件包含、编译选项使用及链接库配置的关键技巧,旨在提升程序的移植性和效率。
 

许多情况下,头文件和源文件会单独存放在不同的目录中。

可以直接在.c文件中利用#include“/path/file.h", 通过指定头文件的路径(可以是绝对路径,也可以是相对路径)来包含头文件. 但这明显降低了程序的可移植性. 在别的系统环境下编译可能会出现问题.

  所以还是利用"-I"选项指定头文件完整的包含路径.

  针对头文件比较多的情况, 最好把它们统一放在一个目录中,比如~/project/include. 这样就不需为不同的头文件指定不同的路径. 如果你嫌每次输入这么多选项太麻烦,你可以通过设置环境变量来添加路径:

  $ C_INCLUDE_PATH=/opt/gdbm-1.8.3/include

  $ export C_INCLUDE_PATH

  $ LIBRART_PATH=/opt/gdbm-1.8.3/lib

  $ export LIBRART_PATH

  可一次指定多个搜索路径,":"用于分隔它们,"."表示当前路径,如:

  $ C_INCLUDE_PATH=.:/opt/gdbm-1.8.3/include:/net/include

  $ LIBRARY_PATH=.:/opt/gdbm-1.8.3/lib:/net/lib

  (可以添加多个路径,路径之间用:相隔,.代表当前目录,若.在最前头,也可省略)

  当然,若想永久地添加这些路径,可以在.bash_profile中添加上述语句.

 

   例如,假设存放源文件的子目录名为./src,而包含文件则放在同层次的其他目录下,如./inc。当我们在./src目录下进行编译工作时,如何告诉GCC到哪里找头文件呢?方法如下所示:
         $ gcc test.c  ,I../inc -o test
  上面的命令告诉GCC包含文件存放在./inc目录下,在当前目录的上一级。如果在编译时需要的包含文件存放在多个目录下,可以使用多个-I 来指定各个目录:
       包含多个目录: $ gcc test.c -I../inc -I../../inc2 -o test
    这里指出了另一个包含子目录inc2,较之前目录它还要在再上两级才能找到。

 

    C编译器通过源文件的后缀名来判断是 C 程序还是 C++ 程序。在 Linux 中,C 源文件的后缀名为 .c,而 C++源文件的后缀名为 .C 或 .cpp。但是,gcc 命令只能编译 C++ 源文件,而不能自动和 C++程序使用的库连接。因此,通常使用 g++ 命令来完成C++ 程序的编译和连接,该程序会自动调用 gcc 实现编译。

     -g生成调试信息。GNU 调试器可利用该信息。

    -w 不生成任何警告信息。
    -Wall 生成所有警告信息。

    -c只编译并生成目标文件

    the -c option says not  to run thelinker.  Then the output consists of object filesoutput by  the assembler.

 

 -c      Compile or assemble the source files, but do notlink.  The link-
          ing stage simply is not done.  The ultimate outputis in the form
          of an object file for each source file.

          By default, the object file name for a source file is made by
          replacing the suffix .c, .i, .s, etc., with .o.

          Unrecognized input files, not requiring compilation orassembly,
          are ignored.

  -S    Stop after the stage of compilation proper; do notassemble.  The
          output is in the form of an assembler code file for each non-
          assembler input file specified.

          By default, the assembler file name for a source file is madeby
          replacing the suffix .c, .i, etc., with .s.

          Input files that don\u2019t require compilation are ignored.

  -E    Stop after the preprocessing stage; do not run the compiler
          proper.  The output is in the form of preprocessedsource code,
          which is sent to the standard output.

          Input files which don't require preprocessing are ignored.


 -v      Print (on standard error output) the commandsexecuted to run the
          stages of compilation.  Also print the versionnumber of the com-
          piler driver program and of the preprocessor and the compiler
          proper.

 --version
          Display the version number and copyrights of the invoked GCC.

  -###
          Like -v except the commands are not executed and all commandargu-
          ments are quoted.  This is useful for shellscripts to capture the
          driver-generated command lines.

  -pipe
          Use pipes rather than temporary files for communicationbetween
          the various stages of compilation.  This fails towork on some
          systems where the assembler is unable to read from a pipe; butthe
          GNU assembler has no trouble.

优化选项:

 

    OptionsThat Control Optimization

      Theseoptions control various sorts ofoptimizations. Without any optimization option,the compiler's goal is to reduce the cost of compilation and tomake debugging produce the expectedresults.  Statements are independent: if you stopthe program with a  breakpoint betweenstatements(计算机程序指令或语句), you can then assign a new value to anyvariable or change the program  counter to any other statement in the function and get exactly theresults you would expect from the source code.

     Turningon optimization flags makes the compiler attempt to improve theperformance and/or code size at the expense ofcompilation time and possibly the ability to debug the program.

      The compiler performs optimization based on the knowledge it has ofthe program.  Usingthe -funit-at-a-time flag will allow the compilerto consider information gained from later functions in the filewhen compiling a function.  Compiling multiplefiles at once to a single output file (and using -funit-at-a-time)will allow the compiler to use information gained from all of thefiles when compiling each of them.

      Not all optimizations are controlled directly by aflag.  Only optimizations that have a flagare
      listed.

      -O
      -O1 Optimize.  Optimizing compilation takessomewhat more time, and a lot more memory for alarge  function.

     With -O, the compiler tries to reduce code size and execution time,without performingany   optimizations that take a great deal of compilation time.-O turnson the following optimization flags: -fdefer-pop -fmerge-constants-fthread-jumps -floop-optimize -fif-conversion-fif-conversion2 -fdelayed-branch-fguess-branch-probability-fcprop-registers  -Oalso turns on -fomit-frame-pointer on machines where doing so doesnot interfere with debugging.

          -O2 Optimize even more.  GCC performs nearly allsupported optimizations that do not involve a space-speedtradeoff.  The compiler does not perform loopunrolling or function inlining when you specify-O2.  As compared to -O, this option increasesboth compilation time and the performance of  thegenerated code.
     -O2 turns on all optimization flags specified by-O.  It also turns on the following optimizationflags: -fforce-mem -foptimize-sibling-calls -fstrength-reduce-fcse-follow-jumps
 -fcse-skip-blocks-frerun-cse-after-loop  -frerun-loop-opt-fgcse  -fgcse-lm -fgcse-sm  -fgcse-las -fdelete-null-pointer-checks-fexpensive-optimizations -fregmove -fschedule-insns
-fschedule-insns2 -fsched-interblock  -fsched-spec-fcaller-saves -fpeephole2 -freorder-blocks
-freorder-functions -fstrict-aliasing -funit-at-a-time-falign-functions -falign-jumps-falign-loops  -falign-labels-fcrossjumping

     Please note the warning under -fgcse about invoking -O2 on programsthat use computed gotos.

      

    -O3Optimize yet more.  -O3 turns on all optimizationsspecified by -O2 and also turns on the -fin-line-functions, -fweb,-frename-registers and -funswitch-loops options.

      -O0 Do not optimize.  This is the default.

      -Os Optimize for size.  -Os enables all -O2optimizations that do not typically increase code size.
       It also performs further optimizations designed to reduce codesize.

     -Os disables the following optimization flags:-falign-functions  -falign-jumps -falign-loops  -falign-labels -freorder-blocks  -fprefetch-loop-arrays

    Ifyou use multiple -O options, with or without level numbers, thelast such option is the one
that is effective.

      Optionsof the form -fflag specify machine-independentflags.  Most flags have both positive and negativeforms; the negative form of -ffoo would be-fno-foo.  In the table below, only one of theforms is listed---the one you typically will use. You can figure out the other form by either removing no or addingit.

     Thefollowing options control specific optimizations. They are either activated by -O options or are related to ones thatare.  You can use the following flags in the rarecases when "fine turning"of optimizations to be performed is desired.

   -fno-default-inline
    Donot make member functions inline by default merely because they aredefined inside the class scope (C++only).  Otherwise, when you specify -O, memberfunctions defined inside class scopeare compiled inline by default;i.e., you don\u2019t need to add inline in front of the memberfunction name.
 

   关于编译选项的次序: Order does matter when you useseveral options of the same kind; for example, ifyou specify -L more than once, the directories are searched in theorder specified.

 

  Overall Options
          -c  -S  -E  -ofile  -pipe  -pass-exit-codes -xlanguage  -v  -###
          --help  --target-help --version

 C Language Options
          -ansi  -std=standard  -aux-infofilename -fno-asm  -fno-builtin
          -fno-builtin-function -fhosted -ffreestanding  -fms-extensions
          -trigraphs  -no-integrated-cpp -traditional  -traditional-cpp
          -fallow-single-precision  -fcond-mismatch-fsigned-bitfields
          -fsigned-char -funsigned-bitfields -funsigned-char
          -fwritable-strings

 C++ Language Options
          -fabi-version=n -fno-access-control  -fcheck-new-fconserve-space
          -fno-const-strings -fno-elide-constructors-fno-enforce-eh-specs
          -ffor-scope  -fno-for-scope -fno-gnu-keywords -fno-implicit-tem-
          plates -fno-implicit-inline-templates -fno-implement-inlines
          -fms-extensions -fno-nonansi-builtins -fno-operator-names
          -fno-optional-diags  -fpermissive-frepo  -fno-rtti  -fstats
          -ftemplate-depth-n -fno-threadsafe-statics -fuse-cxa-atexit
          -fno-weak  -nostdinc++-fno-default-inline  -fvisibil-
          ity-inlines-hidden -Wabi  -Wctor-dtor-privacy-Wnon-virtual-dtor
          -Wreorder -Weffc++  -Wno-deprecated-Wno-non-template-friend
          -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions
          -Wsign-promo
 

下面的是一个调用数学库 libm.asin函数的的例子,创建文件calc.c

    #include<math.h>

    #include<stdio.h>

    int main(void)

   {

    double x= 2.0;

    double y= sin (x);

    printf("The value of sin(2.0) is %f\n", y);

    return0;

  }

尝试单独从该文件生成一个可执行文件将导致一个链接阶段的错误:函数sin,未在本程序中定义也不在默认库‘libc.a’中;

    gcc -Wallcalc.c /usr/lib/libm.a -o calc

为避免在命令行中指定长长的路径,编译器为链接函数库提供了快捷的选项‘-l’。例如,下面的命令      $gcc -Wall calc.c -lm -o calc

与我们上面指定库全路径‘/usr/lib/libm.a’的命令等价。

程序通常要使用很多 -l 选项来指定要链接的数学库,图形库,网络库等。

 

 

 

1)在实现共享库时,要将源文件编译为相对地址编码的格式。
2)Gcc选项 -fpic是实现1)中要求的选项。pic是position independent code的缩写。如:gcc -c-fpic component1.c component2.c

3)在链接时定位共享库:用-L指定绝对路径,也可以是用-l指定相对路径。

   默认搜索路径是/lib和/usr/lib

4)在运行时,应用程序的搜索路径包括:环境变量LD_LIBRARY_PATH指定的路径、/etc/ld.so.cache中的共享库(由ldconfig生成)、/lib和/usr/lib。另外还有一个环境变量LD_PRELOAD,在这里定义的共享库会比任何前述路径优先搜索。

 

 

   gdb调试时:查看数据

       print variable       查看变量

       print *array@len     查看数组(array是数组指针,len是需要数据长度)

       可以通过添加参数来设置输出格式:

           /x 按十六进制格式显示变量。

           /d 按十进制格式显示变量。

           /u 按十六进制格式显示无符号整型。

           /o 按八进制格式显示变量。

           /t 按二进制格式显示变量。

           /a 按十六进制格式显示变量。

           /c 按字符格式显示变量。

           /f 按浮数格式显示变量。

### GCC 编译选项 `-include` 的用法 GCC 提供了一个名为 `-include` 的编译选项,用于在编译过程中自动包含指定的头文件。该选项的作用是在每次编译时强制包含某个特定的头文件,无需在源代码中显式地写入 `#include <filename>` 或 `#include "filename"`。 #### 功能描述 当使用 `-include filename` 时,GCC 会在预处理阶段将指定的头文件内容插入到每一个源文件的开头位置[^1]。这相当于在每个源文件的第一行隐式添加了一条 `#include "filename"` 指令。这种方式特别适用于需要全局定义某些宏或者共享数据结构的情况。 #### 使用场景 - **统一管理全局配置**:可以通过 `-include` 将一些通用的配置文件(如版本号、调试标志等)嵌入到所有源文件中。 - **简化依赖关系**:减少对多个头文件的手动引入需求,特别是在项目中有大量重复使用的头文件时。 - **解决条件编译问题**:可以用来预先加载某些条件编译所需的宏定义。 #### 示例代码 假设有一个头文件 `common.h`,其内容如下: ```c // common.h #define DEBUG_MODE 1 void log_message(const char *msg); ``` 现在希望在整个项目的编译过程中都包含这个头文件,则可以在 GCC 命令行中加入 `-include` 参数: ```bash gcc -include common.h main.c -o program ``` 这条命令的效果等同于在 `main.c` 文件顶部手动加上了以下语句: ```c #include "common.h" ``` 如果还有其他 C 文件也需要此头文件的内容,只需继续沿用相同的编译指令即可,不需要逐一修改各个源文件。 #### 注意事项 1. 如果指定了多个 `-include` 选项,它们会按照出现顺序依次被包含进去。 2. 当同一个头文件既通过 `-include` 被包含又出现在源代码中的 `#include` 中时,实际效果取决于具体实现细节以及是否有防护机制防止多次包含。 3. 对于跨平台开发环境下的交叉编译工具链而言,在应用此类功能的同时还需要注意路径设置等问题,确保能够正确访问目标平台对应的资源文件[^2]。 #### 总结 利用 `-include` 可以为复杂工程项目提供一种便捷的方式来集中管理和分发必要的公共信息片段;然而也需要注意合理规划好整体架构设计以免造成不必要的混乱或冲突现象发生。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值