From 9917010a40b95ecb860db1a6142046ebf6b7b51e Mon Sep 17 00:00:00 2001 From: Sergey Avseyev Date: Mon, 8 Apr 2024 10:44:45 -0700 Subject: [PATCH] PCBC-859: Update build scripts and instructions for Windows (#158) --- WINDOWS.md | 84 +++++++++++++++++++++++------------ bin/package.rb | 6 +-- config.w32 | 56 +++++++++++++++-------- src/CMakeLists.txt | 11 ++++- src/deps/couchbase-cxx-client | 2 +- 5 files changed, 106 insertions(+), 53 deletions(-) diff --git a/WINDOWS.md b/WINDOWS.md index 8e4de95d..bdf1c6ea 100644 --- a/WINDOWS.md +++ b/WINDOWS.md @@ -8,17 +8,19 @@ https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/ Install scoop package manager (https://scoop.sh/): - Set-ExecutionPolicy RemoteSigned -scope CurrentUser - iwr -useb get.scoop.sh | iex - Install tools and dependencies: - scoop install git openssl cmake + winget install Git.Git + winget install Kitware.CMake + winget install NASM.NASM Clone Couchbase SDK source code (note `--recurse-submodules`): git clone --recurse-submodules https://github.com/couchbaselabs/couchbase-php-client c:\users\user\couchbase-php-client +NOTE: it is important that path to the extension source will not have spaces, otherwise PHP build +system will not be able to work properly. + Clone PHP interpreter source code (switch to necessary branch): git clone https://github.com/php/php-src c:\users\user\php-src @@ -31,10 +33,10 @@ Clone PHP SDK tools Open "Visual Studio Installer" application and make sure that "Desktop development with C++" workload is installed. -Navigate to PHP SDK tools and load build environment (we assume Visual Studio 2022, aka VS17 here): +Navigate to PHP SDK tools and load build environment (we assume Visual Studio 2019, aka VS16 here): cd c:\php-sdk - .\phpsdk-vs17-x64.bat + .\phpsdk-vs16-x64.bat Inside the shell with build environment, navigate to PHP interpreter sources @@ -59,15 +61,13 @@ The aforementioned build process will generate a command-line version of `php.ex c:\users\user\php-src\x64\Release_TS\php.exe c:\users\user\php-src\x64\Release_TS\php8ts.dll c:\users\user\php-src\x64\Release_TS\php_couchbase.dll - c:\users\user\php-src\x64\Release_TS\couchbase_php_wrapper.dll Lets create another directory and copy these three files so that the following file tree will be in result: c:\users\user\php-verification\ |- php.exe |- php8ts.dll - |- php_couchbase.dll - +- couchbase_php_wrapper.dll + +- php_couchbase.dll Now navigate to verification directory and check that it can load the extension successfully: @@ -104,36 +104,62 @@ Display service information, that was recorded during the build: PS> php -d extension=c:\Users\User\php-verification\php_couchbase.dll -r "print_r(Couchbase\Extension\version());" Array ( - [extension_revision] => 82377e66c3b8f1d4798cd9860adbd32f00983541 - [cxx_client_revision] => ee002352870f1d623d81868b80a5ef70c0acfcee - [cxx_transactions_revision] => ee002352870f1d623d81868b80a5ef70c0acfcee - [asio] => 1.21.0 - [build_timestamp] => 2022-04-18 15:12:13 - [cc] => MSVC 19.30.30709.0 + [extension_revision] => 5d98471f9651e2157a160443990d303a0eb1cbc3 + [cxx_client_revision] => 291ed3da17a0a0d68a599dd25306dbb8eb7febac + [_MSC_VER] => 1929 + [__cplusplus] => 199711 + [asio] => 1.29.0 + [boringssl_sha] => 2ff4b968a7e0cfee66d9f151cb95635b43dc1d5b + [build_timestamp] => 2024-04-05 00:34:10 + [cc] => MSVC 19.29.30154.0 [cmake_build_type] => RelWithDebInfo - [cmake_version] => 3.23.1 - [compile_definitions] => FMT_LOCALE;SPDLOG_COMPILED_LIB;SPDLOG_FMT_EXTERNAL - [compile_features] => cxx_std_17;cxx_variadic_templates + [cmake_version] => 3.29.1 + [compile_definitions] => SPDLOG_COMPILED_LIB;SPDLOG_FMT_EXTERNAL;ASIO_STANDALONE;ASIO_NO_DEPRECATED;_WIN32_WINNT=0x0A00;WIN32_LEAN_AND_MEAN + [compile_features] => cxx_std_17;cxx_std_11;cxx_std_17;cxx_std_17 [compile_flags] => - [compile_options] => + [compile_options] => /bigobj [cpu] => AMD64 - [cxx] => MSVC 19.30.30709.0 - [fmt] => 8.800.1 - [http_parser] => 2.9.4 + [cxx] => MSVC 19.29.30154.0 + [fmt] => 10.2.1 + [hdr_histogram_c] => 0.11.8 [link_depends] => [link_flags] => - [link_libraries] => project_options;project_warnings;fmt::fmt;spdlog::spdlog;couchbase_backtrace;couchbase_logger;couchbase_platform;couchbase_io;couchbase_meta;couchbase_crypto;couchbase_sasl;couchbase_topology;couchbase_utils;couchbase_protocol;couchbase_management;couchbase_operations;couchbase_operations_management;couchbase_tracing;couchbase_metrics;OpenSSL::SSL;OpenSSL::Crypto + [link_libraries] => project_options;project_warnings;fmt::fmt;spdlog::spdlog;couchbase_backtrace;couchbase_logger;couchbase_platform;couchbase_meta;couchbase_crypto;couchbase_sasl;couchbase_tracing;couchbase_metrics;Microsoft.GSL::GSL;asio;llhttp::llhttp;taocpp::json;snappy;jsonsl;hdr_histogram_static;iphlpapi;OpenSSL::SSL;OpenSSL::Crypto [link_options] => - [openssl_headers] => OpenSSL 3.0.2 15 Mar 2022 - [openssl_runtime] => OpenSSL 3.0.2 15 Mar 2022 - [platform] => Windows-10.0.22000 + [llhttp] => 9.2.0 + [mozilla_ca_bundle_date] => Mon Mar 11 15:25:27 2024 GMT + [mozilla_ca_bundle_embedded] => 1 + [mozilla_ca_bundle_sha256] => 1794c1d4f7055b7d02c2170337b61b48a2ef6c90d77e95444fd2596f4cac609f + [mozilla_ca_bundle_size] => 147 + [openssl_config_dir] => OPENSSLDIR: n/a + [openssl_crypto_interface_imported_location] => + [openssl_crypto_interface_include_directories] => C:/Users/user/.cache/CPM/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/include + [openssl_crypto_interface_link_libraries] => crypto + [openssl_default_cert_dir] => /etc/ssl/certs + [openssl_default_cert_dir_env] => SSL_CERT_DIR + [openssl_default_cert_file] => /etc/ssl/cert.pem + [openssl_default_cert_file_env] => SSL_CERT_FILE + [openssl_headers] => OpenSSL 1.1.1 (compatible; BoringSSL) + [openssl_pkg_config_interface_include_directories] => + [openssl_pkg_config_interface_link_libraries] => + [openssl_runtime] => BoringSSL + [openssl_ssl_imported_location] => + [openssl_ssl_interface_include_directories] => C:/Users/user/.cache/CPM/boringssl/e31ea00c1ea52052d2d78d44006cc88c80fa24a9/boringssl/src/include + [openssl_ssl_interface_link_libraries] => crypto + [platform] => Windows-10.0.26100 + [platform_name] => Windows + [platform_version] => 10.0.26100 [post_linked_openssl] => OFF - [revision] => b5800042a227065cfa8bc4dfc0bcaf04fd859fc7 - [snappy] => 1.1.8 + [revision] => 291ed3da17a0a0d68a599dd25306dbb8eb7febac + [semver] => 1.0.0-dp.14+8.291ed3d + [snappy] => 1.1.10 [snapshot] => - [spdlog] => 1.9.2 + [spdlog] => 1.13.0 + [static_boringssl] => true [static_openssl] => [static_stdlib] => + [txns_forward_compat_extensions] => TI,MO,BM,QU,SD,BF3787,BF3705,BF3838,RC,UA,CO,BF3791,CM,SI,QC,IX,TS,PU + [txns_forward_compat_protocol_version] => 2.0 [version] => 1.0.0 [version_build] => 0 [version_major] => 1 diff --git a/bin/package.rb b/bin/package.rb index 00ffd4f0..8cd9b575 100755 --- a/bin/package.rb +++ b/bin/package.rb @@ -94,9 +94,9 @@ def which(name, extra_locations = []) "boringssl/*/boringssl/**/CMakeLists.txt", "boringssl/*/boringssl/LICENSE", "fmt/*/fmt/CMakeLists.txt", - "fmt/*/fmt/ChangeLog.rst", - "fmt/*/fmt/LICENSE.rst", - "fmt/*/fmt/README.rst", + "fmt/*/fmt/ChangeLog.md", + "fmt/*/fmt/LICENSE.md", + "fmt/*/fmt/README.md", "fmt/*/fmt/include/**/*", "fmt/*/fmt/src/**/*", "fmt/*/fmt/support/cmake/**/*", diff --git a/config.w32 b/config.w32 index 4aef3bd6..19852c58 100644 --- a/config.w32 +++ b/config.w32 @@ -1,24 +1,35 @@ // vim:ft=javascript -ARG_ENABLE("couchbase", "weather to enable Couchbase support", "no"); +ARG_ENABLE("couchbase", "whether to enable Couchbase support", "no"); if (PHP_COUCHBASE != "no") { - var CMAKE = PATH_PROG("cmake"); + // we prefer standalone CMake, as the one that comes with MSVS might be too old + var CMAKE = PATH_PROG("cmake", PROGRAM_FILES + "\\CMake\\bin;" + PROGRAM_FILESx86 + "\\CMake\\bin"); if (!CMAKE) { - ERROR("cmake is required"); + ERROR("cmake is required (use 'winget install Kitware.CMake')"); + } + var LOCALAPPDATA = WshShell.Environment("Process").Item("LOCALAPPDATA"); + var NASM = PATH_PROG("nasm", LOCALAPPDATA + "\\bin\\nasm"); + if (!NASM) { + ERROR("nasm is required for BoringSSL (use 'winget install NASM.NASM')"); } ADD_FLAG("CFLAGS", "/std:c++17"); var COUCHBASE_CMAKE_SOURCE_DIRECTORY = FSO.GetAbsolutePathName(configure_module_dirname + "\\src"); var COUCHBASE_CMAKE_BUILD_DIRECTORY = get_define("BUILD_DIR") + "\\cmake-build"; - var COUCHBASE_PHP_CFLAGS = (get_define("CFLAGS_PHP") + " " + get_define("CFLAGS")) + // TODO: we don't seem to need this: get_define("CFLAGS_PHP") + var COUCHBASE_PHP_CFLAGS = get_define("CFLAGS") .replace('$(BASE_INCLUDES)', '') + .replace(new RegExp('"', 'g'), '\\"') .replace(new RegExp('\\s+', 'g'), ' ') .replace(new RegExp('/D ', 'g'), '/D') .replace(new RegExp('/I ', 'g'), '/I'); STDOUT.WriteLine('MODE_PHPIZE=' + MODE_PHPIZE); - STDOUT.WriteLine('PHP_DIR="' + PHP_DIR + '"'); STDOUT.WriteLine('PHP_SRC_DIR="' + PHP_SRC_DIR + '"'); - var php_src_prefix = MODE_PHPIZE ? PHP_DIR + "\\include" : PHP_SRC_DIR; + STDOUT.WriteLine('BUILD_DIR="' + get_define("BUILD_DIR") + '"'); + if (MODE_PHPIZE) { + STDOUT.WriteLine('PHP_DIR="' + PHP_DIR + '"'); + } + var php_src_prefix = MODE_PHPIZE ? (PHP_DIR + "\\include") : PHP_SRC_DIR; var COUCHBASE_PHP_INCLUDES = php_src_prefix + " " + php_src_prefix + "\\main " + @@ -26,31 +37,38 @@ if (PHP_COUCHBASE != "no") { php_src_prefix + "\\TSRM " + php_src_prefix + "\\ext"; var COUCHBASE_PHP_LIB = - MODE_PHPIZE ? PHP_DIR + "\\lib" : get_define("BUILD_DIR") + + (MODE_PHPIZE ? PHP_DIR + "\\lib" : get_define("BUILD_DIR")) + "\\" + get_define("PHPLIB"); STDOUT.WriteLine('CMAKE="' + CMAKE + '" # version: ' + probe_binary(CMAKE, "longversion")); + STDOUT.WriteLine('NASM="' + NASM + '" # version: ' + probe_binary(NASM, "version")); STDOUT.WriteLine('COUCHBASE_CMAKE_SOURCE_DIRECTORY="' + COUCHBASE_CMAKE_SOURCE_DIRECTORY + '"'); STDOUT.WriteLine('COUCHBASE_CMAKE_BUILD_DIRECTORY="' + COUCHBASE_CMAKE_BUILD_DIRECTORY + '"'); STDOUT.WriteLine('COUCHBASE_PHP_CFLAGS="' + COUCHBASE_PHP_CFLAGS + '"'); STDOUT.WriteLine('COUCHBASE_PHP_INCLUDES="' + COUCHBASE_PHP_INCLUDES + '"'); STDOUT.WriteLine('COUCHBASE_PHP_LIB="' + COUCHBASE_PHP_LIB + '"'); - DEFINE("LIBS_COUCHBASE", "$(BUILD_DIR)\\couchbase_php_wrapper.lib"); - DEFINE("DEPS_COUCHBASE", get_define("LIBS_COUCHBASE")); - EXTENSION("couchbase", "src\\php_couchbase.cxx", true); + // Override build rules. CMake is in charge of the build process. + MFO.WriteLine("$(BUILD_DIR)\\php_couchbase.lib: $(BUILD_DIR)\\php_couchbase.dll"); + MFO.WriteLine("$(BUILD_DIR)\\php_couchbase.dll: " + (MODE_PHPIZE ? "" : "$(BUILD_DIR)\\$(PHPDLL)")); + MFO.WriteLine("\t\"" + CMAKE + "\" --build \"" + COUCHBASE_CMAKE_BUILD_DIRECTORY + "\" --verbose"); + MFO.WriteLine("php_couchbase.dll: $(BUILD_DIR)\\php_couchbase.dll"); + MFO.WriteLine("\t@echo EXT couchbase build complete"); + + // Create dummy source file to keep PHP build system happy. + dummy_source = FSO.CreateTextFile(configure_module_dirname + "\\dummy.c", true); + dummy_source.WriteLine("extern void dummy() {}"); + dummy_source.Close(); - MFO.WriteLine("$(BUILD_DIR)\\couchbase_php_wrapper.lib: $(BUILD_DIR)\\$(PHPDLL)"); - MFO.WriteLine("\t" + CMAKE + " --build " + COUCHBASE_CMAKE_BUILD_DIRECTORY + " --parallel 4 --verbose"); - MFO.WriteLine("couchbase_php_wrapper.lib: $(BUILD_DIR)\\couchbase_php_wrapper.lib"); - MFO.WriteLine("\t@echo EXT couchbase wrapper build complete"); + EXTENSION("couchbase", "dummy.c", true); cmake_command = - 'cmd /c ' + CMAKE + - ' -S ' + COUCHBASE_CMAKE_SOURCE_DIRECTORY + - ' -B ' + COUCHBASE_CMAKE_BUILD_DIRECTORY + - ' -G ' + '"NMake Makefiles"' + + 'cmd /c ""' + CMAKE + '"' + + ' -S "' + COUCHBASE_CMAKE_SOURCE_DIRECTORY + '"' + + ' -B "' + COUCHBASE_CMAKE_BUILD_DIRECTORY + '"' + + ' -G "NMake Makefiles"' + ' -D CMAKE_BUILD_TYPE=RelWithDebInfo' + + ' -D CMAKE_ASM_NASM_COMPILER:PATH="' + NASM + '"' + ' -D COUCHBASE_PHP_CFLAGS="' + COUCHBASE_PHP_CFLAGS + '"' + ' -D COUCHBASE_PHP_INCLUDES="' + COUCHBASE_PHP_INCLUDES + '"' + ' -D COUCHBASE_PHP_LIB="' + COUCHBASE_PHP_LIB + '"' + @@ -58,7 +76,7 @@ if (PHP_COUCHBASE != "no") { ' -D COUCHBASE_CXX_CLIENT_BUILD_EXAMPLES=OFF ' + ' -D COUCHBASE_CXX_CLIENT_BUILD_TOOLS=OFF ' + ' -D COUCHBASE_CXX_CLIENT_BUILD_DOCS=OFF ' + - ' -D COUCHBASE_CXX_CLIENT_BUILD_TESTS=OFF 2>&1'; + ' -D COUCHBASE_CXX_CLIENT_BUILD_TESTS=OFF" 2>&1'; STDOUT.WriteLine(cmake_command); cmake_output = execute(cmake_command); STDOUT.WriteLine(cmake_output); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dadab762..c3f02137 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,9 @@ -cmake_minimum_required(VERSION 3.19) +cmake_minimum_required(VERSION 3.27) +if(POLICY CMP0149) + # BoringSSL requires at least WindowsSDKVersion=10.0.20348.0 + cmake_policy(SET CMP0149 NEW) +endif() + project(couchbase C CXX) set(CMAKE_CXX_STANDARD 17) @@ -75,7 +80,11 @@ set_target_properties(couchbase PROPERTIES PREFIX "") if(APPLE) set_target_properties(couchbase PROPERTIES SUFFIX ".so") endif() +if(MSVC) + set_target_properties(couchbase PROPERTIES PREFIX "php_" IMPORT_PREFIX "php_") +endif() target_include_directories(couchbase PRIVATE ${PROJECT_BINARY_DIR}/generated) +target_include_directories(couchbase PRIVATE ${PROJECT_SOURCE_DIR}/deps/couchbase-cxx-client) target_include_directories(couchbase PRIVATE ${PHP_INCLUDE_DIRS}) target_compile_definitions(couchbase PRIVATE ZEND_COMPILE_DL_EXT=1) set_target_properties(couchbase_cxx_client PROPERTIES C_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden) diff --git a/src/deps/couchbase-cxx-client b/src/deps/couchbase-cxx-client index 933e87ee..291ed3da 160000 --- a/src/deps/couchbase-cxx-client +++ b/src/deps/couchbase-cxx-client @@ -1 +1 @@ -Subproject commit 933e87eeab58b0a3f063fc12d93b443eea39cca7 +Subproject commit 291ed3da17a0a0d68a599dd25306dbb8eb7febac