From a227c62b5daa9a80736acfeda50272498ca12860 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 21:01:21 +0000 Subject: [PATCH 1/2] Initial plan From eb06713d7f93d2558cbb6fe964569fc96e98f763 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 21:07:45 +0000 Subject: [PATCH 2/2] Add MSVC PCH support with stub .cpp files Co-authored-by: randombit <469092+randombit@users.noreply.github.com> --- configure.py | 30 +++++++++++++++++++++++++++--- src/build-data/cc/msvc.txt | 4 ++++ src/build-data/makefile.in | 8 ++++---- src/build-data/ninja.in | 8 ++++---- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/configure.py b/configure.py index f75abf68158..3e923ab312f 100755 --- a/configure.py +++ b/configure.py @@ -2382,13 +2382,29 @@ def test_exe_extra_ldflags(): } if variables['enable_pch']: - variables['pch_include_for_lib'] = '%s %s' % (cc.pch_include, os.path.join(build_paths.pch_dir, 'pch_lib.h')) variables['pch_path_for_lib'] = os.path.join(build_paths.pch_dir, 'pch_lib.h.' + cc.pch_suffix) - - variables['pch_include_for_exe'] = '%s %s' % (cc.pch_include, os.path.join(build_paths.pch_dir, 'pch_exe.h')) variables['pch_path_for_exe'] = os.path.join(build_paths.pch_dir, 'pch_exe.h.' + cc.pch_suffix) variables['pch_target'] = 'pch' + variables['is_msvc'] = cc.macro_name == 'MSVC' + + if cc.macro_name == 'MSVC': + # MSVC requires compiling a .cpp file and using /Fp to specify output + variables['pch_src_for_lib'] = os.path.join(build_paths.pch_dir, 'pch_lib.cpp') + variables['pch_src_for_exe'] = os.path.join(build_paths.pch_dir, 'pch_exe.cpp') + variables['pch_compile_for_lib'] = '/Ycpch_lib.h /Fp%s' % variables['pch_path_for_lib'] + variables['pch_compile_for_exe'] = '/Ycpch_exe.h /Fp%s' % variables['pch_path_for_exe'] + # MSVC uses /Yu to use PCH and /Fp to specify which one, and /FI to force include + variables['pch_include_for_lib'] = '/Yupch_lib.h /Fp%s /FIpch_lib.h' % variables['pch_path_for_lib'] + variables['pch_include_for_exe'] = '/Yupch_exe.h /Fp%s /FIpch_exe.h' % variables['pch_path_for_exe'] + else: + # GCC/Clang compile the header directly + variables['pch_src_for_lib'] = os.path.join(build_paths.pch_dir, 'pch_lib.h') + variables['pch_src_for_exe'] = os.path.join(build_paths.pch_dir, 'pch_exe.h') + variables['pch_compile_for_lib'] = cc.pch_compile + variables['pch_compile_for_exe'] = cc.pch_compile + variables['pch_include_for_lib'] = '%s %s' % (cc.pch_include, os.path.join(build_paths.pch_dir, 'pch_lib.h')) + variables['pch_include_for_exe'] = '%s %s' % (cc.pch_include, os.path.join(build_paths.pch_dir, 'pch_exe.h')) else: variables['pch_include_for_lib'] = '' variables['pch_path_for_lib'] = '' @@ -2396,6 +2412,7 @@ def test_exe_extra_ldflags(): variables['pch_path_for_exe'] = '' variables['pch_target'] = '' + variables['is_msvc'] = False variables['installed_include_dir'] = os.path.join( variables['prefix'], @@ -3554,6 +3571,13 @@ def in_build_module_info(p): if options.enable_pch: shutil.copy(in_src_lib_dir('pch/pch.h'), os.path.join(build_paths.pch_dir, 'pch_lib.h')) shutil.copy(in_src_lib_dir('pch/pch.h'), os.path.join(build_paths.pch_dir, 'pch_exe.h')) + + # MSVC requires a .cpp file to compile the PCH + if template_vars['cc_macro'] == 'MSVC': + with open(os.path.join(build_paths.pch_dir, 'pch_lib.cpp'), 'w', encoding='utf8') as f: + f.write('#include "pch_lib.h"\n') + with open(os.path.join(build_paths.pch_dir, 'pch_exe.cpp'), 'w', encoding='utf8') as f: + f.write('#include "pch_exe.h"\n') def link_headers(headers, visibility, directory): logging.debug('Linking %d %s header files in %s', len(headers), visibility, directory) diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index bbd587743a5..a3859b3a479 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -16,6 +16,10 @@ add_lib_option "%s.lib" compile_flags "/nologo /c" +pch_compile "/Yc" +pch_suffix "pch" +pch_include "/Yu" + optimization_flags "/O2 /Oi /Zc:throwingNew" size_optimization_flags "/O1 /Os" diff --git a/src/build-data/makefile.in b/src/build-data/makefile.in index bdc929dfd5c..da94dea29e2 100644 --- a/src/build-data/makefile.in +++ b/src/build-data/makefile.in @@ -53,11 +53,11 @@ docs: %{doc_stamp_file} %{if enable_pch} -%{pch_path_for_lib}: %{pch_dir}/pch_lib.h - $(CXX) $(LIB_FLAGS) $(BUILD_FLAGS) -DBOTAN_IS_BEING_BUILT %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile} %{dash_c} %{pch_dir}/pch_lib.h %{dash_o}$@ +%{pch_path_for_lib}: %{pch_src_for_lib} + $(CXX) $(LIB_FLAGS) $(BUILD_FLAGS) -DBOTAN_IS_BEING_BUILT %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile_for_lib} %{dash_c} %{pch_src_for_lib} %{dash_o}$@ -%{pch_path_for_exe}: %{pch_dir}/pch_exe.h - $(CXX) $(BUILD_FLAGS) -DBOTAN_IS_BEING_BUILT %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile} %{dash_c} %{pch_dir}/pch_exe.h %{dash_o}$@ +%{pch_path_for_exe}: %{pch_src_for_exe} + $(CXX) $(BUILD_FLAGS) -DBOTAN_IS_BEING_BUILT %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile_for_exe} %{dash_c} %{pch_src_for_exe} %{dash_o}$@ %{endif} diff --git a/src/build-data/ninja.in b/src/build-data/ninja.in index 4b62c8a58ae..caded98ffb6 100644 --- a/src/build-data/ninja.in +++ b/src/build-data/ninja.in @@ -23,14 +23,14 @@ INSTALLED_LIB_DIR = %{libdir} %{if enable_pch} rule compile_pch_lib - command = %{cxx} %{lib_flags} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile} %{dash_c} $in %{dash_o}$out + command = %{cxx} %{lib_flags} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile_for_lib} %{dash_c} $in %{dash_o}$out rule compile_pch_exe - command = %{cxx} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile} %{dash_c} $in %{dash_o}$out + command = %{cxx} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} %{public_include_flags} %{internal_include_flags} %{external_include_flags} %{pch_compile_for_exe} %{dash_c} $in %{dash_o}$out -build %{pch_path_for_lib}: compile_pch_lib %{pch_dir}/pch_lib.h +build %{pch_path_for_lib}: compile_pch_lib %{pch_src_for_lib} -build %{pch_path_for_exe}: compile_pch_exe %{pch_dir}/pch_exe.h +build %{pch_path_for_exe}: compile_pch_exe %{pch_src_for_exe} %{endif}