2011-03-22 58 views
18

我会开始说我在Cmake问题上几乎完全愚蠢。Cmake target_link_libraries没有链接我的库

我有以下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}) 

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

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在我子目录,一切对我来说很有意义了。

谢谢大家!

回答

13

对于原来的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的为它检测到新文件。请看杰克的评论,为什么这可能不是你想使用的。

你的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}) 
+0

不,我没有把它设置,但试图做类似'add_executable(UART的src/main.cpp中的src/uart.cpp ... )'。我停下脚步,因为我发现在'add_subdirectory(src)'后面重复所有源文件的名称并不是很聪明。有没有更好的方法来做到这一点?即使我尝试手动添加所有“.cpp”文件,我也必须提及erros。如果你愿意,我可以把错误放在我的帖子中。谢谢。 – j4x 2011-03-22 18:02:52

+0

如果你可以用你现在所拥有的文件+你项目中的文件来更新原始的CMakeLists.txt,我可以建议你需要CMake – 2011-03-22 19:39:40

+7

请不要推荐使用'file(GLOB ...)': http://www.cmake.org/pipermail/cmake/2010-July/037984.html和http://www.cmake.org/pipermail/cmake/2010-September/039562.html – 2011-03-22 19:58:56