it-swarm.com.de

Überschreiben eines Standardoptionswerts (...) in CMake aus einer übergeordneten CMakeLists.txt

Ich versuche, mehrere Bibliotheken von Drittanbietern in meinen Quellbaum aufzunehmen, wobei das Build-System nur minimal geändert werden muss, um die Aktualisierung zu erleichtern. Sie alle verwenden CMake, genau wie ich. In meiner eigenen CMakeLists.txt kann ich add_subdirectory(extern/foo) für libfoo verwenden.

Die foo CMakeLists.txt kompiliert jedoch eine Testumgebung, erstellt eine Dokumentation, eine gemeinsam genutzte Bibliothek, die ich nicht benötige, und so weiter. Die libfoo-Autoren hatten die Weitsicht, diese Optionen über Optionen zu steuern - beispielsweise option(FOO_BUILD_SHARED "Build libfoo shared library" ON) -, sodass ich sie über die CMake-Befehlszeile einstellen kann. Aber ich möchte das standardmäßig deaktivieren und über die Befehlszeile überschreiben.

Ich habe versucht, set(FOO_BUILD_SHARED OFF) vor add_subdirectory(extern/foo) zu tun. Dies hat den Effekt, dass nicht versucht wird, die gemeinsam genutzte Bibliothek während des zweiten und der nachfolgenden Build-Versuche zu erstellen, jedoch nicht während des ersten, was ich wirklich beschleunigen muss.

Ist dies möglich, oder muss ich für diese Projekte eine gegabelte CMakeLists.txt-Datei pflegen?

52
user79758

Stellen Sie die Variable in der CACHE ein

SET(FOO_BUILD_SHARED OFF CACHE BOOL "Build libfoo shared library")

Hinweis: Sie müssen den Variablentyp und eine Beschreibung angeben, damit CMake diesen Eintrag in der GUI anzeigen kann.

65
pkit

Diese Frage ist ziemlich alt, aber Google hat mich hierher gebracht.

Das Problem bei SET(<variable name> <value> CACHE BOOL "" FORCE) ist, dass die Option auf das gesamte Projekt festgelegt wird. Wenn Sie ein Unterprojekt verwenden möchten, bei dem es sich um eine Bibliothek handelt, und Sie BUILD_STATIC_LIBS für das Unterprojekt (ParentLibrary) mithilfe von SET(... CACHE BOOL "" FORCE) festlegen möchten, wird der Wert für alle Projekte festgelegt.

Ich verwende folgende Projektstruktur:

|CMakeLists.txt (root)
|- dependencies
   | CMakeLists.txt (dependencies)
   |- ParentLibrary
      | CMakeLists.txt (parent)
|- lib
   | CMakeLists.txt (lib)

Jetzt habe ich CMakeLists.txt (dependencies) was so aussieht:

# Copy the option you want to change from ParentLibrary here
option (BUILD_SHARED_LIBS "Build shared libraries" ON)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(ParentLibrary)

Der Vorteil ist, dass ich ParentLibrary nicht ändern muss und die Option nur für dieses Projekt festlegen kann.

Es ist notwendig, den Befehl option explizit von der Variable ParentLibrary zu kopieren, da andernfalls bei der erstmaligen Ausführung der CMake-Konfiguration der Wert der Variablen zuerst mit dem Befehl set festgelegt und später mit dem Befehl option überschrieben wird, da im Wert kein Wert enthalten ist Zwischenspeicher. Wenn Sie die CMake-Konfiguration zum zweiten Mal ausführen, wird der Befehl option ignoriert, da sich bereits ein Wert im Cache befindet und der Wert aus dem Befehl set verwendet wird. Dies würde zu einem seltsamen Verhalten führen, dass die Konfiguration zwischen zwei CMake-Durchläufen unterschiedlich ist.

0
Martin Stolpe