285 lines
10 KiB
CMake
285 lines
10 KiB
CMake
# Project-level configuration.
|
|
cmake_minimum_required(VERSION 3.14)
|
|
project(cloudreve4_flutter LANGUAGES CXX)
|
|
|
|
# The name of the executable created for the application. Change this to change
|
|
# the on-disk name of your application.
|
|
set(BINARY_NAME "cloudreve4_flutter")
|
|
|
|
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
|
# versions of CMake.
|
|
cmake_policy(VERSION 3.14...3.25)
|
|
|
|
# Define build configuration option.
|
|
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
if(IS_MULTICONFIG)
|
|
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
|
|
CACHE STRING "" FORCE)
|
|
else()
|
|
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
set(CMAKE_BUILD_TYPE "Debug" CACHE
|
|
STRING "Flutter build mode" FORCE)
|
|
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
|
"Debug" "Profile" "Release")
|
|
endif()
|
|
endif()
|
|
# Define settings for the Profile build mode.
|
|
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
|
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
|
|
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
|
|
set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
|
|
|
|
# Use Unicode for all projects.
|
|
add_definitions(-DUNICODE -D_UNICODE)
|
|
|
|
# flutter_inappwebview_windows requires NuGet. The plugin's own CMake only
|
|
# calls find_program(NUGET nuget), so seed the cache with an absolute path.
|
|
if(DEFINED NUGET AND NOT NUGET STREQUAL "" AND NOT NUGET STREQUAL "NUGET-NOTFOUND")
|
|
if(NOT EXISTS "${NUGET}")
|
|
unset(NUGET CACHE)
|
|
unset(NUGET)
|
|
endif()
|
|
endif()
|
|
|
|
if(NOT DEFINED NUGET OR NUGET STREQUAL "" OR NUGET STREQUAL "NUGET-NOTFOUND")
|
|
set(_NUGET_CANDIDATES
|
|
"$ENV{SystemRoot}/System32/nuget.exe"
|
|
"$ENV{windir}/System32/nuget.exe"
|
|
"C:/Windows/System32/nuget.exe"
|
|
"$ENV{SystemRoot}/Sysnative/nuget.exe"
|
|
"$ENV{windir}/Sysnative/nuget.exe"
|
|
"C:/Windows/Sysnative/nuget.exe"
|
|
"$ENV{USERPROFILE}/.local/bin/nuget.exe"
|
|
"$ENV{LOCALAPPDATA}/Microsoft/WinGet/Links/nuget.exe"
|
|
"C:/ProgramData/chocolatey/bin/nuget.exe"
|
|
)
|
|
foreach(_NUGET_CANDIDATE IN LISTS _NUGET_CANDIDATES)
|
|
if(EXISTS "${_NUGET_CANDIDATE}")
|
|
set(NUGET "${_NUGET_CANDIDATE}")
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
if(NOT DEFINED NUGET OR NUGET STREQUAL "" OR NUGET STREQUAL "NUGET-NOTFOUND")
|
|
find_program(NUGET NAMES nuget.exe nuget)
|
|
endif()
|
|
|
|
if(NUGET AND NOT NUGET STREQUAL "NUGET-NOTFOUND")
|
|
set(_PROJECT_NUGET "${CMAKE_BINARY_DIR}/nuget.exe")
|
|
execute_process(
|
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${NUGET}" "${_PROJECT_NUGET}"
|
|
RESULT_VARIABLE _NUGET_COPY_RESULT
|
|
)
|
|
if(_NUGET_COPY_RESULT EQUAL 0 AND EXISTS "${_PROJECT_NUGET}")
|
|
set(NUGET "${_PROJECT_NUGET}")
|
|
else()
|
|
message(WARNING "Failed to copy NuGet to ${_PROJECT_NUGET}; using ${NUGET}")
|
|
endif()
|
|
message(STATUS "Found NuGet: ${NUGET}")
|
|
set(NUGET "${NUGET}" CACHE FILEPATH "nuget executable" FORCE)
|
|
else()
|
|
message(WARNING "NuGet executable was not found. Windows WebView builds may fail.")
|
|
endif()
|
|
|
|
# Compilation settings that should be applied to most targets.
|
|
#
|
|
# Be cautious about adding new options here, as plugins use this function by
|
|
# default. In most cases, you should add new options to specific targets instead
|
|
# of modifying this function.
|
|
function(APPLY_STANDARD_SETTINGS TARGET)
|
|
target_compile_features(${TARGET} PUBLIC cxx_std_17)
|
|
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
|
|
target_compile_options(${TARGET} PRIVATE /EHsc)
|
|
target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
|
|
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
|
|
endfunction()
|
|
|
|
# Flutter library and tool build rules.
|
|
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
|
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
|
|
|
# Application build; see runner/CMakeLists.txt.
|
|
add_subdirectory("runner")
|
|
|
|
|
|
# media_kit_libs_windows_video downloads its native archives with CMake's
|
|
# file(DOWNLOAD). In some Windows network/proxy setups that leaves 0-byte files
|
|
# without surfacing the download failure, so prefetch the exact archives with
|
|
# PowerShell and let the plugin's own CMake verify/use them.
|
|
function(ENSURE_WINDOWS_ARCHIVE URL MD5 OUTPUT_PATH)
|
|
string(TOLOWER "${MD5}" EXPECTED_MD5)
|
|
if(EXISTS "${OUTPUT_PATH}")
|
|
file(MD5 "${OUTPUT_PATH}" CURRENT_MD5)
|
|
string(TOLOWER "${CURRENT_MD5}" CURRENT_MD5)
|
|
if(EXPECTED_MD5 STREQUAL CURRENT_MD5)
|
|
return()
|
|
endif()
|
|
file(REMOVE "${OUTPUT_PATH}")
|
|
endif()
|
|
|
|
find_program(POWERSHELL_EXE powershell.exe)
|
|
if(NOT POWERSHELL_EXE)
|
|
find_program(POWERSHELL_EXE pwsh)
|
|
endif()
|
|
if(NOT POWERSHELL_EXE)
|
|
message(FATAL_ERROR "PowerShell is required to download ${URL}")
|
|
endif()
|
|
|
|
get_filename_component(OUTPUT_DIR "${OUTPUT_PATH}" DIRECTORY)
|
|
file(MAKE_DIRECTORY "${OUTPUT_DIR}")
|
|
|
|
message(STATUS "Downloading ${URL}")
|
|
execute_process(
|
|
COMMAND "${POWERSHELL_EXE}" -NoProfile -ExecutionPolicy Bypass -Command
|
|
"$ProgressPreference='SilentlyContinue'; Invoke-WebRequest -Uri '${URL}' -OutFile '${OUTPUT_PATH}' -UseBasicParsing"
|
|
RESULT_VARIABLE DOWNLOAD_RESULT
|
|
)
|
|
if(NOT DOWNLOAD_RESULT EQUAL 0)
|
|
message(FATAL_ERROR "Failed to download ${URL}")
|
|
endif()
|
|
|
|
file(MD5 "${OUTPUT_PATH}" CURRENT_MD5)
|
|
string(TOLOWER "${CURRENT_MD5}" CURRENT_MD5)
|
|
if(NOT EXPECTED_MD5 STREQUAL CURRENT_MD5)
|
|
file(REMOVE "${OUTPUT_PATH}")
|
|
message(FATAL_ERROR "Downloaded ${OUTPUT_PATH} failed MD5 check")
|
|
endif()
|
|
endfunction()
|
|
|
|
ENSURE_WINDOWS_ARCHIVE(
|
|
"https://github.com/media-kit/libmpv-win32-video-build/releases/download/2023-09-24/mpv-dev-x86_64-20230924-git-652a1dd.7z"
|
|
"a832ef24b3a6ff97cd2560b5b9d04cd8"
|
|
"${CMAKE_BINARY_DIR}/mpv-dev-x86_64-20230924-git-652a1dd.7z"
|
|
)
|
|
ENSURE_WINDOWS_ARCHIVE(
|
|
"https://github.com/alexmercerind/flutter-windows-ANGLE-OpenGL-ES/releases/download/v1.0.1/ANGLE.7z"
|
|
"e866f13e8d552348058afaafe869b1ed"
|
|
"${CMAKE_BINARY_DIR}/ANGLE.7z"
|
|
)
|
|
|
|
# Generated plugin build rules, which manage building the plugins and adding
|
|
# them to the application.
|
|
if(POLICY CMP0175)
|
|
# flutter_inappwebview_windows 0.7.0-beta.3 passes DEPENDS to the TARGET
|
|
# form of add_custom_command. Keep older CMake behavior for plugins that do
|
|
# not set this policy themselves.
|
|
set(CMAKE_POLICY_DEFAULT_CMP0175 OLD)
|
|
endif()
|
|
include(flutter/generated_plugins.cmake)
|
|
|
|
if(MSVC)
|
|
if(TARGET flutter_inappwebview_windows_plugin)
|
|
# flutter_inappwebview 插件有很多 MSVC 警告, 屏蔽该插件不输出任何警告
|
|
target_compile_options(flutter_inappwebview_windows_plugin PRIVATE /W0)
|
|
endif()
|
|
endif()
|
|
|
|
# === Installation ===
|
|
# Support files are copied into place next to the executable, so that it can
|
|
# run in place. This is done instead of making a separate bundle (as on Linux)
|
|
# so that building and running from within Visual Studio will work.
|
|
set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")
|
|
# Make the "install" step default, as it's required to run.
|
|
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
|
|
#if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
# set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
|
|
#endif()
|
|
|
|
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
|
|
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
|
|
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
|
|
|
|
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
|
|
COMPONENT Runtime)
|
|
|
|
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
|
COMPONENT Runtime)
|
|
|
|
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
COMPONENT Runtime)
|
|
|
|
if(PLUGIN_BUNDLED_LIBRARIES)
|
|
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
|
|
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
COMPONENT Runtime)
|
|
endif()
|
|
|
|
# Copy the native assets provided by the build.dart from all packages.
|
|
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/")
|
|
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
|
|
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
COMPONENT Runtime)
|
|
|
|
# Fully re-copy the assets directory on each build to avoid having stale files
|
|
# from a previous install.
|
|
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
|
|
install(CODE "
|
|
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
|
|
" COMPONENT Runtime)
|
|
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
|
|
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
|
|
|
|
# Install the AOT library on non-Debug builds only.
|
|
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
|
CONFIGURATIONS Profile;Release
|
|
COMPONENT Runtime)
|
|
|
|
# === Rust Sync Engine ===
|
|
find_program(CARGO_CMD cargo
|
|
PATHS
|
|
"$ENV{USERPROFILE}\\.cargo\\bin"
|
|
"$ENV{HOME}\\.cargo\\bin"
|
|
"$ENV{CARGO_HOME}\\bin"
|
|
NO_DEFAULT_PATH
|
|
)
|
|
if(NOT CARGO_CMD)
|
|
find_program(CARGO_CMD cargo)
|
|
endif()
|
|
|
|
if(NOT CARGO_CMD)
|
|
message(WARNING "cargo not found, skipping Rust sync engine build")
|
|
else()
|
|
set(SYNC_CORE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../native")
|
|
set(RUST_TARGET_DIR "${CMAKE_BINARY_DIR}/rust_target")
|
|
|
|
# 1. 编译时间戳文件
|
|
set(RUST_BUILD_STAMP "${CMAKE_CURRENT_BINARY_DIR}/sync_core_build.stamp")
|
|
|
|
# 2. 核心修复
|
|
# 不管是 Debug 还是 Release,我们都同时通知 Cargo 去检查这两个配置。
|
|
# 这样没有任何动态变量,参数数量是死死固定的,Cargo 100% 不会报错。
|
|
add_custom_command(
|
|
OUTPUT "${RUST_BUILD_STAMP}"
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory "${RUST_TARGET_DIR}"
|
|
|
|
# 无论如何,都去编译 Debug(供 flutter run 使用)
|
|
COMMAND ${CARGO_CMD} build
|
|
--manifest-path "${SYNC_CORE_DIR}/Cargo.toml"
|
|
--target-dir "${RUST_TARGET_DIR}"
|
|
--features sync-core/windows-cfapi
|
|
|
|
# 无论如何,都去编译 Release(供 flutter build 使用)
|
|
COMMAND ${CARGO_CMD} build --release
|
|
--manifest-path "${SYNC_CORE_DIR}/Cargo.toml"
|
|
--target-dir "${RUST_TARGET_DIR}"
|
|
--features sync-core/windows-cfapi
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E touch "${RUST_BUILD_STAMP}"
|
|
COMMENT "Building Rust sync engine (Debug & Release)..."
|
|
VERBATIM
|
|
)
|
|
|
|
# 3. 让目标依赖时间戳
|
|
add_custom_target(sync_core_build DEPENDS "${RUST_BUILD_STAMP}")
|
|
add_dependencies(${BINARY_NAME} sync_core_build)
|
|
|
|
# 4. 动态选择文件夹名称表达式(这个表达式只在安装阶段求值,安全可靠)
|
|
set(CONFIG_DIR_EXPR "$<IF:$<OR:$<CONFIG:Release>,$<CONFIG:Profile>>,release,debug>")
|
|
|
|
# 5. 动态选择 dll 路径进行安装复制
|
|
install(FILES "${RUST_TARGET_DIR}/${CONFIG_DIR_EXPR}/sync_core.dll"
|
|
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
COMPONENT Runtime)
|
|
endif()
|