Linux Cmake target_link_libraries 没有链接我的库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5395578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 00:33:37  来源:igfitidea点击:

Cmake target_link_libraries not linking my library

c++linuxlinkercmakekdevelop

提问by j4x

I'll begin stating that I'm almost complete dumb in Cmake matter.

我将开始说明我在 Cmake 问题上几乎完全愚蠢。

I have the following CMakeLists.txtfor a Kdevelop 4.1 project:

CMakeLists.txt对于 Kdevelop 4.1 项目,我有以下内容:

project(uart)

find_package(KDE4 REQUIRED)
include (KDE4Defaults)

include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} src/include src/include/QSerialDevce )

add_subdirectory(doc)
add_subdirectory(src)
add_subdirectory(icons)

link_directories(/usr/lib)

find_library(SERIALDEVICE_LIB qserialdeviced)

add_executable(uart ${uart_SRCS})
target_link_libraries(uart ${SERIALDEVICE_LIB})

When I try to build my project I see:

当我尝试构建我的项目时,我看到:

uart/build> make -j2
-- Found Qt-Version 4.6.3 (using /usr/bin/qmake-qt4)
-- Found X11: /usr/lib64/libX11.so
-- Found KDE 4.5 include dir: /usr/include/kde4
-- Found KDE 4.5 library dir: /usr/lib64/kde4/devel
-- Found the KDE4 kconfig_compiler4 preprocessor: /usr/bin/kconfig_compiler4
-- Found automoc4: /usr/bin/automoc4
CMake Error at CMakeLists.txt:16 (add_executable):
  add_executable called with incorrect number of arguments


CMake Error: Attempt to add link library "/usr/lib/libqserialdeviced.so" to target "uart" which is not built by this project.
-- Configuring incomplete, errors occurred!
make: *** [cmake_check_build_system] Error 1
*** Failed ***

Everything I read says that add_executableand target_link_librariesshould look like the last two lines of my file:

我读到的所有内容都说明了这一点,add_executable并且target_link_libraries看起来应该像我文件的最后两行:

add_executable(uart ${uart_SRCS})
target_link_libraries(uart ${SERIALDEVICE_LIB})

If I change those two lines of CMakeLists.txtleaving it as:

如果我将这两行更改CMakeLists.txt为:

project(uart)

find_package(KDE4 REQUIRED)
include (KDE4Defaults)

include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} src/include src/include/QSerialDevce )

add_subdirectory(doc)
add_subdirectory(src)
add_subdirectory(icons)

link_directories(/usr/lib)

find_library(SERIALDEVICE_LIB qserialdeviced)

target_link_libraries(${SERIALDEVICE_LIB})

I see:

我懂了:

uart/build> make -j2
-- Found Qt-Version 4.6.3 (using /usr/bin/qmake-qt4)
-- Found X11: /usr/lib64/libX11.so
-- Found KDE 4.5 include dir: /usr/include/kde4
-- Found KDE 4.5 library dir: /usr/lib64/kde4/devel
-- Found the KDE4 kconfig_compiler4 preprocessor: /usr/bin/kconfig_compiler4
-- Found automoc4: /usr/bin/automoc4
-- Configuring done
-- Generating done
-- Build files have been written to: uart/build
[ 11%] Built target doc-handbook
[ 11%] Built target uart_automoc
Linking CXX executable uart
CMakeFiles/uart.dir/uart.o: In function `uart::setupSerial()':
uart/src/uart.cpp:126: undefined reference to `AbstractSerial::AbstractSerial(QObject*)'
CMakeFiles/uart.dir/uart.o: In function `uart::setupEnumerator()':
uart/src/uart.cpp:108: undefined reference to `SerialDeviceEnumerator::SerialDeviceEnumerator(QObject*)'
CMakeFiles/uart.dir/uart.o: In function `uart::setupSerial()':
uart_/uart/src/uart.cpp:136: undefined reference to `AbstractSerial::enableEmitStatus(bool)'
CMakeFiles/uart.dir/uart.o: In function `uart::setupEnumerator()':
uart_/uart/src/uart.cpp:112: undefined reference to `SerialDeviceEnumerator::setEnabled(bool)'
collect2: ld returned 1 exit status
make[2]: *** [src/uart] Error 1
make[1]: *** [src/CMakeFiles/uart.dir/all] Error 2
make: *** [all] Error 2
*** Failed ***

That clearly shows that target_link_librariesis not linking my qserialdeviced.

这清楚地表明这target_link_libraries并没有将我的qserialdeviced.

qserialdevicedis at /usr/lib/libqserialdeviced.so.1.0.0, correctly simlinked to /usr/lib/libqserialdeviced.soand easily found if I manually add it in the Makefile.

qserialdeviced如果我手动将它添加到 Makefile中/usr/lib/libqserialdeviced.so.1.0.0,则正确地链接到/usr/lib/libqserialdeviced.so并且很容易找到。

I obviously tried:

我显然尝试过:

target_link_libraries(-lqserialdeviced)

with no change.

没有变化。

I also tried:

我也试过:

if ("${SERIALDEVICE_LIB}" STREQUAL "SERIALDEVICE_LIB-NOTFOUND")
    message(FATAL_ERROR "'qserialdeviced' wasn't found!")
else()
    message("'qserialdeviced' found: " ${SERIALDEVICE_LIB})
endif ()

But this test succeeds. The library is found:

但是这个测试成功了。找到库:

'qserialdeviced' found: /usr/lib/libqserialdeviced.so

Can anybody please help me to understand what happens here?

有人可以帮我了解这里发生了什么吗?

I am using Linux Fedora 13, cmake version 2.8.0, gcc (GCC) 4.4.5 20101112 (Red Hat 4.4.5-2) and kdevelop-4.1.0-1.fc13.x86_64.

我使用的是 Linux Fedora 13、cmake 版本 2.8.0、gcc (GCC) 4.4.5 20101112 (Red Hat 4.4.5-2) 和 kdevelop-4.1.0-1.fc13.x86_64。

Thanks i advance.

谢谢我提前。



EDIT:

编辑:

As suggested by @DatChu, I split my CMakeLists.txtacross my subdirectories and everything makes sense to me now.

正如@DatChu 所建议的那样,我将我的CMakeLists.txt子目录分开,现在一切对我来说都有意义。

Thanks everbody!

谢谢大家!

采纳答案by Dat Chu

For the original CMakeLists.txt file, the problem is not with target_link_libraries but with add_executable

对于原始的 CMakeLists.txt 文件,问题不在于 target_link_libraries 而在于 add_executable

add_executable(uart ${uart_SRCS})

where did you set your uart_SRCS variable? Do you have

你在哪里设置你的 uart_SRCS 变量?你有

set(uart_SRCS src/blahblah.cpp src/somethingblahblah.cpp)

I think you might misunderstand what add_subdirectory does. It does not add the source files inside. It tells CMake to descend into that folder and look for another CMakeLists.txt. You typically use it when you have a sub-project inside of your project folder.

我想你可能误解了 add_subdirectory 的作用。它不会在里面添加源文件。它告诉 CMake 进入该文件夹并查找另一个 CMakeLists.txt。当您的项目文件夹中有一个子项目时,您通常会使用它。

If you have many source files which you don't want to manually set, you can also do

如果你有很多不想手动设置的源文件,你也可以这样做

file(GLOB uart_SRCS src/*.cpp src/*.c)

The downside is you need to manually re-run CMake in order for it to detect new files. See Hyman's comment on why this might not be what you want to use.

缺点是您需要手动重新运行 CMake 以检测新文件。请参阅 Hyman 关于为什么这可能不是您想要使用的内容的评论。

Your CMakeLists.txt will most likely be

您的 CMakeLists.txt 很可能是

project(uart)

find_package(Qt4 REQUIRED)
include (${QT_USE_FILE})
find_package(KDE4 REQUIRED)
include (KDE4Defaults)

include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} src/include src/include/QSerialDevice )
link_directories(/usr/lib) 

file(GLOB uart_SRCS src/*.cpp src/*.h)
file(GLOB uart_HDRS include/*.h include/QSerialDevice/*.h)

find_library(SERIALDEVICE_LIB qserialdeviced)

add_executable(uart ${uart_SRCS} ${uart_HDRS})
target_link_libraries(uart ${SERIALDEVICE_LIB} ${QT_LIBRARIES})