gcc 笔记
看了这个手册,了解了一些gcc的相关知识,记录一下。
1.
gcc -Wall hello.c
gcc -Wall -g hello.c // 加入了调试信息,可以用gdb调试。 2. gcc 默认搜索的header file path is: /usr/local/include /usr/include 默认搜索的lib path is /usr/local/lib /usr/lib 而且,在/usr/local/xxx中的文件,优先级要高于/usr/xxx 可以使用 `gcc -print-prog-name=cc1` -v
`gcc -print-prog-name=cc1plus` -v
来分别确认c++/c编译器查找header file的位置
如果你的header file 和 lib 不在这几个地方。那就要用 -I -L来指定。 -I 表示要找的header file 文件夹 -L 表示要找的lib file 文件夹 例: gcc -Wall -I/opt/gdbm-1.8.3/include -L/opt/gdbm-1.8.3/lib dbmain.c -lgdbm
3.
如果想要在shell里直接加载path,可以用C_INCLUDE_PATH(表示c) or CPLUS_INCLUDE_PATH(表示c++) LIBRARY_PATH表示lib path. like: $ C_INCLUDE_PATH=/opt/gdbm-1.8.3/include // c++ 的话,就是:CPLUS_INCLUDE_PATH
$ export C_INCLUDE_PATH
$ LIBRARY_PATH=/opt/gdbm-1.8.3/lib
$ export LIBRARY_PATH
这些path的搜索顺序是:先搜索用-I -L指定的,然后就是export进来的,最后才是/usr/local/xxx,最后是/usr/xxx 4. 可以使用':'来区分include 或者 lib,这样就不用一次次指定。ex: $ C_INCLUDE_PATH=.:/opt/gdbm-1.8.3/include:/net/include $ LIBRARY_PATH=.:/opt/gdbm-1.8.3/lib:/net/lib For C++ programs, use the environment variable CPLUS_INCLUDE_PATH instead of C_INCLUDE_PATH. .表示当前目录 如果要分开写,就会很麻烦,上面的就要表示为: $ gcc -I. -I/opt/gdbm-1.8.3/include -I/net/include -L. -L/opt/gdbm-1.8.3/lib -L/net/lib ..... 5. 要加载某个动态库如libName.so,那要在编译时加入 -lName, gcc会自动在设定好的lib path找libName.so的文件,.so文件的优先级高于.a的静态库文件,如果要加静态库,那就要加入 -static, 如: $ gcc -Wall -static -I/opt/gdbm-1.8.3/include/
-L/opt/gdbm-1.8.3/lib/ dbmain.c -lgdbm
6. /etc/ld.so.conf 这个文件管理着加载so文件的路径 7. 对于调试,有时程序会出现core dumped,这时,你是多么的希望有一个core文件。首先要先在编译时加入-g选项。 然后查看 $ulimit -c 0 $ulimit -c unlimited $ulimit -c unlimited
如果ulimit -c得到的是0,说明没有开启在core dumped时生成core文件。使用ulimit -c unlimited就可以解决。 然后: $gdb a.out core
8. how the compiler works
(1)preprocessing(to expand macros)
(2)compilation(from source code to assembly language)
(3)assembly(from assembly language to machine code)
(4)linking(to create the final executable)
9. 当你知道的所有lib在命令行里了,然后还报undefined references错误,那就要注意是不是引用的顺序了。如test.c里面要调用m.so里面的sqrt()方法。那在编译时,指令就要:
$ gcc -Wall test.c -lm -o calc 如果把 -lm 放到test.c前面,就会报undefined references错误了。因为在test.c里找不到sqrt()定义是,就会向后找。如果-lm放在前面,test.c自然就找不到了。 10. 可以通过 cpp -dM /dev/null 查看所有在预编译器中定义的宏。 11. 还是对于调试,有时会定义 #ifdef TEST
xxx
#endif
如果你想让这中间的代码执行,那就要 gcc -DTEST test.c -o test 就是加入-DXXX,XXX为定义的标签。 12. 可以使用gprof进行性能测试。 13. 执行文件的情况分析。让你知道 $file a.out 出来的信息表示什么。 14. $ldd a.out 得到可执行文件所引用的动态库。