From f8474c23995c31ca9cdb749b0d87bcf2ee48f9fb Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Fri, 6 Nov 2020 13:24:43 -0800 Subject: Write proper Windows release build script, and update Windows release docs --- RELEASE.md | 31 ++-- desktop/README.md | 9 +- desktop/include/site/python3.8/greenlet/greenlet.h | 168 --------------------- desktop/package/macos/build.py | 2 +- desktop/package/windows/build.py | 62 ++++++++ 5 files changed, 84 insertions(+), 188 deletions(-) delete mode 100644 desktop/include/site/python3.8/greenlet/greenlet.h create mode 100644 desktop/package/windows/build.py diff --git a/RELEASE.md b/RELEASE.md index 32f88db7..8ff426b7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -99,40 +99,37 @@ briefcase build ### Windows -Build a wheel package for OnionShare CLI (including Tor binaries, from Tor Browser): +Set up the development environment described in `README.md`. And install the [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk) and add `C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86` to your path. -```sh -cd cli -poetry install -poetry build -``` - -This will make a file like `dist\onionshare_cli-$VERSION-py3-none-any.whl` (except with your specific version number). Move it into `..\desktop`: +Make sure your virtual environment is active: ``` -move dist\onionshare_cli-*-py3-none-any.whl ..\desktop -cd ..\desktop +venv\Scripts\activate.bat ``` -Make sure the virtual environment is active, and then run `briefcase create`: +Run the Windows build script: -```sh -venv\Scripts\activate.bat -briefcase create -briefcase package +``` +python package\windows\build.py ``` -_TODO: Codesign_ +This will create `windows/OnionShare-$VERSION.msi`, signed. ### macOS +Set up the development environment described in `README.md`. And install `create-dmg`: + +```sh +brew install create-dmg +``` + Make sure your virtual environment is active: ```sh . venv/bin/activate ``` -Run the macOS build script (you'll need to `brew install create-dmg` first): +Run the macOS build script: ```sh ./package/macos/build.py --with-codesign diff --git a/desktop/README.md b/desktop/README.md index 8d72f22f..a1406b47 100644 --- a/desktop/README.md +++ b/desktop/README.md @@ -19,7 +19,7 @@ If you're using Linux, install `tor` and `obfs4proxy` from either the [official Download and install Python 3.8.6 from https://www.python.org/downloads/release/python-386/. I downloaded `python-3.8.6-macosx10.9.pkg`. (You may need to also run `/Applications/Python\ 3.8/Install\ Certificates.command`.) -Install some python dependencies: +Install python dependencies: ```sh pip3 install --user poetry requests @@ -39,10 +39,15 @@ Download Python 3.8.6, 32-bit (x86) from https://www.python.org/downloads/releas Download and install 7-Zip from http://www.7-zip.org/download.html. I downloaded `7z1900.exe`. Add `C:\Program Files (x86)\7-Zip` to your path. +Install python dependencies: + +``` +pip install poetry requests +``` + Download Tor Browser and extract the binaries: ``` -pip install requests python scripts\get-tor-windows.py ``` diff --git a/desktop/include/site/python3.8/greenlet/greenlet.h b/desktop/include/site/python3.8/greenlet/greenlet.h deleted file mode 100644 index d68160b5..00000000 --- a/desktop/include/site/python3.8/greenlet/greenlet.h +++ /dev/null @@ -1,168 +0,0 @@ -/* vim:set noet ts=8 sw=8 : */ - -/* Greenlet object interface */ - -#ifndef Py_GREENLETOBJECT_H -#define Py_GREENLETOBJECT_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define GREENLET_VERSION "0.4.17" - -#if PY_VERSION_HEX >= 0x030700A3 -# define GREENLET_USE_EXC_INFO -#endif - -#ifndef GREENLET_USE_CONTEXT_VARS -#ifdef Py_CONTEXT_H -#define GREENLET_USE_CONTEXT_VARS 1 -#else -#define GREENLET_USE_CONTEXT_VARS 0 -#endif -#endif - -typedef struct _greenlet { - PyObject_HEAD - char* stack_start; - char* stack_stop; - char* stack_copy; - intptr_t stack_saved; - struct _greenlet* stack_prev; - struct _greenlet* parent; - PyObject* run_info; - struct _frame* top_frame; - int recursion_depth; - PyObject* weakreflist; -#ifdef GREENLET_USE_EXC_INFO - _PyErr_StackItem* exc_info; - _PyErr_StackItem exc_state; -#else - PyObject* exc_type; - PyObject* exc_value; - PyObject* exc_traceback; -#endif - PyObject* dict; -#if GREENLET_USE_CONTEXT_VARS - PyObject* context; -#endif -} PyGreenlet; - -#define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type) -#define PyGreenlet_MAIN(op) (((PyGreenlet*)(op))->stack_stop == (char*) -1) -#define PyGreenlet_STARTED(op) (((PyGreenlet*)(op))->stack_stop != NULL) -#define PyGreenlet_ACTIVE(op) (((PyGreenlet*)(op))->stack_start != NULL) -#define PyGreenlet_GET_PARENT(op) (((PyGreenlet*)(op))->parent) - -#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 1) || PY_MAJOR_VERSION > 3 -#define GREENLET_USE_PYCAPSULE -#endif - -/* C API functions */ - -/* Total number of symbols that are exported */ -#define PyGreenlet_API_pointers 8 - -#define PyGreenlet_Type_NUM 0 -#define PyExc_GreenletError_NUM 1 -#define PyExc_GreenletExit_NUM 2 - -#define PyGreenlet_New_NUM 3 -#define PyGreenlet_GetCurrent_NUM 4 -#define PyGreenlet_Throw_NUM 5 -#define PyGreenlet_Switch_NUM 6 -#define PyGreenlet_SetParent_NUM 7 - -#ifndef GREENLET_MODULE -/* This section is used by modules that uses the greenlet C API */ -static void **_PyGreenlet_API = NULL; - -#define PyGreenlet_Type (*(PyTypeObject *) _PyGreenlet_API[PyGreenlet_Type_NUM]) - -#define PyExc_GreenletError \ - ((PyObject *) _PyGreenlet_API[PyExc_GreenletError_NUM]) - -#define PyExc_GreenletExit \ - ((PyObject *) _PyGreenlet_API[PyExc_GreenletExit_NUM]) - -/* - * PyGreenlet_New(PyObject *args) - * - * greenlet.greenlet(run, parent=None) - */ -#define PyGreenlet_New \ - (* (PyGreenlet * (*)(PyObject *run, PyGreenlet *parent)) \ - _PyGreenlet_API[PyGreenlet_New_NUM]) - -/* - * PyGreenlet_GetCurrent(void) - * - * greenlet.getcurrent() - */ -#define PyGreenlet_GetCurrent \ - (* (PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM]) - -/* - * PyGreenlet_Throw( - * PyGreenlet *greenlet, - * PyObject *typ, - * PyObject *val, - * PyObject *tb) - * - * g.throw(...) - */ -#define PyGreenlet_Throw \ - (* (PyObject * (*) \ - (PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)) \ - _PyGreenlet_API[PyGreenlet_Throw_NUM]) - -/* - * PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args) - * - * g.switch(*args, **kwargs) - */ -#define PyGreenlet_Switch \ - (* (PyObject * (*)(PyGreenlet *greenlet, PyObject *args, PyObject *kwargs)) \ - _PyGreenlet_API[PyGreenlet_Switch_NUM]) - -/* - * PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent) - * - * g.parent = new_parent - */ -#define PyGreenlet_SetParent \ - (* (int (*)(PyGreenlet *greenlet, PyGreenlet *nparent)) \ - _PyGreenlet_API[PyGreenlet_SetParent_NUM]) - -/* Macro that imports greenlet and initializes C API */ -#ifdef GREENLET_USE_PYCAPSULE -#define PyGreenlet_Import() \ -{ \ - _PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \ -} -#else -#define PyGreenlet_Import() \ -{ \ - PyObject *module = PyImport_ImportModule("greenlet"); \ - if (module != NULL) { \ - PyObject *c_api_object = PyObject_GetAttrString( \ - module, "_C_API"); \ - if (c_api_object != NULL && PyCObject_Check(c_api_object)) { \ - _PyGreenlet_API = \ - (void **) PyCObject_AsVoidPtr(c_api_object); \ - Py_DECREF(c_api_object); \ - } \ - Py_DECREF(module); \ - } \ -} -#endif - -#endif /* GREENLET_MODULE */ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_GREENLETOBJECT_H */ diff --git a/desktop/package/macos/build.py b/desktop/package/macos/build.py index 1c5e6a95..0cf3c57c 100755 --- a/desktop/package/macos/build.py +++ b/desktop/package/macos/build.py @@ -36,7 +36,7 @@ def main(): print("○ Building onionshare-cli") run(["poetry", "install"], cli_dir) run(["poetry", "build"], cli_dir) - whl_filename = glob.glob(f"{cli_dir}/dist/*.whl")[0] + whl_filename = glob.glob(os.path.join(cli_dir, "dist", "*.whl"))[0] whl_basename = os.path.basename(whl_filename) shutil.copyfile(whl_filename, os.path.join(desktop_dir, whl_basename)) diff --git a/desktop/package/windows/build.py b/desktop/package/windows/build.py new file mode 100644 index 00000000..3ee7de4f --- /dev/null +++ b/desktop/package/windows/build.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +import os +import inspect +import subprocess +import argparse +import shutil +import glob + +root = os.path.dirname( + os.path.dirname( + os.path.dirname( + os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + ) + ) +) + + +def run(cmd, cwd=None): + subprocess.run(cmd, cwd=cwd, check=True) + + +def main(): + cli_dir = os.path.join(root, "cli") + desktop_dir = os.path.join(root, "desktop") + + print("○ Building onionshare-cli") + run(["poetry", "install"], cli_dir) + run(["poetry", "build"], cli_dir) + whl_filename = glob.glob(os.path.join(cli_dir, "dist", "*.whl"))[0] + whl_basename = os.path.basename(whl_filename) + shutil.copyfile(whl_filename, os.path.join(desktop_dir, whl_basename)) + + print("○ Clean up from last build") + if os.path.exists(os.path.join(desktop_dir, "windows")): + shutil.rmtree(os.path.join(desktop_dir, "windows")) + + print("○ Create the binary") + run(["briefcase", "create"], desktop_dir) + run(["briefcase", "package"], desktop_dir) + msi_filename = os.path.join(desktop_dir, "windows", "OnionShare-2.3.dev1.msi") + print(f"○ Created unsigned installer: {msi_filename}") + + print(f"○ Signing installer") + run( + [ + "signtool.exe", + "sign", + "/v", + "/d", + "OnionShare", + "/a", + "/tr", + "http://time.certum.pl/", + msi_filename, + ], + desktop_dir, + ) + print(f"○ Signed installer: {msi_filename}") + + +if __name__ == "__main__": + main() \ No newline at end of file -- cgit v1.2.3-54-g00ecf