2012-06-27 11 views
7

Mi scuso per aver infastidito tutti, ma ho un piccolo problema di compilazione con cmake.Libreria di edifici con cmake

Ho un file CMakeLists.txt che sto usando per creare un eseguibile di test e una libreria condivisa. Entrambi hanno dipendenza da un'altra libreria (SFML).

Sto usando cmake sulla finestra con MinGW.

So che il nome della lib che sto costruendo è un po 'confuso con quello sfml, ma dovrebbe essere un wrapper SFML, quindi non ho trovato un nome migliore!

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

E cosa ottengo nel terminale:

"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 

Se qualcuno ha un indizio su quello che sta succedendo, sarei molto gratefull!

risposta

14

Ad una congettura, le vostre esigenze della libreria SFMLwindow sono collegate a tutte o parte di sfml-main, sfml-system, sfml-window.

Si potrebbe provare a cambiare alla fine del tuo CMakeLists.txt a:

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


Per inciso, file(GLOB_RECURSE... è generalmente malvista come un modo per raccogliere un elenco di fonti. Dai documenti per file:

Non è consigliabile utilizzare GLOB per raccogliere un elenco di file di origine dall'albero dei sorgenti. Se nessun file CMakeLists.txt cambia quando viene aggiunta o rimossa una sorgente, il sistema di generazione generato non può sapere quando chiedere a CMake di rigenerare.


Inoltre, find_library è preferibile a link_directories in questo caso. Da documenti per link_directories:

Si noti che questo comando è raramente necessario. Le posizioni delle librerie restituite da find_package() e find_library() sono percorsi assoluti. Passa questi percorsi di file della libreria assoluti direttamente al comando target_link_libraries(). CMake si assicurerà che il linker li trovi.

+0

Grazie per l'aiuto, ho modificato il mio CMakeLists.txt, ma non sembra funzionare ancora. Ma la cosa strana è che, se sto solo costruendo l'eseguibile, funziona bene, è solo quando creo la libreria che sto incontrando questo problema. E i file .o sembrano essere creati come dovrebbero essere. My CmakeLists.txt ora: http://pastebin.com/hLux8Lvi – Cuthalion

+0

Ho capito il problema! Avevi ragione riguardo al problema di collegamento, ma per correggerlo dovevo usare 2 target_link_libraries. Uno per l'eseguibile e l'altro per la biblioteca. L'altro problema che ho avuto è stato l'ordine di comando. Sembra che * target_link_libraries * debba apparire dopo add_executable e add_library. Ecco la mia cmake attuale, e ancora, grazie per le informazioni generali su cmake e aiutandomi! http://pastebin.com/ErgbGir0 – Cuthalion

+0

OK: felice che funzioni. La principale differenza tra le nostre soluzioni è che si compilano i sorgenti sia nella libreria * che * nell'exe. Questo è OK per piccoli progetti, ma diventa un problema se si hanno molti file sorgente. Normalmente, dovresti compilare i sorgenti una sola volta nella libreria, quindi collegare semplicemente quella libreria al file di prova.Con CMake, se si specifica che lib A dipende da lib B e exe Z dipende da lib A, allora aggiunge lib B anche come dipendenza di Z. Ecco perché ho specificato solo $ {LIBRARY_NAME} come dipendenza di $ {EXECUTABLE_NAME} '. Non c'è da stupirsi :-) – Fraser