Linux下 C++代码编译和链接文件的具体过程和分析

先写两个linux的命令,一个nm命令

nm命令被用于显示二进制目标文件的符号表

ldd 命令

ldd命令用于打印程序或者库文件所依赖的共享库列表

查看一个头文件myhead.cpp 编译后的myhead.o 文件的符号表:

zhaozheng@ubuntu:~/code/c++/test_compile/myinclude$  nm myhead.o
                 U __cxa_atexit
                 U __dso_handle
0000000000000075 t _GLOBAL__sub_I__Z5printv
0000000000000023 T _Z3sumii
0000000000000037 t _Z41__static_initialization_and_destruction_0ii
0000000000000000 T _Z5printv
                 U _ZNSolsEPFRSoS_E
                 U _ZNSt8ios_base4InitC1Ev
                 U _ZNSt8ios_base4InitD1Ev
                 U _ZSt4cout
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
0000000000000000 b _ZStL8__ioinit
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc

这里面很多看不懂的,没有关系,只要找到这个就好:

zhaozheng@ubuntu:~/code/c++/test_compile/myinclude$ nm myhead.o |grep sum
0000000000000023 T _Z3sumii

找到了我们定义的sum函数,为毛sum函数前面有很多字符,因为c++比c多了一个很重要的机制,就是重载机制。
也就是会出现很多名字相同,但是参数不同的函数。那么编译和链接的时候,如何区分。就是靠这个。(如果文件是.c 文件,用gcc编译,你可以在看一下符号表,就不会有乱码。那么不难直到,如果c和c++相互调用,就需要用extern C 来先编译器声明一下,这是c的代码。不过这是后话了)
我们定义的是:

void sum(int ,int);

你要是好奇宝宝,问前面的z3是什么意思,这个我也不知道哎。

在来看./main

zhaozheng@ubuntu:~/code/c++/test_compile/src$ nm ./main
0000000000601068 B __bss_start
0000000000601190 b completed.7585
                 U __cxa_atexit@@GLIBC_2.2.5
0000000000601058 D __data_start
0000000000601058 W data_start
00000000004007d0 t deregister_tm_clones
0000000000400850 t __do_global_dtors_aux
0000000000600e08 t __do_global_dtors_aux_fini_array_entry
0000000000601060 D __dso_handle
0000000000600e18 d _DYNAMIC
0000000000601068 D _edata
0000000000601198 B _end
0000000000400a54 T _fini
0000000000400870 t frame_dummy
0000000000600df0 t __frame_dummy_init_array_entry
0000000000400ca0 r __FRAME_END__
0000000000601000 d _GLOBAL_OFFSET_TABLE_
000000000040093d t _GLOBAL__sub_I_main
00000000004009c7 t _GLOBAL__sub_I__Z5printv
                 w __gmon_start__
0000000000400a80 r __GNU_EH_FRAME_HDR
00000000004006d8 T _init
0000000000600e08 t __init_array_end
0000000000600df0 t __init_array_start
0000000000400a60 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000600e10 d __JCR_END__
0000000000600e10 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000400a50 T __libc_csu_fini
00000000004009e0 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400896 T main
0000000000400810 t register_tm_clones
00000000004007a0 T _start
0000000000601068 D __TMC_END__
0000000000400975 T _Z3sumii
00000000004008ff t _Z41__static_initialization_and_destruction_0ii
0000000000400989 t _Z41__static_initialization_and_destruction_0ii
0000000000400952 T _Z5printv
                 U _ZNSolsEi@@GLIBCXX_3.4
                 U _ZNSolsEPFRSoS_E@@GLIBCXX_3.4
                 U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
                 U _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
0000000000601080 B _ZSt4cout@@GLIBCXX_3.4
                 U _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@@GLIBCXX_3.4
0000000000601191 b _ZStL8__ioinit
0000000000601192 b _ZStL8__ioinit
                 U _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@@GLIBCXX_3.4

找一下sum函数

zhaozheng@ubuntu:~/code/c++/test_compile/src$ nm ./main | grep sum
0000000000400975 T _Z3sumii

另外,看一下./main 的依赖库

zhaozheng@ubuntu:~/code/c++/test_compile/src$ ldd ./main
    linux-vdso.so.1 =>  (0x00007ffdc472d000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3e90b50000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3e90787000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3e9047d000)
    /lib64/ld-linux-x86-64.so.2 (0x0000564311168000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3e90267000)

后面写不动了….
以后在补吧
累死我了。。。

    原文作者:zhaozhengcoder
    原文地址: https://www.jianshu.com/p/c682a5a23288
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞