CMake链接错误(collect2:ld返回1退出状态) [英] CMake linking error (collect2: ld returned 1 exit status)
问题描述
下面的项目结构是一个简化的示例。
├──CMakeLists.txt
├──debug
├──CommBase
│├──Task.h
│├──Task.cpp
│├──Thread.h
│├──Thread .cpp
│└──CMakeLists.txt
├──网络
│├──TSocket.h
│├──TSocket.cpp
│├─ ─Stream_Channel.h
│├──Stream_Channel.cpp
│└──CMakeLists.txt
├──MessageDispatch
│├──Channel_Manager.h
│ ├──Channel_Manager.cpp
│├──Message_Facade.h
│├──Message_Facade.cpp
│└──CMakeLists.txt
└──DemoServer
├──CMakeLists.txt
└──main.cpp
./ CMakeLists.txt
PROJECT(DDLIB)
CMAKE_MINIMUM_REQUIRED 2.6)
MESSAGE(状态这是PROJECT_BINARY_DIR dir$ {PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH $ {PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH $ {PROJECT_BINARY_DIR})
ADD_SUBDIRECTORY(CommBase)
ADD_SUBDIRECTORY(NetWork)
ADD_SUBDIRECTORY(DemoServer)
CommBase / CMakeLists.txt
AUX_SOURCE_DIRECTORY LIB_SRC_LIST)
ADD_LIBRARY(CommBase SHARED STATIC $ {LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../ boost)
INSTALL(TARGETS CommBase CommBase
LIBRARY DESTINATION)lib
ARCHIVE DESTINATION lib)
SET(CMAKE_BUILD_TYPE Debug)
SET(CMAKE_CXX_FLAGS_DEBUG$ ENV {CXXFLAGS} -O0 -Wall -g -ggdb)
SET(CMAKE_CXX_FLAGS_RELEASE$ ENV {CXXFLAGS} -O3 -Wall)
NetWork / CMakeLists.txt
AUX_SOURCE_DIRECTORY(。LIB_SRC_LIST)
ADD_LIBRARY(NetWork SHARED STATIC $ {LIB_SRC_LIST} )
INCLUDE_DIRECTORIES(../ boost)
INSTALL(TARGETS NetWork NetWork
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
TARGET_LINK_LIBRARIES(NetWork CommBase)
SET(CMAKE_BUILD_TYPE Debug)
SET(CMAKE_CXX_FLAGS_DEBUG$ ENV {CXXFLAGS} -O0 -Wall -g -ggdb)
SET(CMAKE_CXX_FLAGS_RELEASE$ ENV {CXXFLAGS} -O3 -Wall)
MessageDispatch / CMakeLists.txt p>
AUX_SOURCE_DIRECTORY(。 LIB_SRC_LIST)
ADD_LIBRARY(MessageDispatch SHARED STATIC $ {LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../ boost)
INCLUDE_DIRECTORIES(../ CommBase)
INCLUDE_DIRECTORIES / NetWork)
ADD_DEPENDENCIES(MessageDispatch CommBase NetWork)
LINK_DIRECTORIES(/ home / cl / server / ddsvn / debug)
TARGET_LINK_LIBRARIES(MessageDispatch CommBase NetWork)
INSTALL(TARGETS MessageDispatch MessageDispatch
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
DemoServer /CMakeLists.txt
PROJECT(DDLIB)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
MESSAGE(STATUSThis is PROJECT_BINARY_DIR dir$ {PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH $ {PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH $ {PROJECT_BINARY_DIR})
AUX_SOURCE_DIRECTORY(。SRC_LIST)
ADD_EXECUTABLE(DemoServer $ {SRC_LIST})
INCLUDE_DIRECTORIES(../ boost)
INCLUDE_DIRECTORIES(../ CommBase)
INCLUDE_DIRECTORIES(../ NetWork)
INCLUDE_DIRECTORIES (../MessageDispatch)
ADD_DEPENDENCIES(DemoServer CommBase NetWork MessageDispatch)
LINK_DIRECTORIES(/ home / cl / server / ddsvn / debug)
TARGET_LINK_LIBRARIES(DemoServer CommBase NetWork MessageDispatch)
链接CXX可执行文件DemoServer
/ usr / bin / cmake -E cmake_link_script CMakeFiles / DemoServer.dir / link.txt --verbose = 1
/ usr / bin / c ++ -fPIC CMakeFiles / DemoServer.dir / stdafx.cpp.o CMakeFiles / DemoServer.dir / DemoServer.cpp.o -o DemoServer -rdynamic -lCommBase -lNetWork -lMessageDispatch
/usr/local/lib/libMessageDispatch.a(Message_Facade.cpp.o):在函数`Message_Facade :: stop( )':
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:80:未定义引用`Timer_Queue :: instance()'
/ home / cl / server / ddsvn / MessageDispatch / Message_Facade.cpp:80:未定义的引用`Timer_Queue :: stop()'
/usr/local/lib/libMessageDispatch.a(Message_Facade.cpp.o):在函数`Message_Facade :: wait()':
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:87:未定义引用`Task :: wait()'
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp :88:undefined reference to`Task :: wait()'
/usr/local/lib/libMessageDispatch.a(Acceptor_Manager.cpp.o):在函数`Stream_Acceptor'中:
/ home / cl /server/ddsvn/MessageDispatch/../NetWork/Stream_Accecptor.h:40:未定义引用`vtable for Stream_Acceptor'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o):在函数`Channel_Manager':
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:81:未定义引用`Channel_Handler ::〜Channel_Handler()'
/ usr / local / lib / libMessageDispatch。 a(Channel_Manager.cpp.o):在函数`〜Channel_Manager'中:
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:86:未定义引用`Channel_Handler ::〜Channel_Handler()'
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:86:未定义引用`Channel_Handler ::〜Channel_Handler()'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp .o):在函数`Channel_Handler'中:
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Channel_Handler.h:14:未定义引用`vtable for Channel_Handler'
/ usr /local/lib/libMessageDispatch.a(Channel_Manager.cpp.o):(.rodata._ZTI15Channel_Manager [Channel_Manager]的类型信息] + 0x28):未定义引用Channel_Handler的'typeinfo
/ usr / local / lib / libMessageDispatch .a(Message.cpp.o):在函数`Message'中:
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:49:未定义引用`Binary_Stream :: Binary_Stream(int)'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:98:未定义引用`Binary_Stream ::〜Binary_Stream()'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp :100:undefined reference to`Binary_Stream :: Binary_Stream(int)'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):在函数`Message :: resize(int)':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:187:未定义引用`Stream_Base :: resize(int)'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp :196:undefined reference to`Stream_Base :: resize(int)'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):在函数`〜Message'中:
/ home /cl/server/ddsvn/MessageDispatch/Message.cpp:203:未定义引用`Binary_Stream ::〜Binary_Stream()'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:203:undefined reference到`Binary_Stream ::〜Binary_Stream()'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):(.rodata._ZTV7Message[vtable for Message] + 0x20):未定义引用` Stream_Base :: clone_stream()'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):(.rodata._ZTI7Message[typeinfo for Message] + 0x10):未定义引用`typeinfo for Binary_Stream '
/usr/local/lib/libMessageDispatch.a(Connector_Manager.cpp.o):在函数`Stream_Connector'中:
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Stream_Connector .h:42:undefined reference to`vtable for Stream_Connector'
/usr/local/lib/libMessageDispatch.a(Context.cpp.o):在函数`Context'中:
/ home / cl / server / ddsvn / MessageDispatch / Context.cpp:15:undefined对`Dispatch_Thread :: Dispatch_Thread()'的引用
/usr/local/lib/libMessageDispatch.a(Context.cpp.o):在函数`Context: :initialize()':
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:113:未定义引用`Timer_Queue :: instance()'
/ home / cl / server / ddsvn /MessageDispatch/Context.cpp:113:未定义引用`Timer_Queue :: start()'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:116:未定义引用`Task :: activate int,int *)'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:121:未定义引用`Task :: activate(int,int *)'
/ usr / local /lib/libMessageDispatch.a(Re_Connect_Handler.cpp.o):在函数`Re_Connect_Handler :: process_re_connect(Context& int)'中:
/home/cl/server/ddsvn/MessageDispatch/Re_Connect_Handler.cpp:23:未定义对`Timer_Queue :: instance()'的引用
/home/cl/server/ddsvn/MessageDispatch/Re_Connect_Handler.cpp:23:未定义对`Timer_Queue :: schedule_timer(Smart_Ptr< Timer_Handler> ;, Time_Value const&在函数`IO_Thread'中:
/ home / cl / server / local / lib / lib / lib / lib / lib / ddsvn / MessageDispatch / IO_Thread.cpp:4:未定义引用`Task :: Task()'
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:7:未定义引用`Task ::〜 Task()'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o):在函数`〜IO_Thread':
/ home / cl / server / ddsvn / MessageDispatch / IO_Thread。 cpp:12:未定义引用`Task ::〜Task()'
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:12:未定义引用`Task ::〜Task()'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o):(.rodata._ZTI9IO_Thread[type_info for IO_Thread] + 0x10):未定义的引用`typeinfo for Task'
collect2:ld返回1退出状态
make [2]:*** [DemoServer]错误1
make [2]:离开目录`/ home / cl / server / ddsvn / DemoServer / Debug'
make [1]:dev [CMakeFiles / DemoServer.dir / all]错误2
make [1]:离开目录`/ home / cl / server / ddsvn / DemoServer / Debug'
make: *** [all]错误2
我希望这是一个非常简单的缺乏理解CMake如何处理依赖关系。这种编译没有错误,但在链接期间失败
NetWork依赖于CommBase,MessageDispatch依赖于NetWork和CommBase,我如何在DemoServer中指定
解决方案这里有几个问题,一些比其他更关键。大致按重要性排序:
-
add_library
允许您将库定义为STATIC
或SHARED
,但不能同时使用。 -
target_link_libraries
按照它们在命令中出现的顺序链接依赖关系。你应该指定从最相关到最少。因此,在您的DemoServer CMakeLists.txt中,应该TARGET_LINK_LIBRARIES(DemoServer MessageDispatch NetWork CommBase)
但是,从文档:
默认情况下,库依赖项是传递性的。当此目标链接到另一个目标时,链接到该目标的库也将出现在其他目标的链接线上。
换句话说,您应该在NetWork(您已经做),
TARGET_LINK_LIBRARIES(MessageDispatch NetWork)
中拥有TARGET_LINK_LIBRARIES(NetWork CommBase)
> -
http://www.cmake.org/cmake/help/v2.8.11/cmake.html#variable%3aCMAKE_BUILD_TYPE =nofollow>
CMAKE_BUILD_TYPE
通常由用户通过命令行(或CMake GUI)设置。它应该只能在CMakeLists.txt内部设置,如果用户还没有这样做,或者如果它被设置为无效的值。如果你设置或更改值,最好通过消息
告诉用户。您可能不应在两个不同的地方设置。 -
aux_source_directory
作为收集源文件列表的方法。建议的方法是将文件路径硬编码到CMakeLists.txt中,因此如果源列表更改,CMake会自动重新运行。 -
link_directories
很少需要,且不应包含硬编码的绝对路径。 -
target_link_libraries 指定了这些依赖关系,则不需要rel =nofollow>
add_dependencies
调用
The project structure below is a simplified example.
├── CMakeLists.txt
├── debug
├── CommBase
│ ├── Task.h
│ ├── Task.cpp
│ ├── Thread.h
│ ├── Thread.cpp
│ └── CMakeLists.txt
├── NetWork
│ ├── TSocket.h
│ ├── TSocket.cpp
│ ├── Stream_Channel.h
│ ├── Stream_Channel.cpp
│ └── CMakeLists.txt
├── MessageDispatch
│ ├── Channel_Manager.h
│ ├── Channel_Manager.cpp
│ ├── Message_Facade.h
│ ├── Message_Facade.cpp
│ └── CMakeLists.txt
└── DemoServer
├── CMakeLists.txt
└── main.cpp
./CMakeLists.txt
PROJECT(DDLIB)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir "${PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
ADD_SUBDIRECTORY(CommBase)
ADD_SUBDIRECTORY(NetWork)
ADD_SUBDIRECTORY(DemoServer)
CommBase/CMakeLists.txt
AUX_SOURCE_DIRECTORY(. LIB_SRC_LIST)
ADD_LIBRARY(CommBase SHARED STATIC ${LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INSTALL(TARGETS CommBase CommBase
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
SET( CMAKE_BUILD_TYPE Debug )
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
NetWork/CMakeLists.txt
AUX_SOURCE_DIRECTORY(. LIB_SRC_LIST)
ADD_LIBRARY(NetWork SHARED STATIC ${LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INSTALL(TARGETS NetWork NetWork
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
TARGET_LINK_LIBRARIES(NetWork CommBase)
SET( CMAKE_BUILD_TYPE Debug )
SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
MessageDispatch/CMakeLists.txt
AUX_SOURCE_DIRECTORY(. LIB_SRC_LIST)
ADD_LIBRARY(MessageDispatch SHARED STATIC ${LIB_SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INCLUDE_DIRECTORIES(../CommBase)
INCLUDE_DIRECTORIES(../NetWork)
ADD_DEPENDENCIES(MessageDispatch CommBase NetWork)
LINK_DIRECTORIES(/home/cl/server/ddsvn/debug)
TARGET_LINK_LIBRARIES(MessageDispatch CommBase NetWork)
INSTALL(TARGETS MessageDispatch MessageDispatch
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
DemoServer/CMakeLists.txt
PROJECT(DDLIB)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
MESSAGE(STATUS "This is PROJECT_BINARY_DIR dir "${PROJECT_BINARY_DIR})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
AUX_SOURCE_DIRECTORY(. SRC_LIST)
ADD_EXECUTABLE(DemoServer ${SRC_LIST})
INCLUDE_DIRECTORIES(../boost)
INCLUDE_DIRECTORIES(../CommBase)
INCLUDE_DIRECTORIES(../NetWork)
INCLUDE_DIRECTORIES(../MessageDispatch)
ADD_DEPENDENCIES(DemoServer CommBase NetWork MessageDispatch)
LINK_DIRECTORIES(/home/cl/server/ddsvn/debug)
TARGET_LINK_LIBRARIES(DemoServer CommBase NetWork MessageDispatch)
Linking CXX executable DemoServer
/usr/bin/cmake -E cmake_link_script CMakeFiles/DemoServer.dir/link.txt --verbose=1
/usr/bin/c++ -fPIC CMakeFiles/DemoServer.dir/stdafx.cpp.o CMakeFiles/DemoServer.dir/DemoServer.cpp.o -o DemoServer -rdynamic -lCommBase -lNetWork -lMessageDispatch
/usr/local/lib/libMessageDispatch.a(Message_Facade.cpp.o): In function `Message_Facade::stop()':
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:80: undefined reference to `Timer_Queue::instance()'
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:80: undefined reference to `Timer_Queue::stop()'
/usr/local/lib/libMessageDispatch.a(Message_Facade.cpp.o): In function `Message_Facade::wait()':
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:87: undefined reference to `Task::wait()'
/home/cl/server/ddsvn/MessageDispatch/Message_Facade.cpp:88: undefined reference to `Task::wait()'
/usr/local/lib/libMessageDispatch.a(Acceptor_Manager.cpp.o): In function `Stream_Acceptor':
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Stream_Accecptor.h:40: undefined reference to `vtable for Stream_Acceptor'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o): In function `Channel_Manager':
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:81: undefined reference to `Channel_Handler::~Channel_Handler()'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o): In function `~Channel_Manager':
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:86: undefined reference to `Channel_Handler::~Channel_Handler()'
/home/cl/server/ddsvn/MessageDispatch/Channel_Manager.cpp:86: undefined reference to `Channel_Handler::~Channel_Handler()'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o): In function `Channel_Handler':
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Channel_Handler.h:14: undefined reference to `vtable for Channel_Handler'
/usr/local/lib/libMessageDispatch.a(Channel_Manager.cpp.o):(.rodata._ZTI15Channel_Manager[typeinfo for Channel_Manager]+0x28): undefined reference to `typeinfo for Channel_Handler'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o): In function `Message':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:49: undefined reference to `Binary_Stream::Binary_Stream(int)'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:98: undefined reference to `Binary_Stream::~Binary_Stream()'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:100: undefined reference to `Binary_Stream::Binary_Stream(int)'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o): In function `Message::resize(int)':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:187: undefined reference to `Stream_Base::resize(int)'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:196: undefined reference to `Stream_Base::resize(int)'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o): In function `~Message':
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:203: undefined reference to `Binary_Stream::~Binary_Stream()'
/home/cl/server/ddsvn/MessageDispatch/Message.cpp:203: undefined reference to `Binary_Stream::~Binary_Stream()'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):(.rodata._ZTV7Message[vtable for Message]+0x20): undefined reference to `Stream_Base::clone_stream()'
/usr/local/lib/libMessageDispatch.a(Message.cpp.o):(.rodata._ZTI7Message[typeinfo for Message]+0x10): undefined reference to `typeinfo for Binary_Stream'
/usr/local/lib/libMessageDispatch.a(Connector_Manager.cpp.o): In function `Stream_Connector':
/home/cl/server/ddsvn/MessageDispatch/../NetWork/Stream_Connector.h:42: undefined reference to `vtable for Stream_Connector'
/usr/local/lib/libMessageDispatch.a(Context.cpp.o): In function `Context':
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:15: undefined reference to `Dispatch_Thread::Dispatch_Thread()'
/usr/local/lib/libMessageDispatch.a(Context.cpp.o): In function `Context::initialize()':
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:113: undefined reference to `Timer_Queue::instance()'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:113: undefined reference to `Timer_Queue::start()'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:116: undefined reference to `Task::activate(int, int*)'
/home/cl/server/ddsvn/MessageDispatch/Context.cpp:121: undefined reference to `Task::activate(int, int*)'
/usr/local/lib/libMessageDispatch.a(Re_Connect_Handler.cpp.o): In function `Re_Connect_Handler::process_re_connect(Context&, int)':
/home/cl/server/ddsvn/MessageDispatch/Re_Connect_Handler.cpp:23: undefined reference to `Timer_Queue::instance()'
/home/cl/server/ddsvn/MessageDispatch/Re_Connect_Handler.cpp:23: undefined reference to `Timer_Queue::schedule_timer(Smart_Ptr<Timer_Handler>, Time_Value const&, Smart_Ptr<Ref_Object>, EDispatchType, Dispatch_Thread*)'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o): In function `IO_Thread':
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:4: undefined reference to `Task::Task()'
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:7: undefined reference to `Task::~Task()'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o): In function `~IO_Thread':
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:12: undefined reference to `Task::~Task()'
/home/cl/server/ddsvn/MessageDispatch/IO_Thread.cpp:12: undefined reference to `Task::~Task()'
/usr/local/lib/libMessageDispatch.a(IO_Thread.cpp.o):(.rodata._ZTI9IO_Thread[typeinfo for IO_Thread]+0x10): undefined reference to `typeinfo for Task'
collect2: ld returned 1 exit status
make[2]: *** [DemoServer] Error 1
make[2]: Leaving directory `/home/cl/server/ddsvn/DemoServer/Debug'
make[1]: *** [CMakeFiles/DemoServer.dir/all] Error 2
make[1]: Leaving directory `/home/cl/server/ddsvn/DemoServer/Debug'
make: *** [all] Error 2
I'm hoping this is a really simple lack of understanding of how CMake handles dependencies. This compiles without error, but fails during linking
NetWork is dependent on CommBase, MessageDispatch dependent on NetWork and CommBase,how can i specify in DemoServer
There are a few issues here, some more critical than others. Roughly in order of importance:
add_library
allows you to define the library as eitherSTATIC
orSHARED
, but not both.target_link_libraries
links the dependencies in the order they appear in the command. You should specify them from most-dependent to least. So, in your DemoServer CMakeLists.txt, it should beTARGET_LINK_LIBRARIES(DemoServer MessageDispatch NetWork CommBase)
However, from the docs:
Library dependencies are transitive by default. When this target is linked into another target then the libraries linked to this target will appear on the link line for the other target too.
In other words, you should have
TARGET_LINK_LIBRARIES(NetWork CommBase)
in NetWork (you already do),TARGET_LINK_LIBRARIES(MessageDispatch NetWork)
in MessageDispatch, and justTARGET_LINK_LIBRARIES(DemoServer MessageDispatch)
for the Demo.CMAKE_BUILD_TYPE
would normally be set by the user via the command line (or CMake GUI). It should probably only be set inside the CMakeLists.txt if the user hasn't already done so, or if it's set to an invalid value. If you set or change the value, it would be good to tell the user via amessage
. You probably shouldn't be setting it in 2 different places.aux_source_directory
is not recommended as a means to gather lists of source files. The recommended way is to hard-code the file paths into your CMakeLists.txt, so if the source list changes, CMake automatically re-runs.link_directories
is rarely required, and shouldn't contain a hard-coded absolute path.LIBRARY_OUTPUT_PATH
andEXECUTABLE_OUTPUT_PATH
are deprecated.add_dependencies
is not required if you have already specified these dependencies via atarget_link_libraries
call.
这篇关于CMake链接错误(collect2:ld返回1退出状态)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!