1

我正在 Linux 上构建一个共享库 (.so),并且我正在编译和链接一个在某些函数中没有动态链接的对象。这些函数是“extern 'C'”函数。它们出现在共享对象的普通符号表中,但不在外部函数列表或动态函数列表中。我正在使用 g++ 进行编译和链接。我已经关闭了编译器优化。是否需要设置特殊标志才能使功能出现?

编辑:我用来将目标文件链接在一起的命令是这样的:

g++ -m64 -rpath,/usr/local/Trolltech/Qt-4.8.2/lib -shared -Wl,-soname,libQtCommercialChart.so.1 -o libQtCommercialChart.so.1.0.0 ../build/release/lib/chartdataset.o ../build/release/lib/chartpresenter.o ../build/release/lib/charttheme.o ../build/release/lib/domain.o ../build/release/lib/qchart.o ../build/release/lib/qchartview.o ../build/release/lib/qabstractseries.o ../build/release/lib/chartbackground.o ../build/release/lib/chartelement.o ../build/release/lib/scroller.o ../build/release/lib/chartlayout.o ../build/release/lib/versiontracker.o ../build/release/lib/axisanimation.o ../build/release/lib/xyanimation.o ../build/release/lib/pieanimation.o ../build/release/lib/piesliceanimation.o ../build/release/lib/splineanimation.o ../build/release/lib/baranimation.o ../build/release/lib/stackedbaranimation.o ../build/release/lib/percentbaranimation.o ../build/release/lib/abstractbaranimation.o ../build/release/lib/horizontalbaranimation.o ../build/release/lib/horizontalstackedbaranimation.o ../build/release/lib/horizontalpercentbaranimation.o ../build/release/lib/areachartitem.o ../build/release/lib/qareaseries.o ../build/release/lib/chartaxis.o ../build/release/lib/qabstractaxis.o ../build/release/lib/chartvalueaxisx.o ../build/release/lib/chartvalueaxisy.o ../build/release/lib/qvalueaxis.o ../build/release/lib/chartbarcategoryaxisx.o ../build/release/lib/chartbarcategoryaxisy.o ../build/release/lib/qbarcategoryaxis.o ../build/release/lib/chartcategoryaxisx.o ../build/release/lib/chartcategoryaxisy.o ../build/release/lib/qcategoryaxis.o ../build/release/lib/chartdatetimeaxisx.o ../build/release/lib/chartdatetimeaxisy.o ../build/release/lib/qdatetimeaxis.o ../build/release/lib/bar.o ../build/release/lib/abstractbarchartitem.o ../build/release/lib/qabstractbarseries.o ../build/release/lib/qbarset.o ../build/release/lib/qbarmodelmapper.o ../build/release/lib/qvbarmodelmapper.o ../build/release/lib/qhbarmodelmapper.o ../build/release/lib/qbarseries.o ../build/release/lib/barchartitem.o ../build/release/lib/qstackedbarseries.o ../build/release/lib/stackedbarchartitem.o ../build/release/lib/qpercentbarseries.o ../build/release/lib/percentbarchartitem.o ../build/release/lib/qhorizontalbarseries.o ../build/release/lib/horizontalbarchartitem.o ../build/release/lib/qhorizontalstackedbarseries.o ../build/release/lib/horizontalstackedbarchartitem.o ../build/release/lib/qhorizontalpercentbarseries.o ../build/release/lib/horizontalpercentbarchartitem.o ../build/release/lib/qlegend.o ../build/release/lib/legendmarker.o ../build/release/lib/legendlayout.o ../build/release/lib/linechartitem.o ../build/release/lib/qlineseries.o ../build/release/lib/qpieseries.o ../build/release/lib/piesliceitem.o ../build/release/lib/piechartitem.o ../build/release/lib/qpieslice.o ../build/release/lib/qpiemodelmapper.o ../build/release/lib/qvpiemodelmapper.o ../build/release/lib/qhpiemodelmapper.o ../build/release/lib/qscatterseries.o ../build/release/lib/scatterchartitem.o ../build/release/lib/qsplineseries.o ../build/release/lib/splinechartitem.o ../build/release/lib/xychart.o ../build/release/lib/qxyseries.o ../build/release/lib/qxymodelmapper.o ../build/release/lib/qvxymodelmapper.o ../build/release/lib/qhxymodelmapper.o   -L/usr/local/Trolltech/Qt-4.8.2/lib -L/tmp/qcharts/lib/release -Wl,-rpath,/tmp/qcharts/lib/release -lQtGui -L/usr/local/Trolltech/Qt-4.8.2/lib -L/usr/X11R6/lib64 -lQtCore -lpthread  

用于构建缺少功能的对象的命令是这样的:

g++ -c -m64 -pipe -fvisibility=hidden -fvisibility-inlines-hidden -O0 -Wall -W -D_REENTRANT -fPIC -DQTCOMMERCIALCHART_LIBRARY -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/local/Trolltech/Qt-4.8.2/mkspecs/linux-g++-64 -I. -I/usr/local/Trolltech/Qt-4.8.2/include/QtCore -I/usr/local/Trolltech/Qt-4.8.2/include/QtGui -I/usr/local/Trolltech/Qt-4.8.2/include -I../include -I../include -I. -Ianimations -Iareachart -Iaxis -Iaxis/valueaxis -Iaxis/barcategoryaxis -Iaxis/categoryaxis -Iaxis/datetimeaxis -Ibarchart -Ibarchart/vertical/bar -Ibarchart/vertical/stacked -Ibarchart/vertical/percent -Ibarchart/horizontal/bar -Ibarchart/horizontal/stacked -Ibarchart/horizontal/percent -Ilegend -Ilinechart -Ipiechart -Iscatterchart -Isplinechart -Ithemes -Ixychart -I../build/release/lib -o ../build/release/lib/versiontracker.o versiontracker.cpp
4

1 回答 1

4

man gcc

-fvisibility =default|internal|hidden|protected
...
extern声明不受-fvisibility影响,因此可以使用-fvisibility=hidden重新编译许多代码而无需修改。但是,这意味着对没有显式可见性的extern函数的调用将使用 PLT ,因此使用__attribute ((visibility))和/或#pragma GCC visibility告诉编译器哪些extern声明应被视为隐藏更有效.

我自己没有使用过这个,但是从GCC Wiki - Visibility和一个小例子,我会说添加

__attribute__ ((visibility ("default")))

到您的extern "C"函数,应该使它们在动态函数列表中可见,例如nm -D libQtCommercialChart.so.1.0.0.

如果你定义了很多函数,用

extern "C" {
#pragma GCC visibility push(default)
...
#pragma GCC visibility pop
};

可能更方便。

如果您不关心符号可见性,那么-fvisibility=hidden从命令行中删除当然也可以。

于 2012-12-27T23:07:08.097 回答