Linux和Windows下C++代码编译的一些基本区别

从Windows Visual Studio开发迁移到Linux GCC开发的人们,经常会遇到一些奇怪的问题,因为在Linux上面的一些行为和Windows不同,当人们习惯了Windows的行为以后,往往不会想到这些不同的地方。

在这里,我把Linux下gcc编译和Windows下VC编译不同的地方列出来,方便大家避开坑。

编译程序

Windows 下VC编译C++ 程序使用 cl.exe,链接程序使用 link.exe
Linux 下GCC编译C++ 程序使用 g++,并会链接程序,无需单独再调用链接程序。
另外GCC还有一个程序名叫gccg++ 相当于 gcc -xc++ -lstdc++ -shared-libgcc

依赖库名字

link 时,Windows下面要指定完整的lib的名称,而linux默认静态库的名字为libXXX.a,动态库为libXXX.so,因此在链接时,只需加选项 -lXXX即可。
如果Linux下面的动态库不符合这一命名规则,如test.so,则需要选项 -Wl,test.so

库依赖顺序

在Linux下,gcc命令行的链接外部库选项,如-lXXX的位置会影响链接结果。链接器按照指定的顺序搜索和处理库和对象文件。因此,如果命令行如foo.o -lz bar.o,连接器将在文件foo.o之后、bar.o之前搜索库z。如果bar.o引用z中的函数,则可能不会加载这些函数。编译错误显示为未定义的符号。

生成动态库

在Linux下gcc编译动态库时,需要使用-fPIC选项支持生成位置独立代码(PIC),才可以被可执行文件在运行时加载到适当的位置,否则可能因为无法加载而失败。

运行时动态库路径

通常,在Windows下,只要把exe文件用到的dll文件放在同一个目录,即可正常运行。无需放到PATH环境变量指定的目录下。因为Windows首先在exe文件所在目录查找dll,具体规则可以参考这个链接,更详细的规则参考这个链接。

Linux 引入了一个 rpath 的概念,即run-time search path。它规定了可执行文件在寻找.so文件时的优先路径。可以参考这个链接。

在gcc编译时,可以通过选项-Wl,-rpath=.指定到和可执行文件相同目录,或者-Wl,-rpath=./lib指定到其他目录如可执行文件所在目录下的lib目录。

rpath也可以在编译后用chrpath工具修改,详情见这个链接。

在Windows下,可以通过 Dependencies.exe 程序查看一个可执行文件依赖的库。对应于Linux,可以使用 ldd命令。

===============

其他细节想到以后,再补充。也欢迎大家留言补充。谢谢!

你可能感兴趣的:(C++,Linux,linux,windows,c++)