2017-07-12 5 views
1

Zu Beginn bin ich neu bei CMake.CMake Multi-Projekt-Setup für Visual Studio 2017

Ich möchte von der Kompilierung meiner Lösung direkt in VS 2017 zu CMake wechseln, um das Projekt einfach auf anderen Plattformen wie Linux zu erstellen.

Ordnerstruktur:

project 
    |─── CMakeLists.txt 
    |─── bin 
    |  | ─── intermediates 
    |  |  |─── Win32 
    |  |  |  |─── Debug 
    |  |  |  └─── Release 
    |  |  └─── Linux 
    |  |    |─── Debug 
    |  |    └─── Release 
    |  |─── Win32 
    |  |  |─── Debug 
    |  |  └─── Release 
    |  └─── Linux 
    |   |─── Debug 
    |   └─── Release 
    |─── include 
    |─── Project 1 
    |  |─── CMakeLists.txt 
    |  |─── src 
    |  |─── res 
    |  └─── header 
    └─── Project 2 
     |─── CMakeLists.txt 
     |─── src 
     |─── res 
     └─── header 

CMake Dateien

Und hier meine CMakeLists sind, die erste für das Root-Projekt ist die zweite für das erste Projekt und das zweite Projekt:

# Specify the minimum version for CMake 
cmake_minimum_required(VERSION 3.8.2) 

# Project's name 
project(Project X) 

# Set the C++ Version 
message("!REQUIRED! -- Supported features = ${cxx_std_14}") 
message("Supported features = ${cxx_std_17}") 

set(CMAKE_CXX_STANDARD 14) 
set(CMAKE_CXX_STANDARD_REQUIRED ON) 
set(CMAKE_CXX_EXTENSIONS OFF) 

# Set the output folder where the program will be created 

set(CMAKE_BINARY_DIR ${CMAKE_SOURCE_DIR}/bin) 
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}) 

# Add the modules 
add_subdirectory(Project 1) 
add_subdirectory(Project 2) # depends on Project 1 

Die CMakeLists.txt für das erste und zweite Projekt, wie der Inhalt der Datei ist der gleiche:

# Specify the minimum version for CMake 
cmake_minimum_required(VERSION 3.8.2) 

project(Project 1) 

# In order to find all cpp files automatically for compilation 
file(GLOB CPP_FILES src/*.cpp) 
file(GLOB CPP_FILES header/*.h) 

# Set the version number of the project here 
set(VERSION_MAJOR "0") 
set(VERSION_MINOR "1") 
set(VERSION_PATCH "0") 
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) 

Und das sind meine VS-Einstellungen:

Output Directory:  $(SolutionDir)bin\$(Platform)\$(Configuration)\ 
Intermediate Directory: $(SolutionDir)bin\intermediates\$(Platform)\$(Configuration)\ 

Projekt B in diesem Fall ist die ausführbare Datei während Projekt A nur ein lib ist, die mit Projekt B, um verbunden zu sein hat für das Projekt B zu kompilieren.

Frage:

  • Wie kann ich die Visual Studio 2017-Einstellungen zu CMake gelten? (Wie muss ich die CMAKE_BINARY_DIR Einstellung usw. konfigurieren)
  • Projekt 2 hängt von Projekt 1 wird CMake diese automatisch handhaben, oder muss ich etwas zu dem CMakeLists.txt hinzufügen müssen?

Antwort

2

Es gibt mehrere Punkte zu Adresse:

  1. CMAKE_BINARY_DIR ist, für alle Absichten und Zwecke, eine schreibgeschützte Variable, und auf jeden Fall als solche behandelt werden sollten. Die Art und Weise, das Binärverzeichnis anzugeben, besteht darin, CMake in diesem Verzeichnis auszuführen (wenn über die Befehlszeile ausgeführt wird) oder dieses Verzeichnis als das binary/output-Verzeichnis festzulegen (wenn eine CMake-GUI verwendet wird). Also in Ihrem Fall zu erreichen, um das Setup Sie behaupten, Sie wollen, sollten Sie dies tun:

    > cd project/bin 
    > cmake .. -G "Visual Studio whatever" ... 
    

    („whatever“ ist, natürlich, ein Platzhalter)

    Allerdings empfehle ich Ihnen zu tun Verwenden Sie kein Layout wie dieses. Eine viel bessere Layout wäre ein rein out-of-Source-build, wie folgt aus:

    project 
    project/source/CMakeLists.txt 
    project/source/include 
    project/source/... 
    project/build/Win32 
    project/build/Linux 
    

    Mit diesem Setup, würden Sie dann wie folgt aus:

    > cd project/build/Win32 
    > cmake ../../source -G "Visual Studio whatever" ... 
    
  2. Es gibt einen Konflikt zwischen wie Sie Ihre binären Ausgabepfade in CMake einstellen und was Sie als Ihre VS-Einstellungen vorgestellt haben."Ich weiß nicht, welcher Status Ihr Intended ist, aber wenn Sie CMake so einrichten möchten, dass Ihre Binärdateien in dem Ausgabeverzeichnis enden, das Sie in den VS-Einstellungen aufgelistet haben, würden Sie Folgendes tun:

    set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}) 
    

    Das Gleiche gilt für LIBRARY_OUTPUT_PATH.

  3. Soweit das Zwischenverzeichnis Einstellung geht, ist dies etwas, CMake schafft selbst und man kann dies nicht wirklich beeinflussen. die Frage ist, warum Sie wollen würde, though.

  4. In Bezug auf Projektabhängigkeiten: Sie haben die CMake-Befehle, die das Binar tatsächlich erstellen, nicht angezeigt ies (add_library()/add_executable()) oder Befehle, die ihre Eigenschaften festlegen. Wenn Sie jedoch angeben, dass die von Project 2 erstellte ausführbare Datei mit der von Project 1 erstellten Bibliothek verknüpft ist, wird CMake die Abhängigkeit korrekt verfolgen. Sie würden es so an:

    target_link_libraries(targetNameOfProject2executable targetNameOfProject1library) 
    
  5. Bitte beachten Sie, dass file(GLOB) mit einer Liste von Quelldateien zu konstruieren, ist eine schlechte Idee und wird von CMake abgeraten. Der Grund ist einfach: Das Hinzufügen einer Quelldatei führt nicht zur Neugenerierung des Buildsystems, dh die Quelldatei wird nicht aufgenommen. Wenn Sie stattdessen Quelldateien explizit auflisten, bedeutet das Hinzufügen der Datei, dass Sie sie zur Liste in der CMakeList (oder in einer von ihr eingeschlossenen Datei) hinzufügen müssen, wodurch eine erneute Generierung des Buildsystems ausgelöst wird.

  6. Hinweis für Linux: Im Gegensatz zu Visual Studio, der Makefile-Generator (und in der Tat der meisten von CMake der Generatoren) ist Single-Konfiguration, was bedeutet, dass Sie ein Buildsystem für jede Konfiguration erzeugen müssen. In dem Out-of-Souce-Setup, dann würden Sie es wie folgt tun:

    > cd project/build/Linux/Debug 
    > cmake ../../../../source -DCMAKE_BUILD_TYPE=Debug ... 
    > cd project/build/Linux/Release 
    > cmake ../../../../source -DCMAKE_BUILD_TYPE=Release ... 
    
+0

** Zu 1: ** Können Sie erklären, warum ein "rein out-of-Source-build" wären besser? ** Zu 2: ** Ich möchte, dass die CMake-Einstellungen mit denen in VS übereinstimmen. ** Zu 5: ** Wie kann ich erreichen, alle Quelldateien zu kompilieren, da ich nicht Hunderte von Dateien manuell schreiben möchte. – ShadowDragon

+1

@ShadowDragon ** 1 ** Es ist nicht unbedingt notwendig, aber es ist die bevorzugte CMake-Betriebsart. "CMake out-of-source" sollte googeln. Aber Ihre ursprüngliche Idee, bei der die Verzeichnisse zumindest verschieden sind, ist auch ziemlich gut. ** 2 ** Die Antwort zeigt das. Es funktioniert auch für Ihr "Under-Source" Setup. ** 5 ** Sie können die Liste (die 'set()' -Aufrufe) in eine separate Datei verschieben, die Sie 'include()' einfügen und ein Skript oder etwas verwenden, um es zum ersten Mal zu erzeugen. Dann aktualisieren Sie es einfach manuell. – Angew