tutorial library example c++ linux linker cmake kdevelop

c++ - tutorial - cmake add library example



Cmake target_link_libraries no vincula mi biblioteca (1)

Comenzaré a afirmar que estoy casi completo como tonto en este asunto.

Tengo el siguiente CMakeLists.txt para un proyecto de 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})

Cuando intento construir mi proyecto veo:

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

Todo lo que leo dice que add_executable y target_link_libraries deberían parecerse a las dos últimas líneas de mi archivo:

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

Si cambio esas dos líneas de CMakeLists.txt dejándolo como:

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

Veo:

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

Eso muestra claramente que target_link_libraries no está enlazando mi qserialdeviced .

qserialdeviced está en qserialdeviced , correctamente vinculado a /usr/lib/libqserialdeviced.so y se encuentra fácilmente si lo agrego manualmente en el Makefile.

Obviamente lo intenté

target_link_libraries(-lqserialdeviced)

sin cambio

También intenté:

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

Pero esta prueba tiene éxito. La biblioteca se encuentra:

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

¿Alguien por favor me puede ayudar a entender lo que pasa aquí?

Estoy usando Linux Fedora 13, cmake versión 2.8.0, gcc (GCC) 4.4.5 20101112 (Red Hat 4.4.5-2) y kdevelop-4.1.0-1.fc13.x86_64.

Gracias avanzo

EDITAR:

Como lo sugirió @DatChu, dividí mi CMakeLists.txt en mis subdirectorios y ahora todo tiene sentido para mí.

Gracias a todos!


Para el archivo CMakeLists.txt original, el problema no es con target_link_libraries sino con add_executable

add_executable(uart ${uart_SRCS})

¿Dónde configuraste tu variable uart_SRCS? Tienes

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

Creo que podrías malinterpretar lo que hace add_subdirectory. No agrega los archivos de origen en el interior. Le dice a CMake que descienda a esa carpeta y busque otro CMakeLists.txt. Normalmente lo usa cuando tiene un subproyecto dentro de la carpeta de su proyecto.

Si tiene muchos archivos de origen que no desea configurar manualmente, también puede hacer

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

El inconveniente es que necesita volver a ejecutar CMake manualmente para que pueda detectar nuevos archivos. Vea el comentario de Jack sobre por qué esto podría no ser lo que quiere usar.

Tus CMakeLists.txt probablemente serán

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