launcher_generator.cmake 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. #
  2. # Copyright (c) Contributors to the Open 3D Engine Project.
  3. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. #
  5. # SPDX-License-Identifier: Apache-2.0 OR MIT
  6. #
  7. #
  8. # This will be used to turn on "PerMonitor" DPI scaling support. (Currently there is no way in CMake to specify "PerMonitorV2")
  9. set(O3DE_DPI_AWARENESS "PerMonitor")
  10. set_property(GLOBAL PROPERTY LAUNCHER_UNIFIED_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
  11. # Launcher targets for a project need to be generated when configuring a project.
  12. # When building the engine source, this file will be included by LauncherUnified's CMakeLists.txt
  13. # When using an installed engine, this file will be included by the FindLauncherGenerator.cmake script
  14. get_property(O3DE_PROJECTS_NAME GLOBAL PROPERTY O3DE_PROJECTS_NAME)
  15. foreach(project_name project_path IN ZIP_LISTS O3DE_PROJECTS_NAME LY_PROJECTS)
  16. # Computes the realpath to the project
  17. # If the project_path is relative, it is evaluated relative to the ${LY_ROOT_FOLDER}
  18. # Otherwise the the absolute project_path is returned with symlinks resolved
  19. file(REAL_PATH ${project_path} project_real_path BASE_DIRECTORY ${LY_ROOT_FOLDER})
  20. ################################################################################
  21. # Assets
  22. ################################################################################
  23. if(PAL_TRAIT_BUILD_HOST_TOOLS)
  24. add_custom_target(${project_name}.Assets
  25. COMMENT "Processing ${project_name} assets..."
  26. COMMAND "${CMAKE_COMMAND}"
  27. -DLY_LOCK_FILE=$<GENEX_EVAL:$<TARGET_FILE_DIR:AZ::AssetProcessorBatch>>/project_assets.lock
  28. -P ${LY_ROOT_FOLDER}/cmake/CommandExecution.cmake
  29. EXEC_COMMAND $<GENEX_EVAL:$<TARGET_FILE:AZ::AssetProcessorBatch>>
  30. --zeroAnalysisMode
  31. --project-path=${project_real_path}
  32. --platforms=${LY_ASSET_DEPLOY_ASSET_TYPE}
  33. )
  34. set_target_properties(${project_name}.Assets
  35. PROPERTIES
  36. EXCLUDE_FROM_ALL TRUE
  37. FOLDER ${project_name}
  38. )
  39. endif()
  40. ################################################################################
  41. # Monolithic game
  42. ################################################################################
  43. if(LY_MONOLITHIC_GAME)
  44. # In the monolithic case, we need to register the gem modules, to do so we will generate a StaticModules.inl
  45. # file from StaticModules.in
  46. set_property(GLOBAL APPEND PROPERTY LY_STATIC_MODULE_PROJECTS_NAME ${project_name})
  47. get_property(game_gem_dependencies GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_${project_name}.GameLauncher)
  48. set(game_build_dependencies
  49. ${game_gem_dependencies}
  50. Legacy::CrySystem
  51. )
  52. if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
  53. get_property(server_gem_dependencies GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_${project_name}.ServerLauncher)
  54. set(server_build_dependencies
  55. ${server_gem_dependencies}
  56. Legacy::CrySystem
  57. )
  58. endif()
  59. if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
  60. get_property(unified_gem_dependencies GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_${project_name}.UnifiedLauncher)
  61. set(unified_build_dependencies
  62. ${unified_gem_dependencies}
  63. Legacy::CrySystem
  64. )
  65. endif()
  66. else()
  67. set(game_runtime_dependencies
  68. Legacy::CrySystem
  69. )
  70. if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
  71. set(server_runtime_dependencies
  72. Legacy::CrySystem
  73. )
  74. endif()
  75. if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
  76. set(unified_runtime_dependencies
  77. Legacy::CrySystem
  78. )
  79. endif()
  80. endif()
  81. ################################################################################
  82. # Game
  83. ################################################################################
  84. ly_add_target(
  85. NAME ${project_name}.GameLauncher ${PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE}
  86. NAMESPACE AZ
  87. FILES_CMAKE
  88. ${CMAKE_CURRENT_LIST_DIR}/launcher_project_files.cmake
  89. PLATFORM_INCLUDE_FILES
  90. ${pal_dir}/launcher_project_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
  91. COMPILE_DEFINITIONS
  92. PRIVATE
  93. # Adds the name of the project/game
  94. LY_PROJECT_NAME="${project_name}"
  95. # Adds the ${project_name}_GameLauncher target as a define so for the Settings Registry to use
  96. # when loading .setreg file specializations
  97. # This is needed so that only gems for the project game launcher are loaded
  98. LY_CMAKE_TARGET="${project_name}_GameLauncher"
  99. INCLUDE_DIRECTORIES
  100. PRIVATE
  101. .
  102. ${CMAKE_CURRENT_BINARY_DIR}/${project_name}.GameLauncher/Includes # required for StaticModules.inl
  103. BUILD_DEPENDENCIES
  104. PRIVATE
  105. AZ::Launcher.Static
  106. AZ::Launcher.Game.Static
  107. ${game_build_dependencies}
  108. RUNTIME_DEPENDENCIES
  109. ${game_runtime_dependencies}
  110. )
  111. # Needs to be set manually after ly_add_target to prevent the default location overriding it
  112. set_target_properties(${project_name}.GameLauncher
  113. PROPERTIES
  114. FOLDER ${project_name}
  115. LY_PROJECT_NAME ${project_name}
  116. )
  117. # Turn on DPI scaling support.
  118. set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DPI_AWARE ${O3DE_DPI_AWARENESS})
  119. if(LY_DEFAULT_PROJECT_PATH)
  120. if (TARGET ${project_name})
  121. get_target_property(project_game_launcher_additional_args ${project_name} GAMELAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS)
  122. if (project_game_launcher_additional_args)
  123. # Avoid pushing param-NOTFOUND into the argument in case this property wasn't found
  124. set(additional_game_vs_debugger_args "${project_game_launcher_additional_args}")
  125. endif()
  126. endif()
  127. set_property(TARGET ${project_name}.GameLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS
  128. "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${additional_game_vs_debugger_args}")
  129. endif()
  130. # Associate the Clients Gem Variant with each projects GameLauncher
  131. ly_set_gem_variant_to_load(TARGETS ${project_name}.GameLauncher VARIANTS Clients)
  132. ################################################################################
  133. # Server
  134. ################################################################################
  135. if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
  136. ly_add_target(
  137. NAME ${project_name}.ServerLauncher APPLICATION
  138. NAMESPACE AZ
  139. FILES_CMAKE
  140. ${CMAKE_CURRENT_LIST_DIR}/launcher_project_files.cmake
  141. PLATFORM_INCLUDE_FILES
  142. ${pal_dir}/launcher_project_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
  143. COMPILE_DEFINITIONS
  144. PRIVATE
  145. # Adds the name of the project/game
  146. LY_PROJECT_NAME="${project_name}"
  147. # Adds the ${project_name}_ServerLauncher target as a define so for the Settings Registry to use
  148. # when loading .setreg file specializations
  149. # This is needed so that only gems for the project server launcher are loaded
  150. LY_CMAKE_TARGET="${project_name}_ServerLauncher"
  151. INCLUDE_DIRECTORIES
  152. PRIVATE
  153. .
  154. ${CMAKE_CURRENT_BINARY_DIR}/${project_name}.ServerLauncher/Includes # required for StaticModules.inl
  155. BUILD_DEPENDENCIES
  156. PRIVATE
  157. AZ::Launcher.Static
  158. AZ::Launcher.Server.Static
  159. ${server_build_dependencies}
  160. RUNTIME_DEPENDENCIES
  161. ${server_runtime_dependencies}
  162. )
  163. # Needs to be set manually after ly_add_target to prevent the default location overriding it
  164. set_target_properties(${project_name}.ServerLauncher
  165. PROPERTIES
  166. FOLDER ${project_name}
  167. LY_PROJECT_NAME ${project_name}
  168. )
  169. # Turn on DPI scaling support.
  170. set_property(TARGET ${project_name}.ServerLauncher APPEND PROPERTY VS_DPI_AWARE ${O3DE_DPI_AWARENESS})
  171. if(LY_DEFAULT_PROJECT_PATH)
  172. if (TARGET ${project_name})
  173. get_target_property(project_server_launcher_additional_args ${project_name} SERVERLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS)
  174. if (project_server_launcher_additional_args)
  175. # Avoid pushing param-NOTFOUND into the argument in case this property wasn't found
  176. set(additional_server_vs_debugger_args "${project_server_launcher_additional_args}")
  177. endif()
  178. endif()
  179. set_property(TARGET ${project_name}.ServerLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS
  180. "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${additional_server_vs_debugger_args}")
  181. endif()
  182. # Associate the Servers Gem Variant with each projects ServerLauncher
  183. ly_set_gem_variant_to_load(TARGETS ${project_name}.ServerLauncher VARIANTS Servers)
  184. # If the Editor is getting built, it should rebuild the ServerLauncher as well. The Editor's game mode will attempt
  185. # to launch it, and things can break if the two are out of sync.
  186. if(PAL_TRAIT_BUILD_HOST_TOOLS)
  187. ly_add_dependencies(Editor ${project_name}.ServerLauncher)
  188. endif()
  189. endif()
  190. ################################################################################
  191. # Unified
  192. ################################################################################
  193. if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
  194. ly_add_target(
  195. NAME ${project_name}.UnifiedLauncher APPLICATION
  196. NAMESPACE AZ
  197. FILES_CMAKE
  198. ${CMAKE_CURRENT_LIST_DIR}/launcher_project_files.cmake
  199. PLATFORM_INCLUDE_FILES
  200. ${pal_dir}/launcher_project_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
  201. COMPILE_DEFINITIONS
  202. PRIVATE
  203. # Adds the name of the project/game
  204. LY_PROJECT_NAME="${project_name}"
  205. # Adds the ${project_name}_UnifiedLauncher target as a define so for the Settings Registry to use
  206. # when loading .setreg file specializations
  207. # This is needed so that only gems for the project unified launcher are loaded
  208. LY_CMAKE_TARGET="${project_name}_UnifiedLauncher"
  209. INCLUDE_DIRECTORIES
  210. PRIVATE
  211. .
  212. ${CMAKE_CURRENT_BINARY_DIR}/${project_name}.UnifiedLauncher/Includes # required for StaticModules.inl
  213. BUILD_DEPENDENCIES
  214. PRIVATE
  215. AZ::Launcher.Static
  216. AZ::Launcher.Unified.Static
  217. ${unified_build_dependencies}
  218. RUNTIME_DEPENDENCIES
  219. ${unified_runtime_dependencies}
  220. )
  221. # Needs to be set manually after ly_add_target to prevent the default location overriding it
  222. set_target_properties(${project_name}.UnifiedLauncher
  223. PROPERTIES
  224. FOLDER ${project_name}
  225. LY_PROJECT_NAME ${project_name}
  226. )
  227. # Turn on DPI scaling support.
  228. set_property(TARGET ${project_name}.UnifiedLauncher APPEND PROPERTY VS_DPI_AWARE ${O3DE_DPI_AWARENESS})
  229. if(LY_DEFAULT_PROJECT_PATH)
  230. if (TARGET ${project_name})
  231. get_target_property(project_unified_launcher_additional_args ${project_name} UNIFIEDLAUNCHER_ADDITIONAL_VS_DEBUGGER_COMMAND_ARGUMENTS)
  232. if (project_unified_launcher_additional_args)
  233. # Avoid pushing param-NOTFOUND into the argument in case this property wasn't found
  234. set(additional_unified_vs_debugger_args "${project_unified_launcher_additional_args}")
  235. endif()
  236. endif()
  237. set_property(TARGET ${project_name}.UnifiedLauncher APPEND PROPERTY VS_DEBUGGER_COMMAND_ARGUMENTS
  238. "--project-path=\"${LY_DEFAULT_PROJECT_PATH}\" ${additional_unified_vs_debugger_args}")
  239. endif()
  240. # Associate the Unified Gem Variant with each projects UnfiedLauncher
  241. ly_set_gem_variant_to_load(TARGETS ${project_name}.UnifiedLauncher VARIANTS Unified)
  242. endif()
  243. endforeach()
  244. #! Defer generation of the StaticModules.inl file needed in monolithic builds until after all the CMake targets are known
  245. # This is that the GEM_MODULE target runtime dependencies can be parsed to discover the list of dependent modules
  246. # to load
  247. function(ly_delayed_generate_static_modules_inl)
  248. if(LY_MONOLITHIC_GAME)
  249. get_property(launcher_unified_binary_dir GLOBAL PROPERTY LAUNCHER_UNIFIED_BINARY_DIR)
  250. get_property(project_names GLOBAL PROPERTY LY_STATIC_MODULE_PROJECTS_NAME)
  251. foreach(project_name ${project_names})
  252. unset(extern_module_declarations)
  253. unset(module_invocations)
  254. unset(all_game_gem_dependencies)
  255. o3de_get_gem_load_dependencies(
  256. GEM_LOAD_DEPENDENCIES_VAR all_game_gem_dependencies
  257. TARGET "${project_name}.GameLauncher")
  258. foreach(game_gem_dependency ${all_game_gem_dependencies})
  259. # Sometimes, a gem's Client variant may be an interface library
  260. # which depends on multiple gem targets. The interface libraries
  261. # should be skipped; the real dependencies of the interface will be processed
  262. if(TARGET ${game_gem_dependency})
  263. get_target_property(target_type ${game_gem_dependency} TYPE)
  264. if(${target_type} STREQUAL "INTERFACE_LIBRARY")
  265. continue()
  266. endif()
  267. endif()
  268. # To match the convention on how gems targets vs gem modules are named,
  269. # we remove the ".Static" from the suffix
  270. # Replace "." with "_"
  271. string(REPLACE "." "_" game_gem_dependency ${game_gem_dependency})
  272. string(APPEND extern_module_declarations "extern \"C\" AZ::Module* CreateModuleClass_Gem_${game_gem_dependency}();\n")
  273. string(APPEND module_invocations " modulesOut.push_back(CreateModuleClass_Gem_${game_gem_dependency}());\n")
  274. endforeach()
  275. configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/StaticModules.in
  276. ${launcher_unified_binary_dir}/${project_name}.GameLauncher/Includes/StaticModules.inl
  277. )
  278. ly_target_link_libraries(${project_name}.GameLauncher PRIVATE ${all_game_gem_dependencies})
  279. if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
  280. unset(extern_module_declarations)
  281. unset(module_invocations)
  282. unset(all_server_gem_dependencies)
  283. o3de_get_gem_load_dependencies(
  284. GEM_LOAD_DEPENDENCIES_VAR all_server_gem_dependencies
  285. TARGET "${project_name}.ServerLauncher")
  286. foreach(server_gem_dependency ${all_server_gem_dependencies})
  287. # Skip interface libraries
  288. if(TARGET ${server_gem_dependency})
  289. get_target_property(target_type ${server_gem_dependency} TYPE)
  290. if(${target_type} STREQUAL "INTERFACE_LIBRARY")
  291. continue()
  292. endif()
  293. endif()
  294. # Replace "." with "_"
  295. string(REPLACE "." "_" server_gem_dependency ${server_gem_dependency})
  296. string(APPEND extern_module_declarations "extern \"C\" AZ::Module* CreateModuleClass_Gem_${server_gem_dependency}();\n")
  297. string(APPEND module_invocations " modulesOut.push_back(CreateModuleClass_Gem_${server_gem_dependency}());\n")
  298. endforeach()
  299. configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/StaticModules.in
  300. ${launcher_unified_binary_dir}/${project_name}.ServerLauncher/Includes/StaticModules.inl
  301. )
  302. ly_target_link_libraries(${project_name}.ServerLauncher PRIVATE ${all_server_gem_dependencies})
  303. endif()
  304. if(PAL_TRAIT_BUILD_UNIFIED_SUPPORTED)
  305. unset(extern_module_declarations)
  306. unset(module_invocations)
  307. unset(all_unified_gem_dependencies)
  308. o3de_get_gem_load_dependencies(
  309. GEM_LOAD_DEPENDENCIES_VAR all_unified_gem_dependencies
  310. TARGET "${project_name}.UnifiedLauncher")
  311. foreach(unified_gem_dependency ${all_unified_gem_dependencies})
  312. # Skip interface libraries
  313. if(TARGET ${unified_gem_dependency})
  314. get_target_property(target_type ${unified_gem_dependency} TYPE)
  315. if(${target_type} STREQUAL "INTERFACE_LIBRARY")
  316. continue()
  317. endif()
  318. endif()
  319. # Replace "." with "_"
  320. string(REPLACE "." "_" unified_gem_dependency ${unified_gem_dependency})
  321. string(APPEND extern_module_declarations "extern \"C\" AZ::Module* CreateModuleClass_Gem_${unified_gem_dependency}();\n")
  322. string(APPEND module_invocations " modulesOut.push_back(CreateModuleClass_Gem_${unified_gem_dependency}());\n")
  323. endforeach()
  324. configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/StaticModules.in
  325. ${launcher_unified_binary_dir}/${project_name}.UnifiedLauncher/Includes/StaticModules.inl
  326. )
  327. ly_target_link_libraries(${project_name}.UnifiedLauncher PRIVATE ${all_unified_gem_dependencies})
  328. endif()
  329. endforeach()
  330. endif()
  331. endfunction()