许多情况下,头文件和源文件会单独存放在不同的目录中。
可以直接在.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.a 中 sin函数的的例子,创建文件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 按浮数格式显示变量。