Skip to content

Fix test_venv on Windows adding support for building python launchers #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

jcfr
Copy link
Contributor

@jcfr jcfr commented Jun 12, 2025

Summary

This pull request adds support for building the following Windows-specific Python launchers:

  • venvlauncher and venvwlauncher. Introduced in Python ≥ 3.3, but only built when Python ≥ 3.9 to simplify resource handling.
  • pylauncher and pywlauncher. Introduced and built when Python ≥ 3.11.

These launchers rely on launcher.c and launcher2.c, depending on the target. They enable Python-specific runtime behavior for virtual environments and support shebang redirection on Windows.

Implementation Notes

_WINDOWS Macro Handling

To avoid build issues related to the _WINDOWS macro being implicitly defined via /D_WINDOWS (e.g., from CMAKE_C_FLAGS), we introduce a helper function:

_add_executable_without_windows(target_name ...)

This function:

  • Adds the executable target using add_executable(...)

  • Explicitly undefines _WINDOWS using:

    target_compile_options(${target_name} PRIVATE /U_WINDOWS)
  • Avoids modifying global variables like CMAKE_C_FLAGS, which are unreliable and fragile during CMake generation

  • Accepts that the following harmless MSVC warning will be emitted:

    cl : command line warning D9025: overriding '/D_WINDOWS' with '/U_WINDOWS'
    

This prevents incorrect subsystem settings or entry-point mismatches that would otherwise occur if _WINDOWS were incorrectly defined, particularly in console-mode launchers.

Manifest Handling

  • Pass /MANIFEST:NO to the linker to avoid resource duplication errors, since pylauncher.rc already includes an embedded manifest.

Conditional Launcher Build Logic

  • venvlauncher and venvwlauncher are only built when PY_VERSION ≥ 3.9.

    • While support for these launchers was introduced in Python 3.3, versions < 3.9 required generating pythonnt_rc.h.
    • This requirement was removed in python/cpython@4efc336
      "bpo-41054: Simplify resource compilation on Windows (GH-21004)".
    • Restricting to Python ≥ 3.9 simplifies the build and avoids conditional logic for legacy resource files.

Working toward addressing:

jcfr added 2 commits June 11, 2025 23:03
This adds logic to build the following Windows-specific Python launchers:

- `venvlauncher` and `venvwlauncher` (available in Python >= 3.3)
- `pylauncher` and `pywlauncher` (available in Python >= 3.11)

Both `launcher.c` and `launcher2.c` source files are used depending on the
target. These launchers integrate Python-specific runtime behavior for
virtual environments and shebang redirection on Windows.

To avoid build issues on MSVC due to the `_WINDOWS` macro being defined via
`CMAKE_C_FLAGS` (see CMake #19796), we introduce a helper function
`add_executable_without_windows()` that:

- Temporarily removes `/D_WINDOWS` from `CMAKE_C_FLAGS`
- Adds `/U_WINDOWS` to ensure `_WINDOWS` is not defined
- Restores the original flags after each target is added

This avoids conflicts in console launchers (e.g., incorrect subsystem or
entry point resolution), and resolves CVTRES and LNK1123 errors that can
occur when `_WINDOWS` is incorrectly defined.

Additionally, `/MANIFEST:NO` is passed to the linker to prevent duplicate
resource errors due to `pylauncher.rc` already embedding a manifest.
@jcfr jcfr enabled auto-merge (rebase) June 12, 2025 17:07
jcfr added 2 commits June 12, 2025 15:48
… global flags

Follow-up to the initial support for building Windows Python launchers.

Instead of modifying the global `CMAKE_C_FLAGS` to remove `/D_WINDOWS` (which
is unreliable due to how CMake handles cached variables) this patch uses
`target_compile_options()` to explicitly undefine `_WINDOWS` at the target level.

This effectively resolves the original issue while introducing the following
MSVC warning:

```
cl : command line  warning D9025: overriding '/D_WINDOWS' with '/U_WINDOWS' [C:\D\T\jcfr\pycbs-3.12-build\CMakeBuild\launcher\pylaunc
her.vcxproj]
```
Although `venvlauncher` was introduced in Python 3.3, this change raises
the minimum required version to Python 3.9 to avoid complications related
to resource generation.

Specifically, earlier versions require generating `pythonnt_rc.h`,
which was removed in python/cpython@4efc3360c9a ("bpo-41054: Simplify resource compilation on Windows")

This simplifies the build logic by eliminating the need to maintain or
conditionally generate legacy resource files.
@jcfr jcfr changed the title Fix test_venv adding support for building windows python launchers Fix test_venv on Windows adding support for building python launchers Jun 12, 2025
@jcfr jcfr merged commit f807c34 into python-cmake-buildsystem:master Jun 12, 2025
28 checks passed
@jcfr jcfr deleted the support-building-pylauncher-and-venvlauncher branch June 12, 2025 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant