marcelotduarte / cx_Freeze

cx_Freeze creates standalone executables from Python scripts, with the same performance, is cross-platform and should work on any platform that Python itself works on.
https://marcelotduarte.github.io/cx_Freeze/
Other
1.28k stars 210 forks source link

Building with pyproject.toml does not include local package #2436

Closed jpvbarbosa closed 3 weeks ago

jpvbarbosa commented 3 weeks ago

Describe the bug I am trying to build a simple example project with the cxfreeze build command and a pyproject.toml. The project includes a single executable script, main.py, and single package and module, package1.module1. I currently have both a setup.py and a pyproject.toml for testing purposes, but my goal is to only use pyproject.toml. I've created the pyproject.toml such that, to the best of my knowledge, it mirrors exactly what setup.py is doing.

The problem is that calling cxfreeze build does not include package1.module1 in the resulting build whereas calling python setup.py build does include it. Running the executable created with cxfreeze build will crash because it cannot find my package1.module1 in <build-folder>/lib, whereas running the executable created with python setup.py build runs without error.

I have tested each scenario independently as well to rule out the pyrproject.toml conflicting with setup.py or vice-versa, but the result is the same.

I've tried adding various combinations of packages = [...] and includes = [...] to pyproject.toml but these all resulted in a "Module not found"-type error.

The only thing that did work was adding include_path = "." to pyproject.toml, but I would expect the project root to already be included in the path and I would prefer to rely on auto-detecting packages rather than hard-coding directories.

I admittedly don't have much experience managing python packages so there's a good chance I'm doing something fundamentally wrong here or I'm just missing something in the pyproject.toml. Any advice appreciated.

To Reproduce Clone my example repo and test building with both setup.py and pyproject.toml

git clone https://github.com/jpvbarbosa/cx_freeze_simple.git
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install --upgrade cx_freeze
cxfreeze build  # creates build folder 'build-pyproject'
# Compare to:
python setup.py build  # creates build folder 'build-setup'

I've attached the outputs I get for both for comparison: pyproject_output.txt setup_output.txt

Here is the setup.py I'm using:

from cx_Freeze import setup, Executable
import sys

# Dependencies are automatically detected, but it might need
# fine tuning.
build_options = {'packages': [], 'excludes': [], 'build_exe': "build-setup"}

executables = [
    Executable('main.py', target_name="main_setup", base=None)
]

print(sys.path)

setup(name='Main-setup',
      version = '1.0',
      description = 'Main setup',
      options = {'build_exe': build_options},
      executables = executables)

And here is the pyproject.toml:

[project]
name = "Main-pyproject"
version = "1.0"
description = "Main pyproject"

[tool.cxfreeze]
executables = [
    {script = "main.py", target_name = "main-pyproject"}
]

[tool.cxfreeze.build_exe]
build_exe = "build-pyproject"

My project structure is as follows:

├── main.py
├── package1
│   ├── __init__.py
│   └── module1.py
├── pyproject.toml
├── setup.py

Expected behavior I would expect both build outputs above to include the package1.module module in the resulting <build-folder>/lib directory, however, only the setup.py method of building includes it.

Desktop (please complete the following information):

marcelotduarte commented 3 weeks ago

I confirm the bug. I'll fix it. There are two workarounds to use pyproject for your use case: cxfreeze build_exe --include-path=. or python -m cx_Freeze build

marcelotduarte commented 1 week ago

Release 7.1.1 is out! Documentation

jpvbarbosa commented 1 week ago

I've confirmed it's working now, thanks!