在CMAKE中链接自定义外部库

时间:2017-07-19 16:49:22

标签: cmake qt5

有一个项目,当构建项目时,项目的链接库存在问题。 如果有人告诉我如何解决这个问题,我将非常感激。 据我所知,问题出在图书馆的正确位置。因此,在构建与项目正确链接的项目时。

这是项目文件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

提前致谢。 很长一段时间我都无法理解如何解决这个问题。

3 个答案:

答案 0 :(得分:0)

如果您已编写并已安装NetworkCommunication,请考虑在程序包中包含FindNetworkCommunication.cmake文件。该文件应该包含一个查找NetworkCommunication的方法,如下所示:

# 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 是一个由维护使用的独立库,但您打算让其他几个库也使用它,这是一个很好的解决方案。如果 NetworkCommunication 是与维护相同的项目解决方案的一部分,并且实际上只是要链接到一个项目,那么可能有更简单的解决方案。

答案 1 :(得分:0)

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

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

有许多类似的库用于另一个项目,我像

一样链接
U_LIBS += NetworkCommunication \
    Logging \
    UnitController \
    TherapyRunnersController \
    GenersControllerCommon

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

答案 2 :(得分:0)

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

因为如果你比较这个选项

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

来自QtCreator项目文件maintenance.pro并为每个库编写模块,与* .pro

中的2行相比,结果非常奇怪和困难