与 CMAKE 中的自定义外部库链接



有一个项目,当构建项目时,链接到该项目的库有问题。 如果有人告诉我如何解决这个问题,我将不胜感激。 据我了解,问题出在库的正确位置。这样在构建项目时正确链接它。

这是项目文件 CmakeList

cmake_minimum_required(VERSION 3.5.1)
project(maintenance)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC OFF)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Charts REQUIRED)
find_package(Qt5Xml REQUIRED)
find_package(Qt5Network REQUIRED)
include_directories(../../088)
#include(FindPackageHandleStandardArgs)
#find_library(Network_LIBRARY NAMES NetworkCommunication PATHS ../../088/build-libs-ubuntu-Release)
#find_package_handle_standard_args(Network DEFAULT_MSG Network_LIBRARY)
add_library(NetworkCommunication SHARED IMPORTED)
set_property(TARGET NetworkCommunication PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/../../088/build-libs-ubuntu-Release/libNetworkCommunication.so)
set(Network_LIBRARY NetworkCommunication)
#link_directories(${CMAKE_CURRENT_LIST_DIR}/../../088/build-libs-ubuntu-Release)
qt5_add_resources(RCC_RESOURCES resources.qrc)
file(GLOB SOURCE_FILES_2
${CMAKE_CURRENT_SOURCE_DIR}/cop/*.h
${CMAKE_CURRENT_SOURCE_DIR}/cop/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/curves/*.h
${CMAKE_CURRENT_SOURCE_DIR}/curves/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/curves/shapes/*.h
${CMAKE_CURRENT_SOURCE_DIR}/curves/shapes/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/general/*.h
${CMAKE_CURRENT_SOURCE_DIR}/general/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/load_cells/*.h
${CMAKE_CURRENT_SOURCE_DIR}/load_cells/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/motors/*.h
${CMAKE_CURRENT_SOURCE_DIR}/motors/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/passive_mode/*.h
${CMAKE_CURRENT_SOURCE_DIR}/passive_mode/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/settings/*.h
${CMAKE_CURRENT_SOURCE_DIR}/settings/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/system/*.h
${CMAKE_CURRENT_SOURCE_DIR}/system/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../Gener095/Messages/*.h
${CMAKE_CURRENT_SOURCE_DIR}/../Gener095/Messages/*.cpp
)
set(SOURCE_FILES
Error.cpp
Error.hpp
main.cpp
MainWindow.cpp
MainWindow.h
NetworkCommunicator.cpp
NetworkCommunicator.h
Utils.cpp
Utils.h
ITab.h
)
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${SOURCE_FILES_2} ${RCC_RESOURCES})
#target_link_libraries(${PROJECT_NAME} ${Network_LIBRARY})
target_link_libraries(${PROJECT_NAME} NetworkCommunication)
target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::Core Qt5::Gui Qt5::Charts Qt5::Xml Qt5::Network)
include(../../088/BuildUtilities/scripts/lib_setup.cmake)

并记录错误

...
[ 95%] Building CXX object CMakeFiles/maintenance.dir/qrc_resources.cpp.o
[ 97%] Building CXX object CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o
[100%] Linking CXX executable maintenance
CMakeFiles/maintenance.dir/MainWindow.cpp.o: In function `MainWindow::MainWindow(QMainWindow*)':
/media/blinct/free1/QtProjects/Applications/095/maintenance/MainWindow.cpp:74: undefined reference to `TenzGraphTab::TenzGraphTab(QWidget*)'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o: In function `AngleSensors::qt_static_metacall(QObject*, QMetaObject::Call, int, void**)':
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:92: undefined reference to `AngleSensors::OnSetNullPosition()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:93: undefined reference to `AngleSensors::OnResetAccel()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:94: undefined reference to `AngleSensors::OnDataReceived(QString, QMap<QString, QVariant>)'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:95: undefined reference to `AngleSensors::OnHandleUp()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:96: undefined reference to `AngleSensors::OnHandleDown()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:97: undefined reference to `AngleSensors::OnHandleReleased()'
/media/blinct/free1/QtProjects/Applications/095/maintenance/cmake-build-debug/maintenance_autogen/ECUKZBRF6L/moc_AngleSensors.cpp:98: undefined reference to `AngleSensors::OnHandleTimer()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x28): undefined reference to `AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x30): undefined reference to `AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x1c0): undefined reference to `non-virtual thunk to AngleSensorColumn::~AngleSensorColumn()'
CMakeFiles/maintenance.dir/maintenance_autogen/moc_compilation.cpp.o:(.data.rel.ro._ZTV17AngleSensorColumn[_ZTV17AngleSensorColumn]+0x1c8): undefined reference to `non-virtual thunk to AngleSensorColumn::~AngleSensorColumn()'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlSerialPortImpl::setRequestToSend(bool)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `g_sVersion_NetworkCommunication'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlUdpSocketImpl::writeDatagram(QByteArray const&, QHostAddress const&, unsigned short)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::isListening() const'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlFileImpl::close()'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::hasPendingConnections() const'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpSocketImpl::connectToHost(QHostAddress const&, unsigned short)'
...
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlUdpSocketImpl::readDatagram(char*, long long, QHostAddress*, unsigned short*)'
../../../088/build-libs-ubuntu-Release/libNetworkCommunication.so: undefined reference to `BtlTcpServerImpl::close()'
collect2: error: ld returned 1 exit status
CMakeFiles/maintenance.dir/build.make:936: recipe for target 'maintenance' failed
make[3]: *** [maintenance] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/maintenance.dir/all' failed
make[2]: *** [CMakeFiles/maintenance.dir/all] Error 2
CMakeFiles/Makefile2:79: recipe for target 'CMakeFiles/maintenance.dir/rule' failed
make[1]: *** [CMakeFiles/maintenance.dir/rule] Error 2
Makefile:118: recipe for target 'maintenance' failed
make: *** [maintenance] Error 2

提前谢谢。 很长一段时间我都不明白如何解决这个问题。

如果 NetworkCommunication 是您编写并已安装的内容,请考虑在包中包含FindNetworkCommunication.cmake文件。该文件应包含查找网络通信的方法,如下所示:

# Sets NetworkCommunication_FOUND if found.
#
# If NetworkCommunication_FOUND is TRUE, then the following variables are also
# set: 
#
#    NetworkCommunication_LIBRARY      - Full path to library to link
#    NetworkCommunication_INCLUDE_DIR  - Path to include directory
#
# $NetworkCommunicationDIR is an environment variable that would correspond to the
# ./configure --prefix=$NetworkCommunicationDIR used in building NetworkCommunication.
#
find_path(NetworkCommunication_INCLUDE_DIR NetworkCommunication.h
HINTS
ENV NetworkCommunicationDIR
PATH_SUFFIXES include/NetworkCommunication include/NetworkCommunication include
PATHS
/opt/local
[HKEY_LOCAL_MACHINE\SOFTWARE\Alexey\NetworkCommunication\1.00.0000;InstallDir]
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(_NetworkCommunication_ARCH_DIR libs/Win64)
else()
set(_NetworkCommunication_ARCH_DIR libs/Win32)
endif()
find_library(NetworkCommunication_LIBRARY
NAMES NetworkCommunication
HINTS
ENV NetworkCommunicationDIR
PATH_SUFFIXES lib64 lib libs64 libs ${_NetworkCommunication_ARCH_DIR}
PATHS
/opt/local
[HKEY_LOCAL_MACHINE\SOFTWARE\Alexey\NetworkCommunication\1.00.0000;InstallDir]
)
unset(_NetworkCommunication_ARCH_DIR)
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NetworkCommunication  DEFAULT_MSG  NetworkCommunication_LIBRARY NetworkCommunication_INCLUDE_DIR)
mark_as_advanced(NetworkCommunication_LIBRARY NetworkCommunication_INCLUDE_DIR)

FindNetworkCommunication.cmake复制到 cmake 安装的模块文件夹 (/usr/share/cmake-3.8/Modules( 或将其复制到本地文件夹并在${CMAKE_MODULES_PATH}中包含该文件夹的路径。

接下来,在维护项目的CMakeLists.txt文件中,在add_executable后添加以下内容

Find_Package(NetworkCommunication REQUIRED)
if (NetworkCommunication_FOUND)
target_include_directories(${PROJECT_NAME} ${NetworkCommunication_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${NetworkCommunication_LIBRARY})
endif (NetworkCommunication_FOUND)

如果NetworkCommunication是一个由维护使用的独立库,但您也打算将其由其他几个库使用,这是一个很好的解决方案。 如果网络通信是与维护相同的项目解决方案的一部分,并且实际上只意味着链接到一个项目,那么可能有更简单的解决方案。

在Qt Creator的 maintenance.pro 中,我有这个库的链接

U_LIB_DIR_PREFIX += ../../088/build-libs
U_LIBS += NetworkCommunication

另一个项目有很多类似的库,我链接了这样的

U_LIBS += NetworkCommunication 
Logging 
UnitController 
TherapyRunnersController 
GenersControllerCommon

所有这些库都是作为动态库构建的。在此之后,我将这个库链接到项目。

也许还有另一种方法可以将库链接到项目?

因为如果你比较这个选项

U_LIB_DIR_PREFIX += ../../088/build-libs-ubuntu-Release
U_LIBS += NetworkCommunication

从 QtCreator 项目文件 maintenance.pro 并为每个库编写一个模块,与 *.pro 中的 2 行相比,结果非常奇怪和困难

最新更新