如何在目标之间创建人工循环依赖
How to create an artificial circular dependency between targets
我有一个导出符号的可执行文件(游戏引擎)(我用过 set_target_properties(game PROPERTIES ENABLE_EXPORTS ON)
)。
我有一堆 link 该可执行文件的插件:
foreach(plugin ${PLUGINS})
target_link_libraries(${plugin} game)
endforeach()
它们由可执行文件使用 LoadLibrary
/dlopen
动态加载。
当我在 Visual Studio 中按 F5 并开始游戏时,我没有重新构建已更改的插件,因为游戏不依赖于它们 - 恰恰相反。
我想执行以下操作:
foreach(plugin ${PLUGINS})
add_dependencies(game ${plugin})
endforeach()
但它在每个插件和游戏之间引入了循环依赖。如何解决我的 F5 问题?
这是一个 "chicken-and-egg" 问题,因为 game
构建将生成 plugin
所需的导入库。所以你不能在 game
.
之前构建 plugin
我已经试过你的场景
如果我在 POST_BUILD
步骤中强制重建,我显然会得到一个递归构建调用:
add_custom_command(
TARGET game
POST_BUILD
COMMAND ${CMAKE_COMMAND} --build . --target ALL_BUILD --config $<CONFIG>
)
如果我构建一个单独的目标作为 "runner" 目标,我可能会混淆使用我的项目的其他人:
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()
所以您关于重新使用 ALL_BUILD
目标的建议可能是最好的建议。对于自动生成所需的 .user
设置,您可能会发现以下内容很有趣:
CMake add_custom_target(): Run custom command using 'Debug->Start Debugging'
我已经使用以下内容来测试您的场景:
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()
我有一个导出符号的可执行文件(游戏引擎)(我用过 set_target_properties(game PROPERTIES ENABLE_EXPORTS ON)
)。
我有一堆 link 该可执行文件的插件:
foreach(plugin ${PLUGINS})
target_link_libraries(${plugin} game)
endforeach()
它们由可执行文件使用 LoadLibrary
/dlopen
动态加载。
当我在 Visual Studio 中按 F5 并开始游戏时,我没有重新构建已更改的插件,因为游戏不依赖于它们 - 恰恰相反。
我想执行以下操作:
foreach(plugin ${PLUGINS})
add_dependencies(game ${plugin})
endforeach()
但它在每个插件和游戏之间引入了循环依赖。如何解决我的 F5 问题?
这是一个 "chicken-and-egg" 问题,因为 game
构建将生成 plugin
所需的导入库。所以你不能在 game
.
plugin
我已经试过你的场景
如果我在
POST_BUILD
步骤中强制重建,我显然会得到一个递归构建调用:add_custom_command( TARGET game POST_BUILD COMMAND ${CMAKE_COMMAND} --build . --target ALL_BUILD --config $<CONFIG> )
如果我构建一个单独的目标作为 "runner" 目标,我可能会混淆使用我的项目的其他人:
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()
所以您关于重新使用
ALL_BUILD
目标的建议可能是最好的建议。对于自动生成所需的.user
设置,您可能会发现以下内容很有趣:CMake add_custom_target(): Run custom command using 'Debug->Start Debugging'
我已经使用以下内容来测试您的场景:
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()