python - 自定义 python 模块引导 .so 文件而不是 .dylib

标签 python setup.py

我正在制作一个使用 CMake 编译的自定义 Python 3.7 模块(在 OSX 上)。它将模块编译为 dylib 就很好,但是当我运行此命令时:

python3.7 setup.py install

egg 文件中生成的引导文件如下所示:

def __bootstrap__():
    global __bootstrap__, __loader__, __file__
    import sys, pkg_resources, imp
    __file__ = pkg_resources.resource_filename(__name__, 'spexi.cpython-37m-darwin.so')
    __loader__ = None; del __bootstrap__, __loader__
    imp.load_dynamic(__name__,__file__)
__bootstrap__()

但是,文件 spexi.cpython-37m-darwin.so 不存在,应该改为读取 spexi.dylib。如果我手动更改它,我似乎能够很好地运行代码。

setup.py 脚本现在看起来像这样:https://pastebin.com/sMWnJRdn

如何使用对 dylib 文件的正确引用来生成引导脚本?

以下是运行 setup.py 脚本的输出:

➜  spexi-gis-py python3.7 setup.py install
running install
running bdist_egg
running egg_info
writing spexi.egg-info/PKG-INFO
writing dependency_links to spexi.egg-info/dependency_links.txt
writing top-level names to spexi.egg-info/top_level.txt
reading manifest file 'spexi.egg-info/SOURCES.txt'
writing manifest file 'spexi.egg-info/SOURCES.txt'
installing library code to build/bdist.macosx-10.9-x86_64/egg
running install_lib
running build_ext
cmake /Users/colinbasnett/spexi-gis-py -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/colinbasnett/spexi-gis-py/build/lib.macosx-10.9-x86_64-3.7 -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is AppleClang 11.0.0.11000033
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found Python: /Library/Frameworks/Python.framework/Versions/3.7/lib/libpython3.7m.dylib (found version "3.7") found components: Development
-- Found TIFF: /usr/local/lib/libtiff.dylib (found version "4.0.10")
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/colinbasnett/spexi-gis-py/build/temp.macosx-10.9-x86_64-3.7
cmake --build . --config Release -- -j4
Scanning dependencies of target spexi
[ 50%] Building C object CMakeFiles/spexi.dir/src/vincenty.c.o
[ 50%] Building C object CMakeFiles/spexi.dir/src/dem.c.o
[ 75%] Building C object CMakeFiles/spexi.dir/src/spexi.c.o
[100%] Linking C shared library ../lib.macosx-10.9-x86_64-3.7/spexi.dylib
[100%] Built target spexi
creating build/bdist.macosx-10.9-x86_64
creating build/bdist.macosx-10.9-x86_64/egg
copying build/lib.macosx-10.9-x86_64-3.7/spexi.dylib -> build/bdist.macosx-10.9-x86_64/egg
creating build/bdist.macosx-10.9-x86_64/egg/spexi.cpython-37m-darwin.so
creating stub loader for spexi.cpython-37m-darwin.so
byte-compiling build/bdist.macosx-10.9-x86_64/egg/spexi.py to spexi.cpython-37.pyc
creating build/bdist.macosx-10.9-x86_64/egg/EGG-INFO
copying spexi.egg-info/PKG-INFO -> build/bdist.macosx-10.9-x86_64/egg/EGG-INFO
copying spexi.egg-info/SOURCES.txt -> build/bdist.macosx-10.9-x86_64/egg/EGG-INFO
copying spexi.egg-info/dependency_links.txt -> build/bdist.macosx-10.9-x86_64/egg/EGG-INFO
copying spexi.egg-info/top_level.txt -> build/bdist.macosx-10.9-x86_64/egg/EGG-INFO
writing build/bdist.macosx-10.9-x86_64/egg/EGG-INFO/native_libs.txt
zip_safe flag not set; analyzing archive contents...
__pycache__.spexi.cpython-37: module references __file__
creating 'dist/spexi-1.0.0-py3.7-macosx-10.9-x86_64.egg' and adding 'build/bdist.macosx-10.9-x86_64/egg' to it
removing 'build/bdist.macosx-10.9-x86_64/egg' (and everything under it)
Processing spexi-1.0.0-py3.7-macosx-10.9-x86_64.egg
removing '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/spexi-1.0.0-py3.7-macosx-10.9-x86_64.egg' (and everything under it)
creating /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/spexi-1.0.0-py3.7-macosx-10.9-x86_64.egg
Extracting spexi-1.0.0-py3.7-macosx-10.9-x86_64.egg to /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages
spexi 1.0.0 is already the active version in easy-install.pth

Installed /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/spexi-1.0.0-py3.7-macosx-10.9-x86_64.egg
Processing dependencies for spexi==1.0.0
Finished processing dependencies for spexi==1.0.0

setup.py

import os
import pathlib
from setuptools import setup, Extension
from setuptools.command.build_ext import build_ext as build_ext_orig


class CMakeExtension(Extension):
    def __init__(self, name, cmake_lists_dir='.', **kwa):
        Extension.__init__(self, name, sources=[], **kwa)
        self.cmake_lists_dir = os.path.abspath(cmake_lists_dir)


class build_ext(build_ext_orig):
    def run(self):
        for ext in self.extensions:
            self.build_cmake(ext)
        super().run()

    def build_cmake(self, ext):
        cwd = pathlib.Path().absolute()

        # these dirs will be created in build_py, so if you don't have
        # any python sources to bundle, the dirs will be missing
        build_temp = pathlib.Path(self.build_temp)
        build_temp.mkdir(parents=True, exist_ok=True)
        extdir = pathlib.Path(self.get_ext_fullpath(ext.name))
        extdir.mkdir(parents=True, exist_ok=True)

        # example of cmake args
        config = 'Debug' if self.debug else 'Release'
        cmake_args = [
            '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + str(extdir.parent.absolute()),
            '-DCMAKE_BUILD_TYPE=' + config
        ]

        # example of build args
        build_args = [
            '--config', config,
            '--', '-j4'
        ]

        os.chdir(str(build_temp))
        self.spawn(['cmake', str(cwd)] + cmake_args)
        if not self.dry_run:
            self.spawn(['cmake', '--build', '.'] + build_args)
        os.chdir(str(cwd))


def main():
    setup(name="spexi",
          version="1.0.0",
          author="Colin Basnett",
          ext_modules=[CMakeExtension('spexi')],
          package_data={'python_package': ['*.dylib']},
          cmdclass={
              'build_ext': build_ext,
          })


if __name__ == "__main__":
    main()

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.15)
PROJECT(spexi)

SET(CMAKE_CXX_STANDARD 14)

FIND_PACKAGE(Python 3.5 COMPONENTS Development)
INCLUDE_DIRECTORIES(${Python_INCLUDE_DIRS})
LINK_LIBRARIES(${Python_LIBRARIES})

FIND_PACKAGE(TIFF REQUIRED)
INCLUDE_DIRECTORIES(${TIFF_INCLUDE_DIR})
LINK_LIBRARIES(${TIFF_LIBRARIES})

SET(SRC src/vincenty.h src/data.h src/dem.h src/vincenty.cpp src/dem.cpp src/spexi.cpp src/draw.h src/draw.cpp)

ADD_LIBRARY(spexi SHARED ${SRC})
SET_TARGET_PROPERTIES(
        spexi
        PROPERTIES
        PREFIX ""
        OUTPUT_NAME "spexi"
        LINKER_LANGUAGE "CXX"
)

最佳答案

您应该能够通过在 CMakeLists.txt 中使用以下命令来修复此问题:

SET(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")

关于python - 自定义 python 模块引导 .so 文件而不是 .dylib,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59830364/

相关文章:

python - pip 安装项目而不复制整个项目文件夹

python - Python 'build_py' 的步骤 'setup.py install' 中的神秘错误

python - Boost.Python 函数指针作为类构造函数参数

javascript - 如何在 python 中处理 JavaScript blob?

Python 3.3 似乎无法在 pocketsphinx 库中找到解码器模块

python - setup.py 中的 2 到 3 没有涵盖测试?

python - pip3 安装命令重复失败,无法创建文件 '/tmp/pip-install-xxxxx/package'

python - numpy.bincounts 的反转?

python - 如何将 Python 控制台输出重定向到 QTextBox

python - BeautifulSoup:获取空变量