Подтвердить что ты не робот

Cmake target_link_libraries не связывает мою библиотеку

Я начну утверждать, что я почти полностью погружен в вопрос Cmake.

У меня есть следующий 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_executable и target_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.

Спасибо, я заранее.


EDIT:

Как было предложено @DatChu, я разделил свой CMakeLists.txt на мои подкаталоги, и теперь все имеет смысл для меня.

Спасибо всем!

4b9b3361

Ответ 1

Для исходного файла 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})