简体   繁体   中英

Including compiled extension with cx_freeze

I have a C extension that I am building with scikit-build (because it uses a CMake library), and this builds fine and works when imported in python.

I am then trying to build the script that uses the extension with cx-freeze , which is building, but I see the extension listed under "Missing modules":

Missing modules:
? _atscManufacturing imported from atsc.atscManufacturing.atscManufacturing

When I run the built executable from command prompt it just hangs for a couple seconds and then exits with no output.

I have seen this solution which suggests using Extension to add the C extension, but this seems to want to compile the library instead of just including the compiled library. I don't think this will work because it needs to build the CMake library.

Here is my main setup.py :

from cx_Freeze import setup, Executable

# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {"packages": ["os", "atsc.atscManufacturing.atscManufacturing", "intelhex", "logging", "atexit", "sys"], "excludes": []}

base = None

setup(  name = "Manufacturing script",
    version = "1.0.0",
    description = "manufacturing script",
    options = {"build_exe": build_exe_options},
    executables = [Executable("main.py", base = base)])

Here is the setup.py from the extension in ./atsc :

from skbuild import setup

setup(
    name="atscManufacturing",
    version="0.1",
    packages=['atscManufacturing']
)

I was able to get it working, there were a few issues:

  1. I was using python setup.py build to build the atscManufacturing module. This builds the library in the build directory. I added the --inplace option to output the library in the module.
  2. The module linked a C library that was being built as a shared library. According to this issue there is no way to copy in the compiled shared library with scikit-build. It could be copied from the build directory into the module directory with a custom script, but instead I just changed the C library to be built statically so it is compiled into the pyd library. This issue was confusing because I got the error "python ImportError: DLL load failed while importing _atscManufacturing: The specified module could not be found." which isn't saying _atscManufacturing can't be found, but that a shared library that _atscManufacturing depends on can't be found. I figured this one out by running dumpbin /dependents _atscManufacturing.cp310-win_amd64.pyd from a Visual Studio command prompt, which listed the shared library in question
  3. I was using SWIG to generate the wrapper, and for some reason the python file it generated worked fine when run with python, but failed (without an error) when run from the cx-freeze exe. Fortunately I didn't need that, and loaded the module in __init__.py , so I just removed the file and changed my import in the main python file. The lack of error made this difficult to debug, I resorted to adding print calls to see where the script failed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM