web-dev-qa-db-ja.com

Cmake target_link_librariesがライブラリをリンクしない

私は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がファイルの最後の2行のように見えるはずだと言っています:

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

CMakeLists.txtの2行を変更すると、次のようになります。

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をサブディレクトリ間で分割しており、すべてが私にとって意味のあることです。

いつもありがとう!

18
j4x

元の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が新しいファイルを検出するために、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})
13
Dat Chu