From b107f606f831a882146398e67fa4ebc0f6b073b2 Mon Sep 17 00:00:00 2001 From: Karim Shamazov Date: Mon, 29 Jun 2026 16:41:01 +0300 Subject: [PATCH] add php_code_commit_hash --- compiler/code-gen/files/init-scripts.cpp | 113 +++++++++++------------ compiler/compiler-settings.h | 1 + compiler/kphp2cpp.cpp | 2 + 3 files changed, 55 insertions(+), 61 deletions(-) diff --git a/compiler/code-gen/files/init-scripts.cpp b/compiler/code-gen/files/init-scripts.cpp index 682fe320f0..b7562c2af5 100644 --- a/compiler/code-gen/files/init-scripts.cpp +++ b/compiler/code-gen/files/init-scripts.cpp @@ -5,8 +5,11 @@ #include "compiler/code-gen/files/init-scripts.h" #include +#include #include +#include "common/algorithms/string-algorithms.h" + #include "compiler/code-gen/common.h" #include "compiler/code-gen/const-globals-batched-mem.h" #include "compiler/code-gen/declarations.h" @@ -19,10 +22,10 @@ #include "compiler/data/src-file.h" struct StaticInit { - void compile(CodeGenerator &W) const; + void compile(CodeGenerator& W) const; }; -void StaticInit::compile(CodeGenerator &W) const { +void StaticInit::compile(CodeGenerator& W) const { if (G->is_output_mode_lib() || G->is_output_mode_k2_lib()) { return; } @@ -51,7 +54,7 @@ void StaticInit::compile(CodeGenerator &W) const { if (!G->is_output_mode_k2()) { FunctionSignatureGenerator(W) << ("char **get_runtime_options([[maybe_unused]] int *count)") << BEGIN; - const auto &runtime_opts = G->get_kphp_runtime_opts(); + const auto& runtime_opts = G->get_kphp_runtime_opts(); if (runtime_opts.empty()) { W << "return nullptr;" << NL; } else { @@ -90,27 +93,27 @@ void StaticInit::compile(CodeGenerator &W) const { FunctionSignatureGenerator(W) << "void const_vars_check_reference_counter()" << SemicolonAndNL() << NL; W << "const_vars_check_reference_counter();" << NL; - } + } W << NL; FunctionSignatureGenerator(W) << "void " << ShapeKeys::get_function_name() << "()" << SemicolonAndNL(); W << ShapeKeys::get_function_name() << "();" << NL; - const auto &ffi = G->get_ffi_root(); - const auto &ffi_shared_libs = ffi.get_shared_libs(); + const auto& ffi = G->get_ffi_root(); + const auto& ffi_shared_libs = ffi.get_shared_libs(); if (!ffi_shared_libs.empty()) { W << "ffi_env_instance = FFIEnv{" << ffi_shared_libs.size() << ", " << ffi.get_dynamic_symbols_num() << "};" << NL; W << "ffi_env_instance.funcs.dlopen = dlopen;" << NL; W << "ffi_env_instance.funcs.dlsym = dlsym;" << NL; - for (const auto &lib : ffi_shared_libs) { + for (const auto& lib : ffi_shared_libs) { W << "ffi_env_instance.libs[" << lib.id << "].path = " << RawString{lib.path} << ";" << NL; } - const auto &ffi_scopes = ffi.get_scopes(); - for (const auto &ffi_scope : ffi_scopes) { - for (const auto &sym : ffi_scope->variables) { + const auto& ffi_scopes = ffi.get_scopes(); + for (const auto& ffi_scope : ffi_scopes) { + for (const auto& sym : ffi_scope->variables) { W << "ffi_env_instance.symbols[" << sym.env_index << "].name = \"" << sym.name() << "\";" << NL; } - for (const auto &sym : ffi_scope->functions) { + for (const auto& sym : ffi_scope->functions) { W << "ffi_env_instance.symbols[" << sym.env_index << "].name = \"" << sym.name() << "\";" << NL; } } @@ -122,9 +125,9 @@ void StaticInit::compile(CodeGenerator &W) const { struct RunInterruptedFunction { FunctionPtr function; RunInterruptedFunction(FunctionPtr function) - : function(function) {} + : function(function) {} - void compile(CodeGenerator &W) const { + void compile(CodeGenerator& W) const { std::string await_prefix = function->is_interruptible ? "co_await " : ""; std::string try_wrapper = "TRY_CALL_VOID_CORO(void, "; std::string image_kind = G->is_output_mode_k2_cli() ? "image_kind::cli" @@ -145,33 +148,31 @@ struct RunInterruptedFunction { struct RunFunction { FunctionPtr function; - RunFunction(FunctionPtr function) : function(function) {} + RunFunction(FunctionPtr function) + : function(function) {} - void compile(CodeGenerator &W) const { - FunctionSignatureGenerator(W) << "void " << FunctionName(function) << "$run() " << BEGIN - << "TRY_CALL_VOID (void, " << FunctionName(function) << "());" << NL - << "finish (0, false);" << NL - << END; + void compile(CodeGenerator& W) const { + FunctionSignatureGenerator(W) << "void " << FunctionName(function) << "$run() " << BEGIN << "TRY_CALL_VOID (void, " << FunctionName(function) << "());" + << NL << "finish (0, false);" << NL << END; W << NL; } }; - struct GlobalsResetFunction { FunctionPtr main_function; explicit GlobalsResetFunction(FunctionPtr main_function); - void compile(CodeGenerator &W) const; + void compile(CodeGenerator& W) const; }; GlobalsResetFunction::GlobalsResetFunction(FunctionPtr main_function) - : main_function(main_function) {} + : main_function(main_function) {} -void GlobalsResetFunction::compile(CodeGenerator &W) const { +void GlobalsResetFunction::compile(CodeGenerator& W) const { // "global vars reset" declarations FunctionSignatureGenerator(W) << "void global_vars_allocate(" << PhpMutableGlobalsRefArgument() << ")" << SemicolonAndNL(); FunctionSignatureGenerator(W) << "void global_vars_reset(" << PhpMutableGlobalsRefArgument() << ")" << SemicolonAndNL(); W << NL; - for (LibPtr lib: G->get_libs()) { + for (LibPtr lib : G->get_libs()) { if (lib && !lib->is_raw_php()) { W << OpenNamespace(lib->lib_namespace()); FunctionSignatureGenerator(W) << "void global_vars_allocate(" << PhpMutableGlobalsRefArgument() << ")" << SemicolonAndNL(); @@ -183,7 +184,7 @@ void GlobalsResetFunction::compile(CodeGenerator &W) const { // "global vars reset" calls FunctionSignatureGenerator(W) << "void " << FunctionName(main_function) << "$globals_reset(" << PhpMutableGlobalsRefArgument() << ")" << BEGIN; W << "global_vars_reset(php_globals);" << NL; - for (LibPtr lib: G->get_libs()) { + for (LibPtr lib : G->get_libs()) { if (lib && !lib->is_raw_php()) { W << lib->lib_namespace() << "::global_vars_reset(php_globals);" << NL; } @@ -191,45 +192,39 @@ void GlobalsResetFunction::compile(CodeGenerator &W) const { W << END << NL; } - struct LibRunFunction { FunctionPtr main_function; LibRunFunction(FunctionPtr main_function); - void compile(CodeGenerator &W) const; + void compile(CodeGenerator& W) const; }; -LibRunFunction::LibRunFunction(FunctionPtr main_function) : - main_function(main_function) { -} +LibRunFunction::LibRunFunction(FunctionPtr main_function) + : main_function(main_function) {} -void LibRunFunction::compile(CodeGenerator &W) const { +void LibRunFunction::compile(CodeGenerator& W) const { // "run" functions just calls the main file of a lib // it's guaranteed that it doesn't contain code except declarations (body_value is empty), // that's why we shouldn't deal with `if (!called)` global - W << StaticLibraryRunGlobal(gen_out_style::cpp) << BEGIN - << "using namespace " << G->get_global_namespace() << ";" << NL - << FunctionName(main_function) << "();" << NL - << END << NL << NL; + W << StaticLibraryRunGlobal(gen_out_style::cpp) << BEGIN << "using namespace " << G->get_global_namespace() << ";" << NL << FunctionName(main_function) + << "();" << NL << END << NL << NL; } +InitScriptsCpp::InitScriptsCpp(SrcFilePtr main_file_id) + : main_file_id(main_file_id) {} -InitScriptsCpp::InitScriptsCpp(SrcFilePtr main_file_id) : - main_file_id(main_file_id) {} - -void InitScriptsCpp::compile(CodeGenerator &W) const { +void InitScriptsCpp::compile(CodeGenerator& W) const { W << OpenFile("init_php_scripts.cpp", "", false); W << ExternInclude(G->settings().runtime_headers.get()); if (!G->is_output_mode_k2()) { - W << ExternInclude("server/php-init-scripts.h"); + W << ExternInclude("server/php-init-scripts.h"); } - W << Include(main_file_id->main_function->header_full_name); if (!G->get_ffi_root().get_shared_libs().empty()) { W << ExternInclude("runtime/ffi.h"); // FFI env singleton - W << ExternInclude("dlfcn.h"); // dlopen, dlsym + W << ExternInclude("dlfcn.h"); // dlopen, dlsym } W << NL << StaticInit() << NL; @@ -248,13 +243,16 @@ void InitScriptsCpp::compile(CodeGenerator &W) const { W << GlobalsResetFunction(main_file_id->main_function) << NL; if (G->is_output_mode_k2()) { - FunctionSignatureGenerator(W) << "void init_php_scripts_in_each_worker(" << PhpMutableGlobalsRefArgument() << ", kphp::coro::task<> &run" ")" << BEGIN; + FunctionSignatureGenerator(W) << "void init_php_scripts_in_each_worker(" << PhpMutableGlobalsRefArgument() + << ", kphp::coro::task<> &run" + ")" + << BEGIN; } else { FunctionSignatureGenerator(W) << "void init_php_scripts_in_each_worker(" << PhpMutableGlobalsRefArgument() << ")" << BEGIN; } W << "global_vars_allocate(php_globals);" << NL; - for (LibPtr lib: G->get_libs()) { + for (LibPtr lib : G->get_libs()) { if (lib && !lib->is_raw_php()) { W << lib->lib_namespace() << "::global_vars_allocate(php_globals);" << NL; } @@ -265,9 +263,7 @@ void InitScriptsCpp::compile(CodeGenerator &W) const { if (G->is_output_mode_k2()) { W << "run = " << FunctionName(main_file_id->main_function) << "$run();" << NL; } else { - W << "set_script (" - << FunctionName(main_file_id->main_function) << "$run, " - << FunctionName(main_file_id->main_function) << "$globals_reset);" << NL; + W << "set_script (" << FunctionName(main_file_id->main_function) << "$run, " << FunctionName(main_file_id->main_function) << "$globals_reset);" << NL; } W << END; @@ -275,7 +271,7 @@ void InitScriptsCpp::compile(CodeGenerator &W) const { W << CloseFile(); } -void LibVersionHFile::compile(CodeGenerator &W) const { +void LibVersionHFile::compile(CodeGenerator& W) const { W << OpenFile("_lib_version.h"); W << "// Runtime sha256: " << G->settings().runtime_sha256.get() << NL; W << "// CXX: " << G->settings().cxx.get() << NL; @@ -284,31 +280,26 @@ void LibVersionHFile::compile(CodeGenerator &W) const { W << CloseFile(); } -void CppMainFile::compile(CodeGenerator &W) const { +void CppMainFile::compile(CodeGenerator& W) const { kphp_assert(G->is_output_mode_server() || G->is_output_mode_cli()); W << OpenFile("main.cpp"); W << ExternInclude("server/php-engine.h") << NL; - W << "int main(int argc, char *argv[]) " << BEGIN - << "return run_main(argc, argv, php_mode::" << G->settings().mode.get() << ")" << SemicolonAndNL{} - << END; + W << "int main(int argc, char *argv[]) " << BEGIN << "return run_main(argc, argv, php_mode::" << G->settings().mode.get() << ")" << SemicolonAndNL{} << END; W << CloseFile(); } -void ComponentInfoFile::compile(CodeGenerator &W) const { +void ComponentInfoFile::compile(CodeGenerator& W) const { kphp_assert(G->is_output_mode_k2()); + kphp_assert(G->settings().php_code_commit_hash.get().size() == 40); W << OpenFile("image_info.cpp"); W << ExternInclude(G->settings().runtime_headers.get()); W << "__attribute__((visibility(\"default\"))) const ImageInfo *k2_describe() " << BEGIN - << R"(static std::array extraInfo {ImageInfo::KeyValuePair{.key = "compiler_version", .value = ")" - << G->settings().get_version() << "\"}};" << NL << "static ImageInfo imageInfo {\"" - << G->settings().k2_component_name.get() << "\"" << "," - << (G->is_output_mode_k2_multishot() ? "0" : "1") << "," - << std::to_string( - std::chrono::duration_cast(G->settings().build_tp.time_since_epoch()).count() - ) << "," + << R"(static std::array extraInfo {ImageInfo::KeyValuePair{.key = "compiler_version", .value = ")" << G->settings().get_version() << "\"}};" << NL + << "static ImageInfo imageInfo {\"" << G->settings().k2_component_name.get() << "\"" << "," << (G->is_output_mode_k2_multishot() ? "0" : "1") << "," + << std::to_string(std::chrono::duration_cast(G->settings().build_tp.time_since_epoch()).count()) << "," << "K2_PLATFORM_HEADER_H_VERSION, " - << "{}," // todo:k2 add commit hash + << "{" << vk::join(G->settings().php_code_commit_hash.get(), ", ", [](auto c) { return std::to_string(static_cast(c)); }) << "}," << "\"" << G->settings().php_code_version.get() << "\"," << "extraInfo.size()" << "," << "extraInfo.data()" diff --git a/compiler/compiler-settings.h b/compiler/compiler-settings.h index cd1615c72d..b4f42d0557 100644 --- a/compiler/compiler-settings.h +++ b/compiler/compiler-settings.h @@ -153,6 +153,7 @@ class CompilerSettings : vk::not_copyable { KphpOption compilation_metrics_file; KphpOption override_kphp_version; KphpOption php_code_version; + KphpOption php_code_commit_hash; KphpOption k2_component_name; diff --git a/compiler/kphp2cpp.cpp b/compiler/kphp2cpp.cpp index 9557fb3dab..2bf0f3310c 100644 --- a/compiler/kphp2cpp.cpp +++ b/compiler/kphp2cpp.cpp @@ -266,6 +266,8 @@ int main(int argc, char *argv[]) { "kphp-version-override", "KPHP_VERSION_OVERRIDE"); parser.add("Specify the compiled php code version", settings->php_code_version, "php-code-version", "KPHP_PHP_CODE_VERSION", "unknown"); + parser.add("Specify the compiled php code commit hash", settings->php_code_commit_hash, + "php-code-commit-hash", "KPHP_PHP_CODE_COMMIT_HASH", "0000000000000000000000000000000000000000"); parser.add("C++ compiler for building the output binary", settings->cxx, "cxx", "KPHP_CXX", get_default_cxx()); parser.add("Directory for c++ compiler toolchain. Will be passed to cxx via -B option", settings->cxx_toolchain_dir,