include("${CMAKE_CURRENT_LIST_DIR}/third_party/asio/main.cmake") set(Aethera_Web_dependencies global::drogon global::spdlog global::magic_enum global::pfr) rcl_add_dependency_action_targets(Aethera_Web_env ${Aethera_Web_dependencies}) set_target_properties(Aethera_Web_env PROPERTIES FOLDER Aethera_Web) function(renderive_configure_frontend) if (CMAKE_CONFIGURATION_TYPES) set(assets_dir "${CMAKE_CURRENT_BINARY_DIR}/$/webapp_gallery") else () set(assets_dir "${CMAKE_CURRENT_BINARY_DIR}/webapp_gallery") endif () set(node_search_paths) if (WIN32 AND DEFINED ENV{APPDATA}) file(GLOB clion_node_versions LIST_DIRECTORIES true "$ENV{APPDATA}/JetBrains/CLion*/node/versions/*") list(SORT clion_node_versions COMPARE NATURAL ORDER DESCENDING) foreach (clion_node_version IN LISTS clion_node_versions) if (EXISTS "${clion_node_version}/node.exe" AND EXISTS "${clion_node_version}/npm.cmd") list(APPEND node_search_paths "${clion_node_version}") endif () endforeach () endif () find_program(node_executable NAMES node node.exe HINTS ${node_search_paths} REQUIRED) get_filename_component(node_dir "${node_executable}" DIRECTORY) if (WIN32) set(npm_executable "${node_dir}/npm.cmd") set(node_path "${node_dir};$ENV{PATH}") else () set(npm_executable "${node_dir}/npm") set(node_path "${node_dir}:$ENV{PATH}") endif () if (NOT EXISTS "${npm_executable}") message(FATAL_ERROR "npm was not found next to Node.js: ${node_dir}") endif () set(frontend_dir "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../webapp_gallery") set(install_stamp "${CMAKE_CURRENT_BINARY_DIR}/webapp_gallery_npm_ci.stamp") set(build_stamp "${CMAKE_CURRENT_BINARY_DIR}/webapp_gallery_vite_build.stamp") file(GLOB_RECURSE frontend_sources CONFIGURE_DEPENDS "${frontend_dir}/src/*") set(frontend_configuration "${frontend_dir}/package.json" "${frontend_dir}/package-lock.json" "${frontend_dir}/vite.config.ts" "${frontend_dir}/tsconfig.json" "${frontend_dir}/tsconfig.app.json" "${frontend_dir}/index.html") add_custom_command( OUTPUT "${install_stamp}" COMMAND "${CMAKE_COMMAND}" -E env "PATH=${node_path}" "${npm_executable}" ci COMMAND "${CMAKE_COMMAND}" -E touch "${install_stamp}" DEPENDS "${frontend_dir}/package.json" "${frontend_dir}/package-lock.json" WORKING_DIRECTORY "${frontend_dir}" COMMENT "Installing Aethera Gallery frontend dependencies" VERBATIM) add_custom_command( OUTPUT "${build_stamp}" COMMAND "${CMAKE_COMMAND}" -E env "PATH=${node_path}" "${npm_executable}" run build COMMAND "${CMAKE_COMMAND}" -E touch "${build_stamp}" DEPENDS "${install_stamp}" ${frontend_configuration} ${frontend_sources} WORKING_DIRECTORY "${frontend_dir}" COMMENT "Building Aethera Gallery frontend" VERBATIM) add_custom_target(Aethera_Web_Assets COMMAND "${CMAKE_COMMAND}" -E remove_directory "${assets_dir}" COMMAND "${CMAKE_COMMAND}" -E copy_directory "${frontend_dir}/dist" "${assets_dir}" DEPENDS "${build_stamp}" COMMENT "Synchronizing Aethera Gallery frontend assets" VERBATIM) endfunction() function(renderive_find_web_dependencies) if (POLICY CMP0144) cmake_policy(SET CMP0144 NEW) endif () rcl_load_dependency_environment(${Aethera_Web_dependencies}) find_package(Drogon CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) find_package(magic_enum CONFIG REQUIRED) endfunction() renderive_configure_frontend() library_get_missing_with_rely(Aethera_Web_dependencies_missing ${Aethera_Web_dependencies}) if (Aethera_Web_dependencies_missing) rcl_log_append(${CMAKE_CURRENT_LIST_LINE} "[FATAL_ERROR] Aethera_Web dependencies\n${Aethera_Web_dependencies_missing}\n are not installed. Build Aethera_Web_env first") return() endif () renderive_find_web_dependencies() if (NOT TARGET Aethera_render_2D) rcl_log_append(${CMAKE_CURRENT_LIST_LINE} "[FATAL_ERROR] Aethera_Web requires Aethera_render_2D") return() endif () if (NOT TARGET Aethera_render_3D) rcl_log_append(${CMAKE_CURRENT_LIST_LINE} "[FATAL_ERROR] Aethera_Web requires Aethera_render_3D") return() endif () if (NOT TARGET Adminive::Nlohmann) set(Aethera_Web_saved_build_testing "${BUILD_TESTING}") set(BUILD_TESTING OFF) add_subdirectory( "${CMAKE_CURRENT_LIST_DIR}/../third_party/Adminive" "${CMAKE_CURRENT_BINARY_DIR}/third_party/Adminive" EXCLUDE_FROM_ALL) set(BUILD_TESTING "${Aethera_Web_saved_build_testing}") unset(Aethera_Web_saved_build_testing) endif () set(Aethera_Web_source_dir "${CMAKE_CURRENT_LIST_DIR}/src") append_glob_source(Aethera_Web_sources "${Aethera_Web_source_dir}") add_executable(Aethera_Web_Server ${Aethera_Web_sources}) target_include_directories(Aethera_Web_Server PRIVATE "$" "$") target_compile_features(Aethera_Web_Server PRIVATE cxx_std_20) target_compile_definitions(Aethera_Web_Server PRIVATE NOMINMAX) target_link_libraries(Aethera_Web_Server PRIVATE Aethera_render_2D Aethera_render_3D Drogon::Drogon spdlog::spdlog Adminive::Nlohmann Adminive::MagicEnum magic_enum::magic_enum asio_object) add_dependencies(Aethera_Web_Server Aethera_Web_Assets) if (MSVC) target_compile_options(Aethera_Web_Server PRIVATE /utf-8) endif ()