使用 package_data 将内置框架复制到 Python 包中
Copying a built framework into Python package with package_data
我正在尝试改进 PyBluez installs on macOS. Here 代码在我更改之前的今天的样子。
简而言之,在 macOS 上安装了一个名为 lightblue
的额外包,这取决于一个名为 LightAquaBlue.framework 的框架。今天,它调用 xcodebuild 来构建框架并将其安装到 /Library/Frameworks
,但我想将其更改为将框架嵌入到 Python 包中。
这是我所做的:
packages.append('lightblue')
package_dir['lightblue'] = 'osx'
install_requires += ['pyobjc-core>=3.1', 'pyobjc-framework-Cocoa>=3.1']
# Add the LightAquaBlue framework to the package data as an 'eager resource'
# so that we can extract the whole framework at runtime
package_data['lightblue'] = [ 'LightAquaBlue.framework' ]
eager_resources.append('LightAquaBlue.framework')
# FIXME: This is inelegant, how can we cover the cases?
if 'install' in sys.argv or 'bdist' in sys.argv or 'bdist_egg' in sys.argv:
# Build the framework into osx/
import subprocess
subprocess.check_call([
'xcodebuild', 'install',
'-project', 'osx/LightAquaBlue/LightAquaBlue.xcodeproj',
'-scheme', 'LightAquaBlue',
'DSTROOT=' + os.path.join(os.getcwd(), 'osx'),
'INSTALL_PATH=/',
'DEPLOYMENT_LOCATION=YES',
])
这会在 osx/
(这是 lightblue
包的目录)中构建 LightAquaBlue.framework,然后将其作为 package_data
传递给 setuptools。但是,当我运行pip install --upgrade -v ./pybluez/
时,LightAquaBlue.framework是不是复制的:
creating build/lib/lightblue
copying osx/_bluetoothsockets.py -> build/lib/lightblue
copying osx/_LightAquaBlue.py -> build/lib/lightblue
copying osx/_obexcommon.py -> build/lib/lightblue
copying osx/_IOBluetoothUI.py -> build/lib/lightblue
copying osx/__init__.py -> build/lib/lightblue
copying osx/_IOBluetooth.py -> build/lib/lightblue
copying osx/_obex.py -> build/lib/lightblue
copying osx/_lightblue.py -> build/lib/lightblue
copying osx/obex.py -> build/lib/lightblue
copying osx/_macutil.py -> build/lib/lightblue
copying osx/_lightbluecommon.py -> build/lib/lightblue
如果我 setup.py 在 osx/
中创建一个虚拟文件并将其添加到 package_data
,它 会 被复制。这对我来说表明路径没有混淆。
如果我添加 os.system('ls osx/')
,它还会显示 LightAquaBlue.framework 与我的虚拟文件位于同一位置。
LightAquaBlue
--> LightAquaBlue.framework
DUMMY_FILE_THAT_WORKS
_IOBluetooth.py
_IOBluetoothUI.py
_LightAquaBlue.py
__init__.py
_bluetoothsockets.py
_lightblue.py
_lightbluecommon.py
_macutil.py
_obex.py
_obexcommon.py
obex.py
为什么没有正确复制框架?
它看起来像 setuptools 的文档 contradicts the implementation 实际上 您不能指定要包含在 package_data
.
中的目录
不是很优雅,但是我用了:
# We can't seem to list a directory as package_data, so we will
# recursively add all all files we find
package_data['lightblue'] = []
for path, _, files in os.walk('osx/LightAquaBlue.framework'):
for f in files:
include = os.path.join(path, f)[4:] # trim off osx/
package_data['lightblue'].append(include)
我正在尝试改进 PyBluez installs on macOS. Here 代码在我更改之前的今天的样子。
简而言之,在 macOS 上安装了一个名为 lightblue
的额外包,这取决于一个名为 LightAquaBlue.framework 的框架。今天,它调用 xcodebuild 来构建框架并将其安装到 /Library/Frameworks
,但我想将其更改为将框架嵌入到 Python 包中。
这是我所做的:
packages.append('lightblue')
package_dir['lightblue'] = 'osx'
install_requires += ['pyobjc-core>=3.1', 'pyobjc-framework-Cocoa>=3.1']
# Add the LightAquaBlue framework to the package data as an 'eager resource'
# so that we can extract the whole framework at runtime
package_data['lightblue'] = [ 'LightAquaBlue.framework' ]
eager_resources.append('LightAquaBlue.framework')
# FIXME: This is inelegant, how can we cover the cases?
if 'install' in sys.argv or 'bdist' in sys.argv or 'bdist_egg' in sys.argv:
# Build the framework into osx/
import subprocess
subprocess.check_call([
'xcodebuild', 'install',
'-project', 'osx/LightAquaBlue/LightAquaBlue.xcodeproj',
'-scheme', 'LightAquaBlue',
'DSTROOT=' + os.path.join(os.getcwd(), 'osx'),
'INSTALL_PATH=/',
'DEPLOYMENT_LOCATION=YES',
])
这会在 osx/
(这是 lightblue
包的目录)中构建 LightAquaBlue.framework,然后将其作为 package_data
传递给 setuptools。但是,当我运行pip install --upgrade -v ./pybluez/
时,LightAquaBlue.framework是不是复制的:
creating build/lib/lightblue
copying osx/_bluetoothsockets.py -> build/lib/lightblue
copying osx/_LightAquaBlue.py -> build/lib/lightblue
copying osx/_obexcommon.py -> build/lib/lightblue
copying osx/_IOBluetoothUI.py -> build/lib/lightblue
copying osx/__init__.py -> build/lib/lightblue
copying osx/_IOBluetooth.py -> build/lib/lightblue
copying osx/_obex.py -> build/lib/lightblue
copying osx/_lightblue.py -> build/lib/lightblue
copying osx/obex.py -> build/lib/lightblue
copying osx/_macutil.py -> build/lib/lightblue
copying osx/_lightbluecommon.py -> build/lib/lightblue
如果我 setup.py 在 osx/
中创建一个虚拟文件并将其添加到 package_data
,它 会 被复制。这对我来说表明路径没有混淆。
如果我添加 os.system('ls osx/')
,它还会显示 LightAquaBlue.framework 与我的虚拟文件位于同一位置。
LightAquaBlue
--> LightAquaBlue.framework
DUMMY_FILE_THAT_WORKS
_IOBluetooth.py
_IOBluetoothUI.py
_LightAquaBlue.py
__init__.py
_bluetoothsockets.py
_lightblue.py
_lightbluecommon.py
_macutil.py
_obex.py
_obexcommon.py
obex.py
为什么没有正确复制框架?
它看起来像 setuptools 的文档 contradicts the implementation 实际上 您不能指定要包含在 package_data
.
不是很优雅,但是我用了:
# We can't seem to list a directory as package_data, so we will
# recursively add all all files we find
package_data['lightblue'] = []
for path, _, files in os.walk('osx/LightAquaBlue.framework'):
for f in files:
include = os.path.join(path, f)[4:] # trim off osx/
package_data['lightblue'].append(include)