Создание библиотеки с помощью cmake

Прошу прощения за беспокойство, но у меня небольшая проблема с компиляцией cmake.

У меня есть файл CMakeLists.txt, который я использую для создания тестового исполняемого файла и общей библиотеки. Оба они зависят от другой библиотеки (SFML).

Я использую cmake в окне с MinGW.

Я знаю, что название библиотеки, которую я создаю, немного сбивает с толку название sfml, но предполагается, что это оболочка SFML, поэтому лучшего имени я не нашел!

Вот CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(projectName)

set(EXECUTABLE_NAME testSFML)
set(LIBRARY_NAME    SFMLwindow)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin/)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include /
${CMAKE_CURRENT_SOURCE_DIR}/../../include
)

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/)

file(
    GLOB_RECURSE
    SRC_FILES
    src/*
)

file(
    GLOB_RECURSE
    INCLUDE_FILES
    include/*
)

add_executable(
${EXECUTABLE_NAME}
main.cpp
${SRC_FILES}
${INCLUDE_FILES}
)

target_link_libraries(
    ${EXECUTABLE_NAME}
    sfml-main
    sfml-system
    sfml-window
)


add_library(
${LIBRARY_NAME}
SHARED
${SRC_FILES}
)

И что я получаю в терминале:

"C:\MinGW\bin\mingw32-make.exe" 
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/iksemel/docs/WorkBench/programming/projets/TestSFML/cmake
Linking CXX shared library libSFMLwindow.dll
Creating library file: libSFMLwindow.dll.a
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x59):undefined reference to `_imp___ZN2sf9VideoModeC1Ejjj'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0xda): undefined reference to `_imp___ZN2sf6WindowC1ENS_9VideoModeERKSsjRKNS_15ContextSettingsE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x163): undefined reference to `_imp___ZN2sf6Window5closeEv'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1bd): undefined reference to `_imp___ZN2sf6Window9pollEventERNS_5EventE'
CMakeFiles\SFMLwindow.dir/objects.a(SFMLWindow.cpp.obj):SFMLWindow.cpp:(.text+0x1d8): undefined reference to `_imp___ZN2sf6Window7displayEv'
collect2: ld a retourné 1 code d'état d'exécution
mingw32-make.exe[2]: *** [libSFMLwindow.dll] Error 1
mingw32-make.exe[1]: *** [CMakeFiles/SFMLwindow.dir/all] Error 2
mingw32-make.exe: *** [all] Error 2

Если у кого-нибудь есть ключ к тому, что происходит, я был бы очень благодарен!


person Cuthalion    schedule 27.06.2012    source источник


Ответы (1)


Полагаю, ваша библиотека SFMLwindow должна быть связана с некоторыми или со всеми sfml-main, sfml-system, sfml-window.

Вы можете попробовать изменить конец вашего CMakeLists.txt на:

add_library(
    ${LIBRARY_NAME}
    SHARED
    ${SRC_FILES}
    ${INCLUDE_FILES}
)

add_executable(
    ${EXECUTABLE_NAME}
    main.cpp
)

target_link_libraries(
    ${LIBRARY_NAME}
    sfml-main
    sfml-system
    sfml-window
)

target_link_libraries(
    ${EXECUTABLE_NAME}
    ${LIBRARY_NAME}
)


Кстати, file(GLOB_RECURSE... обычно не одобряют как способ собрать список источников. Из документации для file:

Мы не рекомендуем использовать GLOB для сбора списка исходных файлов из вашего исходного дерева. Если файл CMakeLists.txt не изменяется при добавлении или удалении источника, созданная система сборки не может знать, когда запрашивать CMake для повторной генерации.


Кроме того, вместо link_directories в этом случае. Из документов для link_directories:

Обратите внимание, что эта команда требуется редко. Расположение библиотек, возвращаемое функциями find_package() и find_library(), является абсолютным путем. Передайте эти абсолютные пути к файлам библиотек непосредственно команде target_link_libraries(). CMake гарантирует, что компоновщик их найдет.

person Fraser    schedule 27.06.2012
comment
Спасибо за помощь, я отредактировал свой CMakeLists.txt, но он пока не работает. Но что странно, если я собираю только исполняемый файл, он работает нормально, только при сборке библиотеки я сталкиваюсь с этой проблемой. И файлы .o вроде бы созданы как надо. Мой CmakeLists.txt сейчас: pastebin.com/hLux8Lvi - person Cuthalion; 27.06.2012
comment
Я понял проблему! Вы были правы насчет проблемы с линковкой, но для ее исправления мне пришлось использовать 2 target_link_libraries. Один для исполняемого файла, а другой для библиотеки. Другой проблемой, с которой я столкнулся, был порядок командования. Кажется, что target_link_libraries должны стоять после add_executable и add_library. Вот мой текущий cmake, и еще раз спасибо за общую информацию о cmake и за помощь! pastebin.com/ErgbGir0 - person Cuthalion; 27.06.2012
comment
ОК - рад, что это работает. Основное различие между нашими решениями заключается в том, что вы компилируете исходники как в библиотеку , так и в исполняемый файл. Это нормально для небольших проектов, но становится проблемой, если у вас много исходных файлов. Обычно вы компилируете исходники только один раз в библиотеку, а затем просто связываете эту библиотеку с тестовым исполняемым файлом. С CMake, если вы укажете, что библиотека A зависит от библиотеки B, а exe Z зависит от библиотеки A, то он также автоматически добавляет lib B в качестве зависимости от Z. Вот почему я указал только ${LIBRARY_NAME} в качестве зависимости от ${EXECUTABLE_NAME}. Хотя ничего страшного :-) - person Fraser; 27.06.2012
comment
Еще раз большое спасибо за ваш опыт! Теперь я ясно понимаю, что вы хотели, чтобы я сделал, и я должен признать, что ваше решение очень эффективно! Я отредактировал свой CMakeLists.txt в соответствии с вашими указаниями: pastebin.com/xL5FATsL - person Cuthalion; 28.06.2012