2

Ich habe eine ausführbare Datei (Game Engine), die Symbole exportiert (ich habe set_target_properties(game PROPERTIES ENABLE_EXPORTS ON) verwendet).Wie erstellt man eine künstliche zirkuläre Abhängigkeit zwischen Zielen

Ich habe eine Reihe von Plug-ins, die auf diese ausführbare Datei verknüpfen:

foreach(plugin ${PLUGINS}) 
    target_link_libraries(${plugin} game) 
endforeach() 

Sie werden dynamisch mit LoadLibrary/dlopen durch die ausführbare Datei geladen.

Wenn ich F5 in Visual Studio drücke und ich das Spiel starte, bekomme ich die geänderten Plugins nicht neu, weil das Spiel nicht von ihnen abhängt - es ist umgekehrt.

Ich wollte folgendes tun:

foreach(plugin ${PLUGINS}) 
    add_dependencies(game ${plugin}) 
endforeach() 

aber es führt eine zirkuläre Abhängigkeit zwischen den einzelnen Plug-in und das Spiel. Wie kann ich mein F5-Problem lösen?

+0

Wie Verwenden Sie die exportierten Funktionen in Ihrem Plug-in-Code? Wenn Sie die Interface-Beschreibungen fest codiert haben oder in einer Header-Datei haben, dann gibt es nur eine indirekte Abhängigkeit von 'plugin' zu' game'. Was passiert also, wenn Sie nur Ihr "Spiel" von der "Plugin" Variante abhängig machen? Sollte aus meiner Sicht gut funktionieren. – Florian

+0

@Florian Nun, ich rufe in die Engine ... fast jedes Stück Funktionalität wird aus der ausführbaren Datei exportiert. Ich benutze die Engine-Header in den Plugins ... Das "' '' Plugin''' hängt ab von '' 'game''''" Abhängigkeit ist hier zu bleiben. Ich frage mich, wie man den F5-Workflow auch funktioniert ... – onqtam

+0

Wenn ich von den Plugins alles, was die Engine exportiert, mit '' 'getProcAddress''' anstelle von' '' __declspec (dllimport) '' 'annotiert weiterleiten Deklarationen, die ich entfernen könnte das "' '' Plugin '' 'hängt von' '' Spiel''' "Abhängigkeit, aber das wäre nicht praktisch zu Code ... – onqtam

Antwort

2

Das ist ein "Huhn-und-Ei" -Problem, da der Build die Importbibliotheken erzeugt, die von plugin benötigt werden. Sie können also plugin nicht vor game erstellen.

ich Ihr Szenario einen Versuch und

  1. gegeben habe Wenn ich in einem POST_BUILD Schritt wieder aufzubauen zwingen, erhalte ich offensichtlich eine rekursive Build Aufruf:

    add_custom_command(
        TARGET game 
        POST_BUILD 
         COMMAND ${CMAKE_COMMAND} --build . --target ALL_BUILD --config $<CONFIG> 
    ) 
    
  2. Wenn ich ein Konstrukt separates Ziel als "Läufer" -Ziel, würde ich wahrscheinlich andere mit meinem Projekt verwirren:

    file(WRITE nobuild.cpp "") 
    add_executable(game_runner nobuild.cpp) 
    
    set_source_files_properties(nobuild.cpp PROPERTIES HEADER_FILE_ONLY 1) 
    set_target_properties(game_runner PROPERTIES OUTPUT_NAME "game") 
    
    foreach(plugin ${PLUGINS}) 
        add_dependencies(game_runner ${plugin}) 
    endforeach() 
    
  3. Also ist wahrscheinlich Ihr Vorschlag, das ALL_BUILD Ziel wieder zu verwenden, das beste. Und für die automatische Generierung Ihrer erforderlichen .user Einstellungen können Sie die folgende interessant finden:

    CMake add_custom_target(): Run custom command using 'Debug->Start Debugging'


ich verwendet habe, die nach Ihrem Szenario zu testen:

project(TestPlugins) 

file(WRITE main.cpp "int main() { return 0; }") 
file(WRITE empty.cpp "") 

add_executable(game main.cpp) 
set_target_properties(game PROPERTIES ENABLE_EXPORTS ON) 
set_target_properties(game PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) 

add_executable(plugin1 empty.cpp) 
add_executable(plugin2 empty.cpp) 

set(PLUGINS plugin1 plugin2) 
foreach(plugin ${PLUGINS}) 
    target_link_libraries(${plugin} game) 
endforeach() 
+0

danke! Ihre andere Antwort, die die .user-Datei generiert, ist ebenfalls gut und es hat funktioniert! nicht mehr manuelle Einrichtung :) Sie sind einer der aktivsten über CMake im Stapelüberlauf - danke Sir. – onqtam

Verwandte Themen