我有以下三個項目:鏈接未解決的符號的共享庫在Linux上
Host
:由加載的運行時庫:一個導出一個全局變量(聲明爲extern)Plugin
可執行Host
和引用全球變量Tool
:一個可執行文件鏈接到Plugin
並使用它的一些功能。它不以任何方式引用全局變量。
現在,如果我在Windows上構建這一切都很好。 Tool
將只鏈接到Plugin
的導出庫,並且不會嘗試解析全局變量。
在linux上,我遇到了一個問題。 Tool
嘗試鏈接到Plugin
.so庫(因爲沒有導出庫),並且會找到它無法解析的全局變量的引用Host
。
如何解決這個問題?
編輯:
下面是使用C進行的問題可編譯例子。
的CMakeLists.txt
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/bin")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/bin")
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ADD_SUBDIRECTORY(Host)
ADD_SUBDIRECTORY(Plugin)
ADD_SUBDIRECTORY(Tool)
主機/ Host.h
#ifndef HOST_H
#define HOST_H
#ifdef _MSC_VER
#ifdef COMPILE_HOST
#define HOST_EXPORT __declspec(dllexport)
#else
#define HOST_EXPORT __declspec(dllimport)
#endif
#else
#define HOST_EXPORT
#endif
class HOST_EXPORT Host
{
public:
int getAnswer();
};
extern HOST_EXPORT Host g_host;
#endif
主機/ Host.cpp
#include "Host.h"
#include "../Plugin/Plugin.h"
#include <iostream>
Host g_host;
int Host::getAnswer()
{
return 42;
}
int main()
{
std::cout << g_host.getAnswer() << std::endl;
// load plugin and use it
}
主機/的CMakeLists.txt
PROJECT(Host)
ADD_EXECUTABLE(Host Host.cpp Host.h)
ADD_DEFINITIONS(-DCOMPILE_HOST)
SET_TARGET_PROPERTIES(Host PROPERTIES ENABLE_EXPORTS ON)
插件/ Plugin.h
#ifndef PLUGIN_H
#define PLUGIN_H
class Plugin
{
public:
Plugin();
};
#endif
插件/ Plugin.cpp
#include "Plugin.h"
#include "../Host/Host.h"
#include <iostream>
Plugin::Plugin()
{
std::cout << g_host.getAnswer() << std::endl;
}
插件/ PluginFunc.h
#ifndef PLUGINFUNC_H
#define PLUGINFUNC_H
#ifdef _MSC_VER
#define PLUGIN_EXPORT __declspec(dllexport)
#else
#define PLUGIN_EXPORT
#endif
namespace plug
{
int PLUGIN_EXPORT getRandomNumber();
}
#endif
插件/ PluginFunc.cpp
#include "PluginFunc.h"
int plug::getRandomNumber()
{
return 4;
}
插件/的CMakeLists.txt
PROJECT(Plugin)
ADD_LIBRARY(Plugin SHARED Plugin.cpp Plugin.h PluginFunc.cpp PluginFunc.h)
TARGET_LINK_LIBRARIES(Plugin Host)
工具/ Tool.cpp
#include "../Plugin/PluginFunc.h"
#include <iostream>
int main()
{
std::cout << plug::getRandomNumber() << std::endl;
}
工具/ CMakeLists。TXT
PROJECT(Tool)
ADD_EXECUTABLE(Tool Tool.cpp)
TARGET_LINK_LIBRARIES(Tool Plugin)
在Windows上建立和運行。 Host.exe顯示「42」,而Tool.exe顯示「4」。
在Linux上,我得到以下鏈接錯誤:
[email protected]:~/vbox/testlink/build$ make
Scanning dependencies of target Host
[ 25%] Building CXX object Host/CMakeFiles/Host.dir/Host.o
Linking CXX executable Host
[ 25%] Built target Host
Scanning dependencies of target Plugin
[ 50%] Building CXX object Plugin/CMakeFiles/Plugin.dir/Plugin.o
[ 75%] Building CXX object Plugin/CMakeFiles/Plugin.dir/PluginFunc.o
Linking CXX shared library libPlugin.so
[ 75%] Built target Plugin
Scanning dependencies of target Tool
[100%] Building CXX object Tool/CMakeFiles/Tool.dir/Tool.o
Linking CXX executable Tool
../Plugin/libPlugin.so: undefined reference to `Host::getAnswer()'
../Plugin/libPlugin.so: undefined reference to `g_host'
collect2: error: ld returned 1 exit status
make[2]: *** [Tool/Tool] Error 1
make[1]: *** [Tool/CMakeFiles/Tool.dir/all] Error 2
make: *** [all] Error 2
你可以發佈一些代碼/構建腳本,以便我們可以看到如何在Win/Linux上構建? – txtechhelp
@txtechhelp我用一個完整的例子更新了我的問題。 – typ1232
靜態鏈接到可執行文件非常傳統。爲什麼你需要這樣做,我們只是好奇而已? – ComicSansMS