From 931863d4ee5dedf2702ea39395db217e32fe40df Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Thu, 16 Jan 2025 19:55:50 +0100 Subject: [PATCH] Build binary on linux --- .gitignore | 1 + novelwriter/config.py | 8 ++++---- pkgutils.py | 6 ++++++ utils/binary_dist.py | 43 +++++++++++++++++++++++++++++++++++++++++++ utils/common.py | 25 +++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 utils/binary_dist.py create mode 100644 utils/common.py diff --git a/.gitignore b/.gitignore index a69e4f00..90e51a5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Setup/Install /MANIFEST /build/ +/build_*/ /deploy/ /dist/ /dist_*/ diff --git a/novelwriter/config.py b/novelwriter/config.py index 14123d8a..3d6210af 100644 --- a/novelwriter/config.py +++ b/novelwriter/config.py @@ -109,10 +109,10 @@ class Config: self._appPath = Path(__file__).parent.absolute() self._appRoot = self._appPath.parent - if self._appRoot.is_file(): - # novelWriter is packaged as a single file - self._appRoot = self._appRoot.parent - self._appPath = self._appRoot + if getattr(sys, "frozen", False): + # novelWriter is packaged as an exe + self._appPath = Path(__file__).parent.parent.absolute() + self._appRoot = self._appPath # Runtime Settings and Variables self._hasError = False # True if the config class encountered an error diff --git a/pkgutils.py b/pkgutils.py index ce350dbb..1110b287 100755 --- a/pkgutils.py +++ b/pkgutils.py @@ -1509,6 +1509,12 @@ if __name__ == "__main__": ) cmdBuildSetupExe.set_defaults(func=makeWindowsEmbedded) + # Build Binary + cmdBuildBinary = parsers.add_parser( + "build-bin", help="Build a standalone binary package." + ) + cmdBuildBinary.set_defaults(func=utils.binary_dist.main) + # Build Clean cmdBuildClean = parsers.add_parser( "build-clean", help="Recursively delete all build folders." diff --git a/utils/binary_dist.py b/utils/binary_dist.py new file mode 100644 index 00000000..37dce983 --- /dev/null +++ b/utils/binary_dist.py @@ -0,0 +1,43 @@ +""" +novelWriter – Binary Dist Tools +=============================== + +This file is a part of novelWriter +Copyright (C) 2025 Veronica Berglyd Olsen and novelWriter contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +from __future__ import annotations + +import argparse + +import PyInstaller.__main__ + + +def runPyinstaller() -> None: + """Run the pyinstaller.""" + build = ["novelWriter.py", "--clean", "--windowed", "--onedir", "--noconfirm"] + build += ["--name", "novelwriter"] + build += ["--workpath", "build_bin"] + build += ["--distpath", "dist_bin"] + build += ["--hidden-import", "pyenchant"] + build += ["--add-data", "novelwriter/assets:assets"] + PyInstaller.__main__.run(build) + return + + +def main(args: argparse.Namespace) -> None: + """Entry point function.""" + runPyinstaller() + return diff --git a/utils/common.py b/utils/common.py new file mode 100644 index 00000000..148db07e --- /dev/null +++ b/utils/common.py @@ -0,0 +1,25 @@ +""" +novelWriter – Common Utils +========================== + +This file is a part of novelWriter +Copyright (C) 2025 Veronica Berglyd Olsen and novelWriter contributors + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" +from __future__ import annotations + +from pathlib import Path + +ROOT_DIR = Path(__file__).parent.parent