initial commit

This commit is contained in:
2026-09-21 13:41:40 +09:00
commit 855c7328df
411 changed files with 85352 additions and 0 deletions
+123
View File
@@ -0,0 +1,123 @@
# Script API: -DWORKER_EXECUTABLE=<absolute exe> -DRUNTIME_FILES=<absolute list>
# Include API: docview_write_windows_runtime_manifest(executable "${files}").
# This writer validates the package inventory, not the PE import table. The
# native dependency scanner is StageWindowsWorker.cmake.
cmake_minimum_required(VERSION 3.24)
include_guard(GLOBAL)
function(docview_runtime_file_info path kind out_name out_size)
if(NOT IS_ABSOLUTE "${path}" OR NOT EXISTS "${path}" OR IS_DIRECTORY "${path}" OR IS_SYMLINK "${path}")
message(FATAL_ERROR "Worker runtime requires an absolute regular file: ${path}")
endif()
get_filename_component(name "${path}" NAME)
string(LENGTH "${name}" length)
string(TOLOWER "${name}" folded)
if(length GREATER 128 OR NOT name MATCHES "^[A-Za-z0-9][A-Za-z0-9._-]*$" OR
name MATCHES "[.]$" OR folded MATCHES "^(con|prn|aux|nul|com[1-9]|lpt[1-9])([.]|$)")
message(FATAL_ERROR "Invalid Windows runtime filename: ${name}")
endif()
if((kind STREQUAL "EXE" AND NOT folded MATCHES "[.]exe$") OR
(kind STREQUAL "DLL" AND NOT folded MATCHES "[.]dll$"))
message(FATAL_ERROR "Only the worker executable and DLLs may enter its runtime: ${name}")
endif()
file(SIZE "${path}" size)
if(size LESS 2 OR size GREATER 268435456)
message(FATAL_ERROR "Worker runtime file exceeds the 256 MiB limit or is empty: ${name}")
endif()
file(READ "${path}" signature LIMIT 2 HEX)
if(NOT signature STREQUAL "4d5a")
message(FATAL_ERROR "Worker runtime file has no MZ signature: ${name}")
endif()
set(${out_name} "${name}" PARENT_SCOPE)
set(${out_size} "${size}" PARENT_SCOPE)
endfunction()
function(docview_write_windows_runtime_manifest executable files)
docview_runtime_file_info("${executable}" EXE executable_name executable_size)
file(REAL_PATH "${executable}" executable_real)
get_filename_component(directory "${executable_real}" DIRECTORY)
if(WIN32)
string(TOLOWER "${directory}" directory)
endif()
list(LENGTH files count)
if(count LESS 1 OR count GREATER 128)
message(FATAL_ERROR "Worker runtime inventory must contain 1..128 files")
endif()
set(seen)
set(total 0)
set(has_executable FALSE)
# Check every limit before hashing potentially large files or changing an
# existing manifest. File order does not affect the serialized inventory.
foreach(path IN LISTS files)
get_filename_component(name "${path}" NAME)
if(name STREQUAL executable_name)
set(kind EXE)
else()
set(kind DLL)
endif()
docview_runtime_file_info("${path}" "${kind}" name size)
file(REAL_PATH "${path}" real)
get_filename_component(parent "${real}" DIRECTORY)
if(WIN32)
string(TOLOWER "${parent}" parent)
endif()
if(NOT parent STREQUAL directory)
message(FATAL_ERROR "Manifest entries must already be beside the worker: ${name}")
endif()
string(TOLOWER "${name}" key)
if(key IN_LIST seen)
message(FATAL_ERROR "Case-insensitive duplicate worker runtime filename: ${name}")
endif()
list(APPEND seen "${key}")
if(name STREQUAL executable_name)
if(NOT real STREQUAL executable_real)
message(FATAL_ERROR "Manifest executable does not match its worker")
endif()
set(has_executable TRUE)
endif()
math(EXPR total "${total} + ${size}")
if(total GREATER 536870912)
message(FATAL_ERROR "Worker runtime exceeds the 512 MiB aggregate limit")
endif()
endforeach()
if(NOT has_executable)
message(FATAL_ERROR "Worker runtime manifest must include its executable")
endif()
list(SORT files CASE INSENSITIVE)
set(entries)
foreach(path IN LISTS files)
get_filename_component(name "${path}" NAME)
file(SIZE "${path}" size)
file(SHA256 "${path}" digest)
string(TOLOWER "${digest}" digest)
list(APPEND entries " {\"path\":\"${name}\",\"sha256\":\"${digest}\",\"size\":${size}}")
endforeach()
list(JOIN entries ",\n" entries_json)
set(json "{\n \"schemaVersion\":1,\n \"executable\":\"${executable_name}\",\n \"files\":[\n${entries_json}\n ]\n}\n")
string(LENGTH "${json}" json_size)
if(json_size GREATER 131072)
message(FATAL_ERROR "Worker runtime manifest exceeds its 128 KiB limit")
endif()
set(output "${executable}.runtime.json")
if(IS_SYMLINK "${output}" OR IS_DIRECTORY "${output}")
message(FATAL_ERROR "Refusing a non-regular worker runtime manifest destination")
endif()
string(RANDOM LENGTH 24 ALPHABET 0123456789abcdef nonce)
set(temporary "${output}.${nonce}.tmp")
if(EXISTS "${temporary}" OR IS_SYMLINK "${temporary}")
message(FATAL_ERROR "Worker runtime manifest temporary path already exists")
endif()
file(WRITE "${temporary}" "${json}")
file(RENAME "${temporary}" "${output}" RESULT renamed)
if(NOT renamed STREQUAL "0")
file(REMOVE "${temporary}")
message(FATAL_ERROR "Cannot atomically publish worker runtime manifest: ${renamed}")
endif()
endfunction()
if(CMAKE_SCRIPT_MODE_FILE STREQUAL CMAKE_CURRENT_LIST_FILE)
if(NOT DEFINED WORKER_EXECUTABLE OR NOT DEFINED RUNTIME_FILES)
message(FATAL_ERROR "WORKER_EXECUTABLE and RUNTIME_FILES are required")
endif()
docview_write_windows_runtime_manifest("${WORKER_EXECUTABLE}" "${RUNTIME_FILES}")
endif()