Mein Vorschlag ist, dies in zwei Phasen anzugehen:
- Erstellen Sie eine Bibliothek aus den
.cpp
und .h
Dateien, mitadd_library
- Durchlaufen Sie alle Ihre
.cxx
Dateien und erstellen Sie aus jeder eine ausführbare Datei mit add_executable
undforeach
Erstellen Sie die Bibliothek
Dies könnte so einfach sein wie
file( GLOB LIB_SOURCES lib/*.cpp )
file( GLOB LIB_HEADERS lib/*.h )
add_library( YourLib ${LIB_SOURCES} ${LIB_HEADERS} )
Erstellen Sie alle ausführbaren Dateien
Durchlaufen Sie einfach alle CPP-Dateien und erstellen Sie separate ausführbare Dateien.
# If necessary, use the RELATIVE flag, otherwise each source file may be listed
# with full pathname. RELATIVE may makes it easier to extract an executable name
# automatically.
# file( GLOB APP_SOURCES RELATIVE app/*.cxx )
file( GLOB APP_SOURCES app/*.cxx )
foreach( testsourcefile ${APP_SOURCES} )
# I used a simple string replace, to cut off .cpp.
string( REPLACE ".cpp" "" testname ${testsourcefile} )
add_executable( ${testname} ${testsourcefile} )
# Make sure YourLib is linked to each app
target_link_libraries( ${testname} YourLib )
endforeach( testsourcefile ${APP_SOURCES} )
Einige Warnungen:
file( GLOB )
wird normalerweise nicht empfohlen, da CMake nicht automatisch neu erstellt wird, wenn eine neue Datei hinzugefügt wird. Ich habe es hier verwendet, weil ich Ihre Quelldateien nicht kenne.
- In einigen Situationen können Quelldateien mit einem vollständigen Pfadnamen gefunden werden. Verwenden Sie gegebenenfalls das Flag RELATIVE für
find( GLOB ... )
.
- Das manuelle Festlegen der Quelldateien erfordert eine Änderung an CMakeLists.txt, die eine Neuerstellung auslöst. In dieser Frage finden Sie die (Nachteile) des Globbing.
- Ich habe den Testnamen mit a generiert
string( REPLACE ... )
. Ich hätte get_filename_component mit dem NAME_WE
Flag verwenden können.
In Bezug auf "allgemeine" CMake-Informationen empfehle ich Ihnen, einige der allgemeinen "CMake-Übersicht" -Fragen zu lesen, die hier bereits zum Stackoverflow gestellt wurden. Z.B:
build/
Verzeichnis der obersten Ebene integriert , oder wird dies die Verzeichnisstruktur des zugrunde liegenden Quellbaums berücksichtigen? siehe auch diese Frageget_filename_component(testname ${testsourcefile} NAME_WE)
anstelle von verwendenstring(REPLACE...
. Der Vorteil ist, dass dadurch auch der Rest des Pfads entfernt wird. Dies ist praktisch, wenn SieEXECUTABLE_OUTPUT_PATH
festlegen möchten, wohin Binärdateien verschoben werden sollen.file( GLOB APP_SOURCES app/*.cxx )
file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) foreach( sourcefile ${APP_SOURCES} ) file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile}) string( REPLACE ".cpp" "" file ${filename} ) add_executable( ${file} ${sourcefile} ) target_link_libraries( ${file} ndn-cxx boost_system ) endforeach( sourcefile ${APP_SOURCES} )
Dies
CMakeLists.txt
funktioniert für mein OpenCV-Projekt,vorausgesetzt, die
*.cpp
Dateien befinden sich im selben Verzeichnis wieCMakeLists.txt
cmake_minimum_required(VERSION 3.5) project(opencv LANGUAGES CXX) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(OpenCV REQUIRED) include_directories( ${OpenCV_INCLUDE_DIRS} ) file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ) foreach( sourcefile ${APP_SOURCES} ) file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile}) string( REPLACE ".cpp" "" file ${filename} ) add_executable( ${file} ${sourcefile} ) target_link_libraries( ${file} ${OpenCV_LIBS} ) endforeach( sourcefile ${APP_SOURCES} )
quelle
Ich befinde mich in einer ähnlichen Situation, wenn ich ein OpenGL-Projekt mit mehreren Beispieldateien organisiere, wobei jede dieser Dateien eine Hauptmethode enthält.
Die folgenden Einstellungen generieren eine separate ausführbare Datei pro c / cpp-Datei und kopieren die erforderlichen Abhängigkeiten in den Ziel-Bin-Ordner.
Ordnerstruktur
CMakeLists.txt
cmake_minimum_required (VERSION 3.9) project ("my-project") include_directories(Resources/Libraries/glew/include Resources/Libraries/glfw/include) link_directories(Resources/Libraries/glew/lib Resources/Libraries/glfw/lib) link_libraries(opengl32.lib glew32.lib glfw3.lib) set(CMAKE_EXE_LINKER_FLAGS "/NODEFAULTLIB:MSVCRT") file(GLOB SOURCE_FILES *.c *.cpp) foreach(SOURCE_PATH ${SOURCE_FILES}) get_filename_component(EXECUTABLE_NAME ${SOURCE_PATH} NAME_WE) add_executable(${EXECUTABLE_NAME} ${SOURCE_PATH}) # Copy required DLLs to the target folder add_custom_command(TARGET ${EXECUTABLE_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_SOURCE_DIR}/Resources/Libraries/glew/bin/glew32.dll" "${CMAKE_BINARY_DIR}/glew32.dll") endforeach(SOURCE_PATH ${SOURCE_FILES})
Optionale Schritte
In Visual Studio
Öffnen Sie das Projekt mit der Option "Lokalen Ordner öffnen" im Startfenster
Wenn Sie eine neue Datei hinzufügen, können Sie entweder:
add_executable
zu CMakeLists.txt zu wechselnTools > Options > CMake
Da neu hinzugefügte Dateien nicht automatisch erfasst werden, da CMakeLists.txt niemals geändert wird, generieren Sie den Cache einfach wie folgt neu:
Project > CMake Cache (x64-Debug) > Delete Cache
Project > Generate Cache for my-project
Jetzt können Sie einfach mit der rechten Maustaste auf eine bestimmte c / cpp-Datei klicken und
Set as Startup Item
sie mit debuggenF5
.Umgebung
quelle