Skip to content

Conversation

@hongxu-jia
Copy link

@hongxu-jia hongxu-jia commented Sep 17, 2025

The build path may contain tmp dir which is not predictable, it caused the generated output file is not stable at each build and made the generated library is not reproducible [1] between builds

vim frozenlist/_frozenlist.cpp
...
/* BEGIN: Cython Metadata
{
"distutils": {
"depends": [],
"language": "c++",
"name": "frozenlist._frozenlist",
"sources": [
"/tmp/.tmp-frozenlist-pep517-cfdvygni/src/frozenlist/_frozenlist.pyx"
]
},
"module_name": "frozenlist._frozenlist"
}
END: Cython Metadata */
...

Replace build path prefix with hardcode `build_path', it is no harm to tweak comments in source file, after applied this commit, vim frozenlist/_frozenlist.cpp
...
/* BEGIN: Cython Metadata
{
"distutils": {
"depends": [],
"language": "c++",
"name": "frozenlist._frozenlist",
"sources": [
"build_path/frozenlist/_frozenlist.pyx"
]
},
"module_name": "frozenlist._frozenlist"
}
END: Cython Metadata */
...

[1] https://reproducible-builds.org/

… generated output file

The build path may contain tmp dir which is not predictable, it caused
the generated output file is not stable at each build and made
the generated library is not reproducible [1] between builds

vim frozenlist/_frozenlist.cpp
...
/* BEGIN: Cython Metadata
{
    "distutils": {
        "depends": [],
        "language": "c++",
        "name": "frozenlist._frozenlist",
        "sources": [
            "/tmp/.tmp-frozenlist-pep517-cfdvygni/src/frozenlist/_frozenlist.pyx"
        ]
    },
    "module_name": "frozenlist._frozenlist"
}
END: Cython Metadata */
...

Replace build path prefix with hardcode `build_path', it is no harm to
tweak comments in source file, after applied this commit,
vim frozenlist/_frozenlist.cpp
...
/* BEGIN: Cython Metadata
{
    "distutils": {
        "depends": [],
        "language": "c++",
        "name": "frozenlist._frozenlist",
        "sources": [
            "build_path/frozenlist/_frozenlist.pyx"
        ]
    },
    "module_name": "frozenlist._frozenlist"
}
END: Cython Metadata */
...

[1] https://reproducible-builds.org/

Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
@rossburton
Copy link

rossburton commented Sep 22, 2025

A related PR is #6489 which I closed previously as #6341 merged but I think this is still a problem. With python3-build doing builds in /tmp the relative path logic in 6341 never triggers and the generated sources always contain an absolute path to the build tree.

If the maintainers are happy with just munging the path to be a static prefix, then great. Alternatively, do we need to re-open !6489 and talk about path-prefix-mapping (as done by gcc etc with -ffile-prefix-map?

Another related issue is #5949.

@rossburton
Copy link

This is actually even more annoying to solve than I thought.

eg _frozenlist.cpython-313-aarch64-linux-gnu.so embeds build paths of eg /tmp/.tmp-frozenlist-pep517-kzt0jo2r/src/frozenlist/_frozenlist.cpp so there's no way to know in advance what the prefix will be, so there's no way to remap them like "traditional" C compilers support.

One way of helping this would be to let build be told where to build, so it doesn't need to make temporary directories. At least then we'd have a known base.

@webknjaz
Copy link
Contributor

This is actually even more annoying to solve than I thought.

eg _frozenlist.cpython-313-aarch64-linux-gnu.so embeds build paths of eg /tmp/.tmp-frozenlist-pep517-kzt0jo2r/src/frozenlist/_frozenlist.cpp so there's no way to know in advance what the prefix will be, so there's no way to remap them like "traditional" C compilers support.

For context, here's why we use a temporary directory: when we run cibuildwheel to produce a bunch of platform-specific wheels, it cycles over a bunch of Python versions in the same container. Cython (by the way of setuptools) creates C-extensions right in the current project tree. It then does not clean them up. And so there's no structured way of determining which shared object files were built by current iteration vs. the previous one.
This results in every following wheel accumulating C-extensions from the previous loop iterations. For example, if we build Python 3.12, 3.13 and 3.14, the last one ends up including a bunch of useless payload:

adding 'yarl/_quoting_c.cpython-312-x86_64-linux-gnu.so'
adding 'yarl/_quoting_c.cpython-313-x86_64-linux-gnu.so'
adding 'yarl/_quoting_c.cpython-314-x86_64-linux-gnu.so'

So my way of dealing with this was to make sure that each build starts with a clean slate. Hence a tmp dir. Post aio-libs/yarl#1586, the builds are stripped in release mode and aio-libs/yarl#1590 explores exposing a toggle for forcing in-place builds.

@scoder
Copy link
Contributor

scoder commented Oct 31, 2025

Cython (by the way of setuptools) creates C-extensions right in the current project tree. It then does not clean them up.

Cython only generates the .c/.cpp files. They are (practically) agnostic to the Python version that built them and thus do not get in the way in your scenario. Whether setuptools then puts the shared library into the source tree or into the build directory is up to the way it is called. You cannot really blame setuptools for copying files into the source tree if you, or the tools that you use, instruct it to do so.

eg _frozenlist.cpython-313-aarch64-linux-gnu.so embeds build paths of eg /tmp/.tmp-frozenlist-pep517-kzt0jo2r/src/frozenlist/_frozenlist.cpp so there's no way to know in advance what the prefix will be

If it builds in a temp directory, then why doesn't it either move the current directory there, or use some other means to advertise the (temporary) project root in the build directory? ISTM that the problem could be solved by a cleaner configuration here.

@rossburton
Copy link

It does feel like cibuildwheels is at fault here - if it's repeatedly building wheels it should have a clean slate for each iteration.

This is exactly why pep517 needs first-class support for out-of-tree builds...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants