CMake Anfänger



  • testo schrieb:

    gibt es irgdnwie noch andere bessere doku zu cmake?

    Wie schon beschrieben, die Doku ist immer schlechter geworden, weil CMake immer umfangreicher wurde.

    Die erste Buchversion zu CMake war reine Geldmacherei, da sie ihre Wiki einfach dedruckt haben...

    hier ein paar, wie ich finde nützliche, Links:
    http://www.cmake.org/Wiki/CMake
    http://www.cmake.org/Wiki/CMake_FAQ
    http://techbase.kde.org/Development/Tutorials/CMake_(de)

    Viel Erfolg! Wenn du erst einmal grössere Projekte verwaltest mit diversen 3rd Party Libs und dann noch auf verschiednenen Rechnern und Plattformen ist CMake gold wert



  • danke dir - so wie sich das anhört sollte ich nicht unbedingt cmake nutzen. Ist ja jetzt nicht eine Mega-Anwendung wie KDE sondern halt ein 20k Zeiler der halt auf verschiedenen Linuxsystemen laufen soll...und ein paar Libs einbindet.

    Lohnen sich da nicht vielleicht doch die autotools - was nützt mir jetzt ein tolles cmake wenn ich nicht weiß wie ich es bedienen soll (ohne gute doku)...



  • doch CMake lohnt sich auf jeden fall. zumal es verschiedenste IDEs unterstützt.

    du möchtest doch lediglich ein makefile generieren, dass alle gewünschten Einstellungen für dich vornimmt, oder nicht? Und genau dafür ist CMake ja gedacht. Aber zaubern kann es auch nicht. Die Pfade zu den libs musst du ihm, wenn es kein passendes findXXX.cmake gibt natürlich schon mitteilen.

    und die obigen Links zeigen beihnalten doch kleine Beispiele, teils sogar mit sourcen.

    kannst dir aber auch gerne:
    http://www.scons.org/
    http://sources.redhat.com/automake/automake.html
    http://www.boost.org/doc/tools/build/index.html
    http://ant.apache.org/

    es gibt aber auch andere



  • ja vielen dank.
    Genau - ich will eine Makefile erstellen.

    Das mit den Pfaden schaffe ich nicht. Ich schaffe es nicht vom oberdirectory die sourcen in src/ zu kompilieren ABER das binary unter bin/ zu legen. Geht das überhaupt?

    Ich bemerke auch das ziemlich viel Müll produziert wird durch CMake , da gibt es CMakeFiles in jedem directory nach dem durchlauf, dann aber auch einen Cache und noch cmake_install.cmake und so weiter. Braucht es die überhaupt nachdem make ausgeführt wurde?

    Könnte ich irgendwie folgendes erreichen? Das ich alle Files nachdem make ausgeführt wurde einfach lösche?



  • keine Ahnung, hab mich um sowas nie wirklich gekümmert.
    Soweit ich weiß wird dass makefile IMMER in dem verzeichnis erstellt in dem du ccmake aufrufst. hier wird später auch das binary abgelegt, was ich für sinnvoll erachte. denn verschieben kann man es ja immer noch. zur bastelst du dir halt ein bash-skript.
    Ansonsten finde ich NACH cmake und make folgende ordnerstruktur + dateien vor:

    ./bin/binary_file
    ./bin/CMakeFiles/ <-da sind ein Haufen
    ./bin/CMakeCache.txt <-da sind alle Variablen drin gespeichert
    ./bin/cmake_install.cmake
    ./bin/Makefile
    ./src/a.h
    ./src/a.cpp
    ./src/b.h
    ./src/b.cpp
    ./src/main.cpp
    

    also sehe ich nicht wirklich das Problem. Löschen kannst du die Dateien durchaus NACH dem Erstellen. In CmakeFiles erstellt er auch die object-files. Also alles prima. Der Source-Ordner bleibt unangetastet und alles redundante wird in bingepackt. und dass ein User in das bin Verzeichniss wechseln muss ist nun wirklich kein Beinbruch!



  • ich danke dir für deine Mithilfe. Warum benutzt du eigentlich ccmake? Das gleiche geht doch mit cmake nur dass du nicht noch extra 'c' hacken musst oder? Was ist der grund?

    Mir ist schon klar das der user ins bin wechseln kann. Trotzdem bin ich mir sicher dass es gehen muss. Wenn CMake das schon nicht kann...also ich weiß nicht 🙂
    Ist natürlich nicht böse gemeint.



  • dürfte ich vielleicht deine CMakeLists.txt sehen? Weil ich dachte man muss pro directory jeweils ein CmakeLists.txt haben...



  • testo schrieb:

    dürfte ich vielleicht deine CMakeLists.txt sehen? Weil ich dachte man muss pro directory jeweils ein CmakeLists.txt haben...

    natürlich kannst du sie sehen!

    CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
    
    INCLUDE("../../../../../../../../CMakeCABMacros.txt")
    INCLUDE("../../../../../../../../CMakePCHMacros.txt")
    INCLUDE("../../../../../../../../CMakeSetCompilerFlags.txt")
    INCLUDE("../../../../../../../../CMakeFindBoost.txt")
    
    CHECK_FOR_VARIABLE(CAB_MACHINE "machine name, e.g. ALTIX, ARWEN")
    SET(CMAKE_CONFIG_FILE "${SOURCE_ROOT}/cmake_config_files/${CAB_MACHINE}.config.cmake")
    
    IF(CAB_MACHINE AND EXISTS ${CMAKE_CONFIG_FILE} )
       PROJECT(mp3d_rcf)
    
       SET(EXECUTABLE_NAME mp3d_rcf)
    
       #erst hier das config file einfügen, ansonsten werden manche settings durch (Project) überschrieben)  
       INCLUDE(${CMAKE_CONFIG_FILE})  
    
       #################################################################
       ###   PACKAGES						###
       #################################################################
       SET(WITH_SUBFOLDERS_FOR_SG YES)
       INCLUDE(${SOURCE_ROOT}/basics/objects/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/basics/utilities/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/basics/memory/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/basics/container/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/basics/writer/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/basics/parallel/CMakePackage.txt)   
    
       INCLUDE(${SOURCE_ROOT}/numerics/geometry3d/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/numerics/geometry3d/creator/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/numerics/geometry3d/fem/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/3rdParty/MuParser/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/3rdParty/rcf/CMakePackage.txt)
    
       INCLUDE(${SOURCE_ROOT}/3rdParty/metis/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/3rdParty/MarchingCubes/CMakePackage.txt)
    
       INCLUDE(${SOURCE_ROOT}/topology/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/transmitter/CMakePackage.txt)
    
       SET(WITH_SUBFOLDERS_FOR_SG NO)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/blockadaptation/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/gridadaptation/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/interactor/CMakePackage.txt)
    
       SET(WITH_SUBFOLDERS_FOR_SG YES)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/services/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/services/interfaces/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/services/adapter/CMakePackage.txt)
    
       SET(WITH_SUBFOLDERS_FOR_SG NO)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/interactor/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/gridadaptation/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/blockadaptation/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/bcadapter/CMakePackage.txt)
       #SET(WITH_SUBFOLDERS_FOR_SG YES)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/utils/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/steering/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/services/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/services/interfaces/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/services/adapter/CMakePackage.txt)
       SET(WITH_SUBFOLDERS_FOR_SG NO)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/connector/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/connector/scalemodules/CMakePackage.txt)
    
       #SET(WITH_SUBFOLDERS_FOR_SG YES)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/gridadaptation/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/blockadaptation/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/connector/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/connector/scalemodules/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/bcadapter/CMakePackage.txt)
       INCLUDE(${SOURCE_ROOT}/topology/amr3d/lbmd3q19/multiphase/services/adapter/CMakePackage.txt)
    
       #################################################################
       ###   LOCAL FILES                                             ###
       #################################################################
       FILE(GLOB SPECIFIC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.h 
                                ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
                                ${CMAKE_CURRENT_SOURCE_DIR}/*.hpp  )
    
       SET(ALL_SOURCES ${ALL_SOURCES} ${SPECIFIC_FILES})
       SOURCE_GROUP(z_main FILES ${SPECIFIC_FILES})
    
       #################################################################
       ###   PCH
       #################################################################
       #folgendes brauch man, egal ob PCH verwendet wird oder nicht!!!
       SET(PRECOMPILED_H ${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h)
       ADD_DEFINITIONS(-DPRECOMPILED_HEADER_FILE=\"${PRECOMPILED_H}\")		
    
       OPTION(USE_PRECOMPILED_HEADER "vorkompilierte header verwenden" OFF)
       IF( USE_PRECOMPILED_HEADER ) 
         SET(PRECOMPILED_CPP ${CMAKE_CURRENT_SOURCE_DIR}/precompiled.cpp)
    	 FILE(GLOB CPP_USING_PCH ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
         list(REMOVE_ITEM CPP_USING_PCH ${PRECOMPILED_CPP})
         SET_PCH_FLAGS(${PRECOMPILED_H} ${PRECOMPILED_CPP} ${CPP_USING_PCH})
       ENDIF()	                                                  
    
       #################################################################
       ###   OWN DEFINES                                             ###
       #################################################################
       ADD_DEFINITIONS( -D${CAB_MACHINE} )
    
       SET(NEED_MPI  TRUE)
    
       #################################################################
       ###   COMPILER                                                ###
       #################################################################
       SET_COMPILER_SPECIFIC_FLAGS(${CAB_COMPILER})
    
       #################################################################
       ###   RCF                                                     ###
       #################################################################
       IF(USE_SF_SERIALIZATION)
         SET(EXECUTABLE_NAME ${EXECUTABLE_NAME}_sf)
       ELSE()
         SET(EXECUTABLE_NAME ${EXECUTABLE_NAME}_boost)
       ENDIF()
    
       #################################################################
       ###   BOOST                                                   ###
       #################################################################
       IF(NEED_MPI)
          SET_BOOST_STUFF( ${NECESSARY_BOOST_LIBS} )
       ENDIF()
    
       #################################################################
       ###   MPI                                                     ###
       #################################################################
       IF(NEED_MPI)
          SET_MPI_STUFF(CAB_MACHINE)
          SET(EXECUTABLE_NAME ${EXECUTABLE_NAME}_mpi)
       ELSE()
          SET(EXECUTABLE_NAME ${EXECUTABLE_NAME}_rcf)
       ENDIF()
    
       #################################################################
       ### QT SPECIFIC (only has effects if a QT source is included)	###
       #################################################################
       IF(NEED_QT AND QT_FOUND)
       INCLUDE_DIRECTORIES( ${QT_INCLUDE_DIR} 
                             ${QT_INCLUDE_PATH} 
                             ${QT_QTCORE_INCLUDE_DIR}
                             ${QT_QTGUI_INCLUDE_DIR}
                             ${QT_QTNETWORK_INCLUDE_DIR}  
                           )
       LINK_LIBRARIES ( debug     ${QT_QTCORE_LIBRARY_DEBUG}
                         debug     ${QT_QTGUI_LIBRARY_DEBUG}
                         debug     ${QT_QTNETWORK_LIBRARY_DEBUG}
                         ${QT_QTCORE_LIBRARY}
                         ${QT_QTGUI_LIBRARY}
                         ${QT_QTNETWORK_LIBRARY} 
                        )
    
       ADD_DEFINITIONS( ${QT_DEFINITIONS})
       ENDIF(NEED_QT AND QT_FOUND)
    
       IF(NEED_QT AND NOT QT_FOUND)
        MESSAGE("Ups\nAt least one package needs Qt!\nPlease check Qt settings\n(e.g. librarys within Advanced Values)")
       ENDIF(NEED_QT AND NOT QT_FOUND)
    
       #################################################################
       ###   ADDITIONAL_MAKE_CLEAN_FILES                             ###
       #################################################################
       SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${GENERATED_FILES}")
    
       #################################################################
       ###   EXCECUTABLE						###
       #################################################################
       ADD_EXECUTABLE(${EXECUTABLE_NAME} ${ALL_SOURCES} )
    
       #################################################################
       ###   ADDITIONAL LINK LIBRARIES                               ###
       #################################################################
       IF(ADDITIONAL_LINK_LIBRARIES)
    	 TARGET_LINK_LIBRARIES(${EXECUTABLE_NAME} ${ADDITIONAL_LINK_LIBRARIES}) 
       ENDIF(ADDITIONAL_LINK_LIBRARIES)
    
       #################################################################
       ###   ADDITIONAL LINK PROPERTIES                              ###
       #################################################################
       IF(ADDITIONAL_LINK_PROPS)
         SET_TARGET_PROPERTIES(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS ${ADDITIONAL_LINK_PROPS})
       ENDIF(ADDITIONAL_LINK_PROPS)
       IF(ADDITIONAL_LINK_PROPS_DEBUG)
         SET_TARGET_PROPERTIES(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS_DEBUG ${ADDITIONAL_LINK_PROPS_DEBUG})
       ENDIF(ADDITIONAL_LINK_PROPS_DEBUG)
       IF(ADDITIONAL_LINK_PROPS_RELEASE)
         SET_TARGET_PROPERTIES(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS_RELEASE ${ADDITIONAL_LINK_PROPS_RELEASE})
       ENDIF(ADDITIONAL_LINK_PROPS_RELEASE)
    
    ELSEIF(CAB_MACHINE)
       MESSAGE("CAB_MACHINE error - following file is missing: \n ${CMAKE_CONFIG_FILE}")
    ELSE()
       MESSAGE("check CAB_MACHINE!!!")
    ENDIF()
    

    um deine Frage zu beantworten: unser Source-Tree ist durch die Ordner in "packages" eingeteilt.EIne Menge selbstgeschriebener Macros fügen die entsprechenden libs (wie mpi, metis, qt, zlib, rcf, etc) hinzu. diese werden teils von mir erstellt (macht cmake automatisch durch das erkennen der abhängigkeiten). je nach compiler oder betriebssystem werden zustätzliche compilerflags, präprozeesor macros, etc. benötigt. jedes package liefert hie reine reihe von optionen, die dann in ccmake nach belieben angepasst weren koennen, wenn einem die defaults nicht gefallen (z.B. auschalten des rangechecks bei STL vectoren unter windows, metis als lib verwenden oder direkt in die sourcen mit aufnehmen, andere RCF / boost version verwenden, anderes serialiserungs framework verwenden). ich hoffe ich konnte damit helfen



  • PS: du kannst das binary dir übrigens doch setzen, mein kollege macht das ständig.
    Das war irgendwas mit CMAKE_BINARY_DIR



  • herzlichen dank...

    und ihr/Du habt nur ein CmakeLists das ihr in dem jeweiligen package aufruft? Liegt denn im source-verzeichnis nicht noch eines ?



  • ah - anscheinend braucht man nur ein CMakeLists.txt da wo die sourcen liegen - kann das sein?



  • ja klar! nur ein CMakeList.txt. Das übergibst du CMake und der prst dann alles durch.
    In unseren CMakePackage.txt Dateien stehen meist nur diese zwei Zeilen:

    GET_FILENAME_COMPONENT( CURRENT_DIR  ${CMAKE_CURRENT_LIST_FILE} PATH) 
    COLLECT_PACKAGE_DATA_WITH_OPTION(${CURRENT_DIR} ALL_SOURCES)
    

    Wobei eben nur die jeweilg in diesem Verzeichnis vorhanden quelldateien eingelesen werden



  • ok...jetzt würde ich noch gerne wissen wie das mit der eingabe von libraries ist. Ich benutzte eine lib.a . diese liegt bei jedem user ganz wo anders. Wie kann ich dem cmake eine library über die shell übergeben bzw. den pfad so dass gegen diese lib gelinkt wird?



  • Das macht diese Zeile

    SET(externalLib "/opt/blabla.a")
    TARGET_LINK_LIBRARIES(binary_name ${externalLib} )
    

    den Pfad musst du zuvor entweder per Variable in CMakeList.txt setzen oder die Variable in der GUI aus setzen.

    oder bei cmake angeben:

    cmake -D externalLib="/opt/blabla.a" ../src/.
    


  • danke dir vielmals 🙂
    ich bin untröstlich - ich suche jetzt eine möglichkeit auch nach libs zu suchen - also wenn sie irgndwo liegt bzw. installiert ist dann so nehmen ansonsten schauen ob der user sie übergeben und sonst halt error...bin natürlich schon auf der suche



  • schau dir mal ein paar der findXXX.cmake files an... dort wird meist ebenfalls nach libs gesucht. die suchorte sind meist standardpfade oder unter windows registry einträge. alle ordner zu durchsuchen kann etwas langwierig sein.
    aber das bekommt man hin



  • Uff - das wird ja ein riesenbrocken da die libs ja immer wo anders sind. und da jetzt so ein riesen-find file zu schreiben das schaffe ich alleine nicht 😞



  • ach was. wirst doch jetzt nicht aufgeben!
    schau dir einfach mal:

    FIND_LIBRARY
    

    an.. die Endung kann man weglassen, denn die ist plattformabh. und kann separat gesetzt werden



  • ja aufgeben tu ich (noch) nicht 🙂

    also ich hab hier ein beispiel gefunden...
    kann es wirlich sein dass ich einfach den Namen der lib angebe über NAMES und die Pfade wo diese liegen könnte? Aberso finde ich die ja evtl. gar nicht wenn der user seine lib ganz wo anders hat...wenn er sie z.B. bei sich im home dir hat?

    Und wie könnte ich den pfad vom user nehmen und in die find_library hineinsetzen?...

    FIND_LIBRARY(XERCES_CPP_LIB
    NAMES
     xerces-c xerces-c_2 xerces-c_static_2
    PATHS
     /usr/lib
     /usr/local/lib
     ${USERLIB_ROOT}/lib
     c:/libraries/lib
    )
    

    ich lese schon ausgiebig die doku - nur ist die wie ich finde nicht ganz so toll...



  • dann habe ich noch ein gravierenderes problem. Ich habe noch verschiedene lib optionen die (wie ich glaube) je nach system unterschiedlich sein müssen. Z.b. muss die option

    -llapack -L/usr/lib/atlas -lblas -latlas -lrt
    

    gesetzt sein bei mir im moment.
    wo anders sieht sie dann aber so aus

    -L/usr/lib64/liblapack.a -llapack -L/usr/lib/atlas -atlas -L/usr/lib64 -lblas -lg2c
    

    nur wie soll ihc das anstellen?


Anmelden zum Antworten