微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 cmake、swig setuptools 项目从复杂的安装文件夹创建包

如何解决如何使用 cmake、swig setuptools 项目从复杂的安装文件夹创建包

我正在编写一个非常复杂的库,它使用 C++ 代码和用 swig 生成的 Python 绑定。该代码旨在用于纯 C++ 或 Python 接口。 当前的部署过程运行良好,但非常基础:cmake -> Visual Studio -> 安装。然后在使用库的 python 脚本中,我必须用正确的路径“附加 sys.path”到已安装的库和 python 模块,例如:

sys.path.insert(0,os.path.abspath(os.path.join('..','install','install_msvc17_python38_64bits','lib','python3.8','site-packages','fms')))

cmake 过程本身非常复杂,有许多子文件夹和一个用于 python 包装的特定文件夹。我不想修改它。

我想为用户简化安装过程。理想情况下,他会运行“python setup.py install”以避免打开 cmake、visual studio,尤其是在路径中添加内容

所以,我最近调查了 setuptool,但老实说,我不明白它到底想要它做什么以及如何做。我找到了几个很好的教程和示例,我创建了一个 setup.py 文件(见下文),但它并不完全是我想要的。

首先我想向您展示使用 cmake 构建过程创建的文件夹:

install_folder

  • 文档
  • 包括
    • python3.8
      • 站点
        • FMS
          • FMS_core.dll
          • FMS_core.py
          • FMS_core.pyd
          • ....
  • 分享(对 cmake 项目有用的东西)
  • 包装(一堆 swig *.i 文件

当我使用 setup.py install 安装东西时,我得到了正确的 cmake 配置、生成、构建、安装,但包会导致问题。这个完整组织的副本在 C:\Anaconda3\Lib\site-packages\FMS-0.6.0-py3.8-win-amd64.egg 中完成。当然,当我在 python 中导入我的库时,我得到了(如预期的......):

>>> import FMS
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
ModuleNotFoundError: No module named 'FMS'

一个好的组织应该是:

  • FMS-0.6.0-py3.8-win-amd64.egg
    • 文档
    • FMS
      • FMS_core.dll
      • FMS_core.py
      • FMS_core.pyd

如何通过 build_ext 掌握anaconda site-package文件夹中的文件夹组织?

非常感谢!

我已经看过的东西:

# -*- coding: utf-8 -*-
import os
import sys
import subprocess
from subprocess import Popen,PIPE
from sysconfig import get_paths
from pprint import pprint

from setuptools import setup,Extension
from setuptools.command.build_ext import build_ext

# Convert distutils Windows platform specifiers to CMake -A arguments
PLAT_TO_CMAKE = {
    "win32": "Win32","win-amd64": "x64","win-arm32": "ARM","win-arm64": "ARM64",}

CMAKE_INSTALL_DIR = "C://Program Files//CMake//bin//cmake.exe"

class CMakeExtension(Extension):
    def __init__(self,name,sourcedir=""):
        Extension.__init__(self,sources=[])
        self.sourcedir = os.path.abspath(sourcedir)

class CMakeBuild_FMS(build_ext):
    def build_extension(self,ext):
        extdir = os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name)))
        #extdir = os.path.join(extdir,'fms')

        #  Python
        python_main_paths = get_paths()  # a dictionary of key-paths
        version_python = str(sys.version_info[0]) + str(sys.version_info[1])
        PYTHON_DIR_EXE =    sys.executable
        PYTHON_DIR_INC =    python_main_paths['include']
        PYTHON_DIR_LIBS =   os.path.join(python_main_paths['data'],'libs',"python" + version_python + ".lib")

        # Utilities (default repositories)
        SWIG_EXE =          os.path.abspath(os.path.join('..','..',"utilities","swigwin-4.0.2","swig.exe"))
        Eigen3_DIR =        os.path.abspath(os.path.join('..',"eigen-3.3.9","install","share","eigen3","cmake"))
        Boost_INCLUDE_DIR = os.path.abspath(os.path.join('..',"boost_1_74_0"))
        FMT_DIR =           os.path.abspath(os.path.join('..',"FMT_V4","install"))

        # RGINE
        RGINE_DIR =         os.path.abspath(os.path.join('..',"rgine","cmake"))

        # required for auto-detection of auxiliary "native" libs
        if not extdir.endswith(os.path.sep):
            extdir += os.path.sep

        cfg = "Debug" if self.debug else "Release"

        # CMake lets you override the generator - we need to check this.
        # Can be set with Conda-Build,for example.
        cmake_generator = os.environ.get("CMAKE_GENERATOR","Visual Studio 15 2017 Win64")

        cmake_args = [
            "-DFMS_VERSION_INFO={}".format(self.distribution.get_version()),"-DCMAKE_BUILD_TYPE={}".format(cfg),# not used on MSVC,but no harm
            "-DSWIG_EXECUTABLE={}".format(SWIG_EXE),"-DCMAKE_INSTALL_PREFIX={}".format(extdir),"-DRGINE_DIR={}".format(RGINE_DIR),"-DEigen3_DIR={}".format(Eigen3_DIR),"-DBoost_INCLUDE_DIR={}".format(Boost_INCLUDE_DIR),"-DFMT_AUTO_DOCUMENTATION={}".format("OFF"),"-DFMT_DIR={}".format(FMT_DIR),"-DFMT_V4_Mode={}".format("Binaries"),"-DPYTHON_EXECUTABLE={}".format(sys.executable),"-DPYTHON_INCLUDE_DIR={}".format(PYTHON_DIR_INC),"-DPYTHON_LIBRARY={}".format(PYTHON_DIR_LIBS),"-DFMS_INSTALL_EXTERNAL_DEPENDENCIES={}".format("TRUE"),"-DFMS_AUTO_DOCUMENTATION={}".format("FALSE"),"-DFMS_Sphinx_AUTO_DOCUMENTATION={}".format("FALSE"),"-DDOXYGEN_SHOW_WARNINGS={}".format("FALSE"),]
        build_args = []

        # Multi-config generators have a different way to specify configs
        cmake_args += [
            "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}".format(cfg.upper(),extdir)
        ]
        build_args += ["--config",cfg]

        if not os.path.exists(self.build_temp):
            os.makedirs(self.build_temp)

        print("CONfigURE / GENERATE PROJET ------------------------------------")
        subprocess.check_call([CMAKE_INSTALL_DIR,"-G",cmake_generator,"-S",ext.sourcedir] + cmake_args,cwd=self.build_temp)

        print("BUILD PROJET ---------------------------------------------------")
        subprocess.check_call([CMAKE_INSTALL_DIR,"--build","."] + build_args,cwd=self.build_temp)

        print("INSTALL PROJET -------------------------------------------------")
        subprocess.check_call([CMAKE_INSTALL_DIR,"--install","."],cwd=self.build_temp)

# The information here can also be placed in setup.cfg - better separation of
# logic and declaration,and simpler if you include description/version in a file.
setup(
    name="FMS",version="0.6.0",author="me",author_email="me@somwhere.mars",description="FMS",long_description="",ext_modules=[CMakeExtension("FMS","")],cmdclass={"build_ext": CMakeBuild_FMS},zip_safe=False,)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。