Es scheint, dass CMake ExternalProject
immer das Stammverzeichnis des externen Projekts als Quellverzeichnis annimmt. Aber was, wenn das nicht der Fall ist?CMake ExternalProject: Wie wird der relative Pfad zur Wurzel CMakeLists.txt angegeben?
Betrachten Sie das folgende Beispiel:
Das externe Projekt diese Verzeichnisstruktur verwendet:
libfoo.git <--- ExternalProject assumes this as source dir.
├── ...
└── libfoo <--- However, the actual source directory is this!
├── CMakeLists.txt
└── ...
Im abhängig Projekt libfoo
wie folgt konfiguriert ist:
ExternalProject_Add(libfoo
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/EP_libfoo"
GIT_REPOSITORY "<link to remote which hosts libfoo.git>"
GIT_TAG "<some hash>"
)
Der Build dann nicht mit die folgende Fehlermeldung:
$ cmake -H/path/to/source-dir -B/path/to/build-dir
...
$ cmake --build /path/to/build-dir/ --target all
...
CMake Error: The source directory "/path/to/build-dir/EP_libfoo/src/libfoo" does not appear to contain CMakeLists.txt.
...
$
So, wie in der obigen Verzeichnisstruktur wies darauf hin, denkt CMake, dass die Wurzel des externen Projekt
/path/to/build-dir/EP_libfoo/src/libfoo
ist, wenn in der Tat, es
/path/to/build-dir/EP_libfoo/src/libfoo/libfoo
Meine Versuche ist zu dieses Problem lösen:
Leider
SOURCE_DIR
vondas Argument zu ändernhat nicht funktioniert, weil der Wert dieser Variablen als Speicherort verwendet wird, die das Git-Repository vonlibfoo
geklont ist. Dies führt zu einer rekursiven Abhängigkeitshölle, die nicht gebrochen werden kann.Ändern des Verzeichnislayouts von
libfoo
, um zu entsprechen. Offensichtlich würde dies funktionieren, aber es funktioniert möglicherweise nicht für andere (schreibgeschützte) Third-Party-Bibliotheken.Missbrauch des Aktualisierungs/Patch-Schritts von , z.B. durch Angabe
Das funktioniert, aber es ist hackish und sehr anfällig für andere externe Projekte.
Aufbauend auf der solution to another problem: fügen Sie eine temporäre
CMakeLists.txt
an der Stelle, wo CMake es annimmt. Diese temporäre Datei beinhaltet dann die eigentlicheCMakeLists.txt
:set(EP_LIBFOO_DIR "${CMAKE_CURRENT_BINARY_DIR}/EP_libfoo") set(GENERATED_DIR "${CMAKE_BINARY_DIR}/generated") file(MAKE_DIRECTORY ${GENERATED_DIR}) file(WRITE ${GENERATED_DIR}/CMakeLists.txt "cmake_minimum_required(VERSION 3.0)\n" "add_subdirectory(libfoo)\n" ) ExternalProject_Add(libfoo PREFIX "${EP_LIBFOO_DIR}" GIT_REPOSITORY "<link to remote which hosts libfoo.git>" GIT_TAG "<some hash>" # Copy the UPDATE_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/generated/CMakeLists.txt ${EP_LIBFOO_DIR}/src/libfoo )
Dies funktioniert auch und fühlt sich besser als die bisherige Lösung.
Allerdings ist ein elegantere bestehen, das gleiche zu tun?
Die Funktion wurde akzeptiert und ist ab CMake 3.7 verfügbar: https://cmake.org/cmake/help/v3.7/module/ExternalProject.html – Matthew