cc(C ++)中-h <name>和-o <outputfile>选项之间的区别

我正在构build.so库,并想知道 – 有什么区别b / w -h和-o cc编译器选项(使用Sun Studio C ++)?

他们不是指同一件事 – 输出文件的名称?

-o是编译器将写入磁盘的文件的名称

-h是将被记录在与该文件链接的ELF二进制文件中的名称。

一个常见的用途是提供库的次要版本号。 例如,如果你正在创建共享库libfoo,你可以这样做:

 cc -o libfoo.so.1.0 -h libfoo.so.1 *.o ln -s libfoo.so.1.0 libfoo.so.1 ln -s libfoo.so libfoo.so.1 

然后,如果你编译你的世界应用程序,并与它链接

 cc -o hello -lfoo 

hello的elf二进制文件会记录libfoo.so.1一个NEEDED条目(你可以通过运行elfdump -d hello来查看)。

然后,当你以后需要添加新的函数时,可以将-o值改为libfoo.so.1.1而将-h放在libfoo.so.1 – 所有使用1.0 libfoo.so.1的程序仍然会尝试加载libfoo.so.1在运行时,所以继续工作而不被重建,但是你会通过ls看到它是1.1。

如果您没有单独的安装目录或通过打包系统进行安装,则在运行时使用相同目录中的库时,有时也会使用这种方法。 为了避免当你重写库二进制文件时运行的程序崩溃,并且为了避免程序无法在构建过程中启动,一些Makefiles将执行:

 cc -o libfoo.so.1.new -h libfoo.so.1 *.o rm libfoo.so.1 ; mv libfoo.so.1.new libfoo.so.1 

(由X的旧Imake makefile生成器生成的Makefiles通常会这样做。)

他们指的是不同的名字。 具体来说, -o选项是文件的实际名称 – 文件系统上的名称。 -h选项在最终的目标文件中设置内部 DT_SONAME 。 这是共享对象由其他模块内部引用的名称。 我相信这是你在链接到它的对象上运行ldd时也能看到的名字。

-o选项将命名输出文件,而-h选项将在库中设置内部名称。 该内在名称在动态加载器使用时优先于文件名,并允许其使用预定义的规则来查看正确的库。

你可以看到用这个命令记录到一个给定的库中的内在名字:

elfdump -d xxx.so | grep SONAME

看看这里的细节:

http://docs.oracle.com/cd/E23824_01/html/819-0690/chapter4-97194.html