美文网首页Linux学习|Gentoo/Arch/FreeBSDC++我用 Linux
Linux下 C++代码编译和链接文件的具体过程和分析

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

作者: DayDayUpppppp | 来源:发表于2017-02-24 15:59 被阅读336次

先写两个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)

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

相关文章

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

    先写两个linux的命令,一个nm命令 nm命令被用于显示二进制目标文件的符号表 ldd 命令 ldd命令用于打印...

  • Makefile小结

    一、程序的编译和链接c、c++都需要将源文件(src)编译成中间代码文件(ubuntu下面是.o),这个过程叫编译...

  • 编译与执行?

    编译:包括编译和链接两个过程。广义而言把代码转换成可执行文件。具体来说,编译部分是把app的程序源文件(代码)转换...

  • C语言多文件编译 gcc 与 Cmake

    关于编译和链接 一般来说,无论是C、C++,首先要把源文件编译成中间代码文件,在Windows下也就是.obj文件...

  • Linux C/C++动态库加载位置

    在Linux环境下编译链接C/C++项目,经常需要加载动态库,包括系统默认的库和外部的库。具体来说,加载库可能会在...

  • 深入理解目标文件

    1. 概述 目标文件是指源代码经过编译后没有被链接的那些中间文件(Linux下的.o)。因为目标文件的内容和结构与...

  • C++的编译总结

    一、C++编译过程概述 不管是Linux系统还是Windows系统,C++源文件的编译流程都是一样的,只是编译过程...

  • 在Linux中如何运行c++文件

    在Linux中如何运行c++文件 首先安装必要的工具和编译器来运行代码。 gcc(GNU编译器套件)简介: GNU...

  • 目标文件、ELF文件的一点小总结 《程序员的自我修养》·笔记

    目标文件 源代码编译后但是没有进行链接的那些中间文件,比如win下的.obj文件、linux下的.o文件,与可执行...

  • 可执行程序的装载

    曹朋辉原创作品转载请注明出处《Linux内核分析》MOOC课程 可执行文件的创建——预处理、编译和链接 静态链接和...

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/fijwwttx.html