mirror of
https://github.com/onionshare/onionshare.git
synced 2025-01-10 11:47:27 -03:00
Support cx_Freeze in macOS
This commit is contained in:
parent
ec7fa4ef16
commit
ba5a746e93
3 changed files with 160 additions and 7 deletions
2
desktop/poetry.lock
generated
2
desktop/poetry.lock
generated
|
@ -666,7 +666,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = ">=3.9,<3.10"
|
python-versions = ">=3.9,<3.10"
|
||||||
content-hash = "279d5af1fc6f163903bd24cf0a3e5bcaae4903be4f717298ff19ef096a530c86"
|
content-hash = "a13c1965ecb244469752adb4f03e284c9e7c91fc0247efee74fa902b5e18a9da"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
atomicwrites = [
|
atomicwrites = [
|
||||||
|
|
|
@ -10,7 +10,7 @@ python = ">=3.9,<3.10"
|
||||||
onionshare_cli = {path = "../cli", develop = true}
|
onionshare_cli = {path = "../cli", develop = true}
|
||||||
PySide2 = "5.15.2"
|
PySide2 = "5.15.2"
|
||||||
qrcode = "*"
|
qrcode = "*"
|
||||||
cx_freeze = {version = "*", platform = "win32"}
|
cx_freeze = "*"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
black = "*"
|
black = "*"
|
||||||
|
|
|
@ -19,11 +19,119 @@ You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import platform
|
||||||
|
import cx_Freeze
|
||||||
from cx_Freeze import setup, Executable
|
from cx_Freeze import setup, Executable
|
||||||
|
|
||||||
|
# There's an obscure cx_Freeze bug that I'm hitting that's preventing the macOS
|
||||||
|
# package from getting built. This is some monkeypatching to fix it.
|
||||||
|
|
||||||
|
if platform.system() == "Darwin":
|
||||||
|
import importlib_metadata
|
||||||
|
import shutil
|
||||||
|
import pathlib
|
||||||
|
from pathlib import Path
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
|
||||||
|
class CustomPackagePath(pathlib.PurePosixPath):
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.long_filename = str(filename)
|
||||||
|
self.short_filename = "/".join(filename.as_posix().split("/")[-2:])
|
||||||
|
super(CustomPackagePath, self).__init__()
|
||||||
|
|
||||||
|
def read_text(self, encoding="utf-8"):
|
||||||
|
with self.locate().open(encoding=encoding) as stream:
|
||||||
|
return stream.read()
|
||||||
|
|
||||||
|
def read_binary(self):
|
||||||
|
with self.locate().open("rb") as stream:
|
||||||
|
return stream.read()
|
||||||
|
|
||||||
|
def locate(self):
|
||||||
|
return Path(self.long_filename)
|
||||||
|
|
||||||
|
def as_posix(self):
|
||||||
|
return self.short_filename
|
||||||
|
|
||||||
|
class DistributionCache(importlib_metadata.PathDistribution):
|
||||||
|
_cachedir = TemporaryDirectory(prefix="cxfreeze-")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def at(path):
|
||||||
|
return DistributionCache(Path(path))
|
||||||
|
|
||||||
|
at.__doc__ = importlib_metadata.PathDistribution.at.__doc__
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_name(cls, name):
|
||||||
|
distribution = super().from_name(name)
|
||||||
|
temp_dir = Path(cls._cachedir.name)
|
||||||
|
dist_dir = None
|
||||||
|
files = distribution.files or []
|
||||||
|
prep = importlib_metadata.Prepared(distribution.name)
|
||||||
|
normalized = prep.normalized
|
||||||
|
legacy_normalized = prep.legacy_normalized
|
||||||
|
for file in files:
|
||||||
|
# patch: the onionshare and onionshare_cli files are using absolute paths, which break everything
|
||||||
|
if name in ["onionshare", "onionshare_cli"]:
|
||||||
|
if ".dist-info" not in file.as_posix():
|
||||||
|
continue
|
||||||
|
|
||||||
|
file = CustomPackagePath(file)
|
||||||
|
|
||||||
|
if (
|
||||||
|
not file.match(f"{name}-*.dist-info/*")
|
||||||
|
and not file.match(f"{distribution.name}-*.dist-info/*")
|
||||||
|
and not file.match(f"{normalized}-*.dist-info/*")
|
||||||
|
and not file.match(f"{legacy_normalized}-*.dist-info/*")
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
src_path = file.locate()
|
||||||
|
if not src_path.exists():
|
||||||
|
continue
|
||||||
|
dst_path = temp_dir / file.as_posix()
|
||||||
|
if dist_dir is None:
|
||||||
|
dist_dir = dst_path.parent
|
||||||
|
dist_dir.mkdir(exist_ok=True)
|
||||||
|
shutil.copy2(src_path, dst_path)
|
||||||
|
if dist_dir is None:
|
||||||
|
raise importlib_metadata.PackageNotFoundError(name)
|
||||||
|
return cls.at(dist_dir)
|
||||||
|
|
||||||
|
from_name.__doc__ = importlib_metadata.PathDistribution.from_name.__doc__
|
||||||
|
|
||||||
|
cx_Freeze.module.DistributionCache = DistributionCache
|
||||||
|
|
||||||
|
|
||||||
|
# Discover the version
|
||||||
with open(os.path.join("..", "cli", "onionshare_cli", "resources", "version.txt")) as f:
|
with open(os.path.join("..", "cli", "onionshare_cli", "resources", "version.txt")) as f:
|
||||||
version = f.read().strip()
|
version = f.read().strip()
|
||||||
|
|
||||||
|
|
||||||
|
# Build
|
||||||
|
include_files = [(os.path.join("..", "LICENSE"), "LICENSE")]
|
||||||
|
|
||||||
|
if platform.system() == "Windows":
|
||||||
|
include_msvcr = True
|
||||||
|
gui_base = "Win32GUI"
|
||||||
|
|
||||||
|
elif platform.system() == "Darwin":
|
||||||
|
import PySide2
|
||||||
|
import shiboken2
|
||||||
|
|
||||||
|
include_msvcr = False
|
||||||
|
gui_base = None
|
||||||
|
include_files += [
|
||||||
|
(
|
||||||
|
os.path.join(PySide2.__path__[0], "libpyside2.abi3.5.15.dylib"),
|
||||||
|
"libpyside2.abi3.5.15.dylib",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
os.path.join(shiboken2.__path__[0], "libshiboken2.abi3.5.15.dylib"),
|
||||||
|
"libshiboken2.abi3.5.15.dylib",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="onionshare",
|
name="onionshare",
|
||||||
version=version,
|
version=version,
|
||||||
|
@ -39,17 +147,62 @@ setup(
|
||||||
"jinja2.ext",
|
"jinja2.ext",
|
||||||
"onionshare",
|
"onionshare",
|
||||||
"onionshare_cli",
|
"onionshare_cli",
|
||||||
|
"PySide2",
|
||||||
|
"PySide2.QtCore",
|
||||||
|
"PySide2.QtGui",
|
||||||
|
"PySide2.QtWidgets",
|
||||||
],
|
],
|
||||||
"excludes": ["test", "tkinter"],
|
"excludes": [
|
||||||
"include_files": [("..\LICENSE", "LICENSE")],
|
"test",
|
||||||
"include_msvcr": True,
|
"tkinter",
|
||||||
|
"PySide2.Qt3DAnimation",
|
||||||
|
"PySide2.Qt3DCore",
|
||||||
|
"PySide2.Qt3DExtras",
|
||||||
|
"PySide2.Qt3DInput",
|
||||||
|
"PySide2.Qt3DLogic",
|
||||||
|
"PySide2.Qt3DRender",
|
||||||
|
"PySide2.QtCharts",
|
||||||
|
"PySide2.QtConcurrent",
|
||||||
|
"PySide2.QtDataVisualization",
|
||||||
|
"PySide2.QtHelp",
|
||||||
|
"PySide2.QtLocation",
|
||||||
|
"PySide2.QtMultimedia",
|
||||||
|
"PySide2.QtMultimediaWidgets",
|
||||||
|
"PySide2.QtNetwork",
|
||||||
|
"PySide2.QtOpenGL",
|
||||||
|
"PySide2.QtOpenGLFunctions",
|
||||||
|
"PySide2.QtPositioning",
|
||||||
|
"PySide2.QtPrintSupport",
|
||||||
|
"PySide2.QtQml",
|
||||||
|
"PySide2.QtQuick",
|
||||||
|
"PySide2.QtQuickControls2",
|
||||||
|
"PySide2.QtQuickWidgets",
|
||||||
|
"PySide2.QtRemoteObjects",
|
||||||
|
"PySide2.QtScript",
|
||||||
|
"PySide2.QtScriptTools",
|
||||||
|
"PySide2.QtScxml",
|
||||||
|
"PySide2.QtSensors",
|
||||||
|
"PySide2.QtSerialPort",
|
||||||
|
"PySide2.QtSql",
|
||||||
|
"PySide2.QtTest",
|
||||||
|
"PySide2.QtTextToSpeech",
|
||||||
|
"PySide2.QtUiTools",
|
||||||
|
"PySide2.QtWebChannel",
|
||||||
|
"PySide2.QtWebEngine",
|
||||||
|
"PySide2.QtWebEngineCore",
|
||||||
|
"PySide2.QtWebEngineWidgets",
|
||||||
|
"PySide2.QtWebSockets",
|
||||||
|
"PySide2.QtXml",
|
||||||
|
"PySide2.QtXmlPatterns",
|
||||||
|
],
|
||||||
|
"include_files": include_files,
|
||||||
|
"include_msvcr": include_msvcr,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
executables=[
|
executables=[
|
||||||
Executable(
|
Executable(
|
||||||
"package/onionshare.py",
|
"package/onionshare.py",
|
||||||
# base="Win32GUI",
|
base=gui_base,
|
||||||
base=None,
|
|
||||||
icon=os.path.join("onionshare", "resources", "onionshare.ico"),
|
icon=os.path.join("onionshare", "resources", "onionshare.ico"),
|
||||||
),
|
),
|
||||||
Executable(
|
Executable(
|
||||||
|
|
Loading…
Reference in a new issue