Cmake target_link_libraries 未链接我的库

发布于 2024-10-25 12:51:52 字数 4188 浏览 1 评论 0原文

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

我有一个 Kdevelop 4.1 项目的以下 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)

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

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

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 ***

我读到的所有内容都表明 add_executabletarget_link_libraries 应该看起来像我文件的最后两行:

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

如果我更改 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})

我明白:

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 ***

这清楚地表明 target_link_libraries 是没有链接我的qserialdeviced

qserialdeviced 位于 /usr/lib/libqserialdeviced.so.1.0.0,正确地模拟链接到 /usr/lib/libqserialdeviced.so 并且很容易发现如果我手动将其添加到Makefile中。

我显然尝试过:

target_link_libraries(-lqserialdeviced)

没有任何改变。

我也尝试过:

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

但是这次测试成功了。找到图书馆:

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

任何人都可以帮助我了解这里发生了什么吗?

我使用的是 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。

谢谢我提前。


编辑:

按照@DatChu的建议,我将我的CMakeLists.txt拆分到我的子目录中,现在一切对我来说都有意义了。

谢谢大家!

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

I have the following CMakeLists.txt for a Kdevelop 4.1 project:

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_executable and target_link_libraries should look like the last two lines of my file:

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

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

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_libraries is not linking my qserialdeviced.

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

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.

Thanks i advance.


EDIT:

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

Thanks everbody!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很糊涂小朋友 2024-11-01 12:51:53

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

add_executable(uart ${uart_SRCS})

你在哪里设置了 uart_SRCS 变量?我

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

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

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

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

缺点是您需要手动重新运行 CMake 才能检测新文件。请参阅 Jack 的评论,了解为什么这可能不是您想要使用的。

您的 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})

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

add_executable(uart ${uart_SRCS})

where did you set your uart_SRCS variable? Do you have

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.

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 Jack's comment on why this might not be what you want to use.

Your CMakeLists.txt will most likely be

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})
葮薆情 2024-11-01 12:51:53

这并不是真正的直接解决方案,但我在“未定义的引用”错误上遇到了很大的困难(之前通过链接适当的库解决了,但在本例中不是),直到我发现了一些东西 - 与 c 与 cpp 的不兼容性。定义这些引用函数的文件位于 .c 文件中(默认 cmake 使用 C 编译器进行编译。),引用这些函数的文件是 .cpp 文件(使用 g++ 编译器或任何您的环境 c++ 编译器)。一旦我将 .c 文件更改为 .cpp,“未定义的引用”错误就消失了。上面看起来你的 uart 文件是 .cpp,但也许检查其他文件是什么并尝试此方法。这可能不是合适的解决方案,甚至根本不是一个解决方案,但这可能会帮助您度过这一天并继续前进。

This isn't really a direct solution, but I was having such difficulty with "undefined reference" errors (solved previously by linking the appropriate libraries, but not in this case), until I just discovered something - an incompatibility with c vs cpp somehow. The files that defined these reference functions were in .c files (which would default cmake to compile with a C compiler.) and my file referencing these functions is a .cpp file (using g++ compiler or whatever your environment c++ compiler is). Once I changed the .c file to .cpp the "undefined reference" errors disappeared. Above it looks like your uart file is .cpp, but maybe check what the other files are and try this method. It's probably not the appropriate solution or even one at all, but this might get you through the day and moving forward.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文