在编译时链接vs在运行时链接到std ::库

问题描述:

首先问题: 我需要一种方法,而不在/etc/ld.so.conf.d中放置配置文件,以允许客户端根据我的SDK构建RHEL5.7和RHEL6.1都使用默认安装的gcc。在这种情况下,设置LD_LIBRARY_PATH不起作用。有没有其他方法可以让客户与我的SDK链接,而无需向他们提供关于如何配置他们的系统的知识库文章?请阅读下面的说明。在编译时链接vs在运行时链接到std ::库

秒塞纳里奥:

我负责两个RHEL5和RHEL6运行时SDK的版本。我的RHEL5.7盒子和我的RHEL6.1盒子一样是标准的非注册安装。然而,在我的RHEL6箱我编的gcc自己:

[[email protected] ~]$ cat /etc/redhat-release; gcc --version 
Red Hat Enterprise Linux Server release 5.7 (Tikanga) 
gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-51) 
Copyright (C) 2006 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOS 

-

[[email protected] session2]$ cat /etc/redhat-release; gcc --version 
Red Hat Enterprise Linux Server release 6.1 (Santiago) 
gcc (GCC) 4.5.2 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE 

-

我不能提供的。所以,我试图来链接.a文件。但是,我会试图描述发生的事情。采取相同的来源,并对我的SDK构建并运行它。我得到如下结果:

RHEL 6盒:

[[email protected] session2]$ ls -l 
total 1848 
-rw-rw-r-- 1 mehoggan mehoggan  189 Nov 3 13:02 main.cpp 
-rw-rw-r-- 1 mehoggan mehoggan  845 Nov 3 13:02 mainwindow.cpp 
-rw-rw-r-- 1 mehoggan mehoggan  288 Nov 3 13:02 mainwindow.h 
-rwxrwxr-x 1 mehoggan mehoggan 25818 Nov 4 09:26 Session2 
-rw-rw-r-- 1 mehoggan mehoggan  649 Nov 3 13:02 Session2.pro 
-rw-rw-r-- 1 mehoggan mehoggan 1847296 Nov 3 13:02 vc90.pdb 
[[email protected] session2]$ qmake 
[[email protected] session2]$ cat Session2.pro 
#------------------------------------------------- 
# 
# Project created by QtCreator 2011-10-21T09:32:55 
# 
#------------------------------------------------- 

QT += core gui 

TARGET = Session2 
TEMPLATE = app 


SOURCES += main.cpp\ 
     mainwindow.cpp 

HEADERS += mainwindow.h 

#Modify the path accordingly 
CONFIG += debug_and_release 
INCLUDEPATH += "/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/include" 
CONFIG(debug, debug|release) { 
    LIBS += -L"/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin" \ 
      -lArcGISQtd 
} else { 
    LIBS += -L"/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin" \ 
      -lArcGISQt 
} 
[[email protected] session2]$ make 
make -f Makefile.Release 
make[1]: Entering directory `/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/workshops/session2' 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease -o release/main.o main.cpp 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease -o release/mainwindow.o mainwindow.cpp 
/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/bin/moc -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease mainwindow.h -o release/moc_mainwindow.cpp 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease -o release/moc_mainwindow.o release/moc_mainwindow.cpp 
g++ -m64 -Wl,-O1 -Wl,-rpath,/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/lib -o Session2 release/main.o release/mainwindow.o release/moc_mainwindow.o -L/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/lib -L/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin -lArcGISQt -lQtGui -lQtCore -lpthread 
make[1]: Leaving directory `/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/workshops/session2' 
[[email protected] session2]$ echo ${LD_LIBRARY_PATH} 
/home/mehoggan/arcgis/runtime_sdk/qt10.1/ArcGISRuntime10.1/LocalServerLx/bin/wine/lib64:/home/mehoggan/arcgis/runtime_sdk/qt10.1/ArcGISRuntime10.1/LocalServerLx/bin/wine/lib64/wine:/home/mehoggan/arcgis/runtime_sdk/qt10.1/ArcGISRuntime10.1/LocalServerLx/bin/wine/lib64/wine/supp:/home/mehoggan/arcgis/runtime_sdk/qt10.1/ArcGISRuntime10.1/LocalServerLx/bin/wine/lib64:/home/mehoggan/arcgis/runtime_sdk/qt10.1/ArcGISRuntime10.1/LocalServerLx/bin/wine/lib64/wine:/home/mehoggan/arcgis/runtime_sdk/qt10.1/ArcGISRuntime10.1/LocalServerLx/bin/wine/lib64/wine/supp: 
[[email protected] session2]$ ./Session2 
./Session2: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by /home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin/libArcGISQt.so.1) 

如果我运行下面的命令:export LD_LIBRARY_PATH=/usr/local/lib64:${LD_LIBRARY_PATH}; ./Session2或设置路径的libstdc编译版本++中/etc/ld.so.conf.d应用程序运行。

RHEL5盒:

[[email protected] session2]$ ls -l 
total 1852 
-rw-rw-r-- 1 mehoggan mehoggan  189 Nov 3 15:21 main.cpp 
-rw-rw-r-- 1 mehoggan mehoggan  845 Nov 3 15:21 mainwindow.cpp 
-rw-rw-r-- 1 mehoggan mehoggan  288 Nov 3 15:21 mainwindow.h 
-rw-rw-r-- 1 mehoggan mehoggan  649 Nov 3 15:21 Session2.pro 
-rw-rw-r-- 1 mehoggan mehoggan 25151 Nov 3 15:51 Session2.pro.user 
-rw-rw-r-- 1 mehoggan mehoggan 1847296 Nov 3 15:21 vc90.pdb 
[[email protected] session2]$ qmake 
[[email protected] session2]$ ls -l ./Session2.pro 
-rw-rw-r-- 1 mehoggan mehoggan 649 Nov 3 15:21 ./Session2.pro 
[[email protected] session2]$ cat ./Session2.pro 
#------------------------------------------------- 
# 
# Project created by QtCreator 2011-10-21T09:32:55 
# 
#------------------------------------------------- 

QT += core gui 

TARGET = Session2 
TEMPLATE = app 


SOURCES += main.cpp\ 
     mainwindow.cpp 

HEADERS += mainwindow.h 

#Modify the path accordingly 
CONFIG += debug_and_release 
INCLUDEPATH += "/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/include" 
CONFIG(debug, debug|release) { 
    LIBS += -L"/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin" \ 
      -lArcGISQtd 
} else { 
    LIBS += -L"/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin" \ 
      -lArcGISQt 
} 
[[email protected] session2]$ make 
make -f Makefile.Release 
make[1]: Entering directory `/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/workshops/session2' 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease -o release/main.o main.cpp 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease -o release/mainwindow.o mainwindow.cpp 
/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/bin/moc -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease mainwindow.h -o release/moc_mainwindow.cpp 
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/mkspecs/default -I. -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtCore -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include/QtGui -I/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/include -I../../include -Irelease -o release/moc_mainwindow.o release/moc_mainwindow.cpp 
g++ -m64 -Wl,-O1 -Wl,-rpath,/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/lib -o Session2 release/main.o release/mainwindow.o release/moc_mainwindow.o -L/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/lib -L/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin -lArcGISQt -lQtGui -lQtCore -lpthread 
/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/lib/libQtGui.so: undefined reference to `FT_Library_SetLcdFilter' 
/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin/libArcGISQt.so: undefined reference to `std::_List_node_base::_M_unhook()@GLIBCXX_3.4.14' 
/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin/libArcGISQt.so: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)@GLIBCXX_3.4.9' 
/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin/libArcGISQt.so: undefined reference to `std::_List_node_base::_M_hook(std::_List_node_base*)@GLIBCXX_3.4.14' 
/home/mehoggan/QtSDK/Desktop/Qt/474/gcc/lib/libQtGui.so: undefined reference to `FcFreeTypeQueryFace' 
/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin/libArcGISQt.so: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<double>(double)@GLIBCXX_3.4.9' 
/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/bin/libArcGISQt.so: undefined reference to `std::ctype<char>::_M_widen_init() [email protected]X_3.4.11' 
collect2: ld returned 1 exit status 
make[1]: *** [Session2] Error 1 
make[1]: Leaving directory `/home/mehoggan/arcgis/runtime_sdk/qt10.1/SDK/workshops/session2' 
make: *** [release] Error 2 

这越来越成为一个很长的帖子,我想我已经提供了足够的启动帮助。如果您需要任何特定的帮助,请告诉我。

关于我链接的libstdC++的最后一点信息。

RHEL6: 
[[email protected] session2]$ strings /usr/local/lib64/libstdc++.so.6 | grep GLIB 
GLIBCXX_3.4 
GLIBCXX_3.4.1 
GLIBCXX_3.4.2 
GLIBCXX_3.4.3 
GLIBCXX_3.4.4 
GLIBCXX_3.4.5 
GLIBCXX_3.4.6 
GLIBCXX_3.4.7 
GLIBCXX_3.4.8 
GLIBCXX_3.4.9 
GLIBCXX_3.4.10 
GLIBCXX_3.4.11 
GLIBCXX_3.4.12 
GLIBCXX_3.4.13 
GLIBCXX_3.4.14 
GLIBC_2.2.5 
GLIBC_2.3 
GLIBC_2.3.2 
GLIBCXX_FORCE_NEW 
GLIBCXX_DEBUG_MESSAGE_LENGTH 

RHEL5:

[[email protected] session2]$ strings /usr/lib64/libstdc++.so.6 | grep GLIBC 
GLIBCXX_3.4 
GLIBCXX_3.4.1 
GLIBCXX_3.4.2 
GLIBCXX_3.4.3 
GLIBCXX_3.4.4 
GLIBCXX_3.4.5 
GLIBCXX_3.4.6 
GLIBCXX_3.4.7 
GLIBCXX_3.4.8 
GLIBC_2.3 
GLIBC_2.3.2 
GLIBC_2.4 
GLIBC_2.2.5 
GLIBCXX_FORCE_NEW 

它看起来像你的Qt库(libQtGui.so和libArcGISQt​​.so)对GLIBCXX_3.4.14的依赖,这是不存在的RHEL 5中,可能就像你在RHEL 6盒子上构建并安装它(Qt)一样。您需要在RHEL 5上构建Qt,或者在RHEL 5框中提供对更新后的3.4.14 lib的访问。任何想运行二进制文件的人都需要访问它所针对的共享库的正确版本。

为了能够访问库,它需要在有问题的计算机上可读,并且位于ld.so.conf中配置的位置,在应用程序的LD_LIBRARY_PATH envvar中运行,或通过-rpath链接选项配置为可执行文件。

我发现一个链接选项非常有用,用于避免/处理此问题是-Wl,-rpath,'$ORIGIN'。这将导致应用程序查看包含动态库可执行文件的目录以及ld.so.conf(并优先于)。因此,您可以构建一个可执行文件并为其提供一个包含可执行文件和一堆.so动态库的包,并告诉他们“要么将.so文件安装在您的机器上,要么将它们全部放在与可执行文件相同的目录中,无论您喜欢哪一个“然后他们可以运行可执行文件,而不会有太多麻烦。这允许使用几乎任何Linux变体的单个二进制包。

注意,当你把这个选项在Makefile中通常需要将-Wl,-rpath,'$$ORIGIN'作为补充将把$作为变量扩展($$扩展到$)。 qmake可能是一样的。