{"id":18838604,"url":"https://github.com/beeware/mobile-forge","last_synced_at":"2025-04-14T06:23:37.872Z","repository":{"id":195922624,"uuid":"693942720","full_name":"beeware/mobile-forge","owner":"beeware","description":"A tool to manage building cross-platform binary wheels for mobile devices","archived":false,"fork":false,"pushed_at":"2025-03-31T00:48:22.000Z","size":486,"stargazers_count":28,"open_issues_count":10,"forks_count":17,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-03-31T01:27:45.576Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/beeware.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["freakboy3742"],"custom":["http://beeware.org/bee/join"]}},"created_at":"2023-09-20T02:49:30.000Z","updated_at":"2025-03-31T00:48:24.000Z","dependencies_parsed_at":"2023-12-27T03:32:24.779Z","dependency_job_id":"bbd99ad5-cf43-4077-9bc5-bf5429362cd2","html_url":"https://github.com/beeware/mobile-forge","commit_stats":null,"previous_names":["beeware/mobile-forge"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeware%2Fmobile-forge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeware%2Fmobile-forge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeware%2Fmobile-forge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/beeware%2Fmobile-forge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/beeware","download_url":"https://codeload.github.com/beeware/mobile-forge/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248831312,"owners_count":21168445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-08T02:40:00.294Z","updated_at":"2025-04-14T06:23:37.845Z","avatar_url":"https://github.com/beeware.png","language":"Python","funding_links":["https://github.com/sponsors/freakboy3742","http://beeware.org/bee/join"],"categories":[],"sub_categories":[],"readme":"Mobile Forge\n============\n\nThis is a forge-like environment that can be used to build wheels for mobile\nplatforms. It is currently only tested for iOS, but in theory, it should also be\nusable for Android. Contributions to verify Android support, tvOS and watchOS\nsupport, and to add more package recipes, are enthusiastically encouraged.\n\nUsage\n-----\n\nThis repo contains an activation script that will configure your environment so\nit's ready to use. To set up a build environment:\n\n1. Ensure you have ``git-lfs`` installed (``git lfs --version`` should return a\n   version number, not an error). ``git-lfs`` is available from\n   `https://git-lfs.com \u003chttps://git-lfs.com\u003e`_, or by running ``brew install\n   git-lfs``.\n\n2. Clone this repository::\n\n    $ git clone https://github.com/beeware/mobile-forge.git\n    $ cd mobile-forge\n\n3. Run the script for the Python version you want to use, providing the support\n   revision::\n\n    $ source ./setup-iOS.sh 3.11\n\nRunning this script will create a Python virtual environment, install Mobile\nForge and some other required tools, and provide some hints at forge commands\nyou can run.\n\nIf a virtual environment already exists, it will be activated, and the same hints\ndisplayed.\n\n``lru-dict`` is a good first package to try compiling::\n\n  (venv3.11) $ forge iOS lru-dict\n\nOr, to build a wheel for a single architecture::\n\n  (venv3.11) $ forge iphonesimulator:12.0:arm64 lru-dict\n\nOnce this command completes, there should be a wheel for each platform in the ``dist``\nfolder. A log for each successful build will be in the ``logs`` folder; a log for each\nunsuccessful build (if there are any) will be in the ``errors`` folder.\n\nLocal support package builds\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nBy default, the Mobile Forge setup script will download a support revision and\nuse the binaries in the downloaded package. However, you can also use a local\nbuild of the support package.\n\nAfter cloning and building `Python-Apple-support\n\u003chttps://github.com/beeware/Python-Apple-support\u003e`__, set the\n``PYTHON_APPLE_SUPPORT`` environment variable to the root of the\nPython-Apple-support checkout. Then run the ``setup-iOS.sh`` script to configure\nyour environment.\n\nSpecific support package builds\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nThe Mobile Forge setup script will download a support package for any supported\nPython version. The version that is downloaded is hard-coded in the setup\nscript. To use a specific revision rather than the default, add the revision\nnumber as an additional argument to the setup script. For example, to use\nrevision 4 of the 3.11 support package, run::\n\n    $ source ./setup-iOS.sh 3.11 4\n\nThe special snowflakes\n----------------------\n\nMobile Forge is trying to support multiple packages, building on multiple Python\nversions, for multiple architectures; and some of those Python versions were released\nbefore the release of ARM64 macOS hardware. As a result, some versions of some packages\nhave some quirks that must be taken into account.\n\nPandas\n~~~~~~\n\nPandas uses a meta-package named ``oldest-supported-numpy`` to ensure ABI compatibility\nduring compilation. However, this can install a different version of numpy, depending on\nthe platform. This is especially problematic for Python 3.9, because the minimum\nsupported version for Python 3.9 on ARM64 is different to the version that is installed\nfor x86_64. Mobile-forge produces a replacement ``oldest-supported-numpy`` package, tagged\nas version 2999.1.1, which ensures that consistent versions are available for build\npurposes; however, this wheel *should not* be published.\n\nCryptography\n~~~~~~~~~~~~\n\nCryptography currently builds a *very* old version (3.4.8). This is the last version\nthat could be built without a Rust compiler.\n\nWhat now?\n---------\n\nTo include these wheels in a test project, you can add the ``dist`` folder as a links\nsource in your ``requires`` definition in your Briefcase ``pyproject.toml``. For\nexample, the following will install the ``lru-dict`` wheels you've just compiled::\n\n    requires = [\n        \"--find-links\", \"/path/to/mobile-forge/dist\",\n        \"lru-dict\",\n    ]\n\nAdding your own packages\n------------------------\n\nIf there's a package that you want that doesn't have an existing recipe, you can add a\nrecipe for that package.\n\nCreate a directory in ``recipes``. The name of the directory must be in PyPI normalized\nform (PEP 503). Alternatively, you can create this directory somewhere else, and pass\nits path when calling ``forge``.\n\nInside the recipe directory, add the following files.\n\n* A `meta.yaml` file. This supports a subset of Conda syntax, defined in `meta-schema.yaml`.\n* A `test.py` file (or `test` package), to run on a target installation. This should contain a\n  pytest suite which imports the package and does some basic checks.\n* Optionally, one or more patch files in a folder named ``patches``. These patches will be\n  applied when the source code is unpacked for a given platform.\n* For non-Python packages, a ``build.sh`` script. This is the script that will be executed\n  in the build environment build the package. This script should invoke any ``configure``,\n  ``make``, or any other compilation steps needed to build the package. This script will be\n  executed in an environment that defines the following environment variables:\n\n    - ``AR`` - the ``AR`` value used to compile the host Python, as determined from\n      ``sysconfig``\n    - ``CC`` - the ``CC`` value used to compile the host Python, as determined from\n      ``sysconfig``.\n    - ``CFLAGS`` - the ``CFLAGS`` value used to compile the host Python, as determined\n      from ``sysconfig``, augmented with the include paths for the SDK, and\n      ``opt/include`` in the host environment's site-packages.\n    - ``LDFLAGS`` - the ``CFLAGS`` value used to compile the host Python, as determined\n      from ``sysconfig``, augmented with the library paths for the SDK, and\n      ``opt/lib`` in the host environment's site-packages.\n    - ``CPU_COUNT`` - The number of CPUs that are available, as determined by\n      ``multiprocessing.cpu_count()``\n    - ``HOST_TRIPLET`` - the GCC compiler triplet for the host platform (e.g.,\n      ``aarch64-apple-ios12.0-simulator``)\n    - ``BUILD_TRIPLET`` - the GCC compiler triplet for the build platform (e.g.,\n      ``aarch64-apple-darwin``)\n    - ``PREFIX`` - a location where the compiled package can be installed in preparation\n      for packaging.\n\n  This script should install the package into ``$PREFIX``. Mobile Forge will package any\n  content installed into ``$PREFIX`` into a \"wheel\" that can be installed as a host\n  requirement.\n\nPython-based projects\n~~~~~~~~~~~~~~~~~~~~~\n\nAll Python projects are compiled using ``python -m build``, using a clean `crossenv\n\u003chttps://github.com/benfogle/crossenv\u003e`__ virtual environment for each platform of a\npackage. Any PEP518 build requirements will be included in both the host and build\nenvironments.\n\nIf you're lucky, all you'll need to do is define a ``meta.yaml`` that describes the\npackage name and version: e.g.,::\n\n    package:\n      name: blis\n      version: 0.4.1\n\nIf this doesn't result in a successful build, it will likely be for one of the following\nreasons:\n\n1. **The build process has a dependency on a system library**. For example, Pillow has a\n   dependency on ``libjpeg``. ``libjpeg`` isn't available on PyPI; but it *is* possible\n   to build a \"wheel\" for ``libjpeg``, so it can be specified as a requirement.\n\n   A non-python \"wheel\" is constructed by compiling the package for your target platform,\n   then installing it into a folder named ``opt``. As a result of this \"install\", you'll\n   usually end up with an ``opt/include`` and ``opt/lib`` folder; Mobile Forge will then\n   wrap up this ``opt`` folder in a wheel, along with Python wheel metadata.\n\n   When this \"wheel\" is specified as a host requirement, the \"wheel\" will be unpacked\n   into the site packages folder of your cross-compilation host environment. This path\n   the ``include`` and ``lib`` paths will be automatically included in the\n   ``CFLAGS``/``LDFLAGS`` environment variables when the Python build is executed.\n\n2. **The build process has a dependency on external tooling**. Mobile Forge will\n   configure a C and C++ compiler using the same configuration that was used to compile\n   the support libraries; however a package may require addition build tooling (e.g., a\n   Fortran compiler) to complete the build. If this is the case, you'll need to find a\n   version of the tool that can target mobile platforms, and work out how to modify the\n   build process to apply any necessary compiler flags.\n\n3. **The build script has platform-specific logic**. For example,\n   if the ``setup.py`` file contain an ``if sys.platform == ...`` clauses, it is unlikely\n   that a mobile platform will trigger the right logic.\n\nIf you need to make any alterations to a project's source code for a build to succeed,\nyou can provide those patches by putting them in one or more files in a folder named\n``patches`` in the recipe folder. These patches will be applied once the source code\nhas been unpacked.\n\nConfigure-based projects\n~~~~~~~~~~~~~~~~~~~~~~~~\n\nIf the project includes a `configure` script, you will likely need to provide a patch\nfor `config.sub`. `config.sub` is the tools used by `configure` to identify the\narchitecture and machine type; however, it doesn't currently recognize the host triples\nused by Apple. If you get the error::\n\n    checking host system type... Invalid configuration `arm64-apple-ios': machine `arm64-apple' not recognized\n    configure: error: /bin/sh config/config.sub arm64-apple-ios failed\n\nyou will need to patch `config.sub`. There are several examples of patched `config.sub`\nscripts in the packages contained in this repository, and in the Python-Apple-support\nproject; it is quite possible one of those patches can be used for the library you are\ntrying to compile. The `config.sub` script has a datestamp at the top of the file; that\ncan be used to identify which patch you will need.\n\nCommunity\n---------\n\nMobile Forge is part of the `BeeWare suite`_. You can talk to the community through:\n\n* `@beeware@fosstodon.org on Mastodon \u003chttps://fosstodon.org/@beeware\u003e`__\n\n* `Discord \u003chttps://beeware.org/bee/chat/\u003e`__\n\n* The Mobile Forge `Github Discussions forum \u003chttps://github.com/beeware/mobile-forge/discussions\u003e`__\n\nWe foster a welcoming and respectful community as described in our\n`BeeWare Community Code of Conduct`_.\n\nContributing\n------------\n\nIf you experience problems with Mobile Forge, `log them on GitHub`_. If you\nwant to contribute code, please `fork the code`_ and `submit a pull request`_.\n\n.. _BeeWare suite: http://beeware.org\n.. _Read The Docs: https://briefcase.readthedocs.io\n.. _BeeWare Community Code of Conduct: http://beeware.org/community/behavior/\n.. _log them on Github: https://github.com/beeware/mobile-forge/issues\n.. _fork the code: https://github.com/beeware/mobile-forge\n.. _submit a pull request: https://github.com/beeware/mobile-forge/pulls\n\nAcknowledgements\n----------------\n\nThis project draws significantly on the implementation and knowledge developed in the\n`Chaquopy package builder\n\u003chttps://github.com/chaquo/chaquopy/tree/master/server/pypi\u003e`__. Although this is\nlargely a \"clean room\" reimplementation of that project, many details from that project\nhave been used in the development of this one.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeeware%2Fmobile-forge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbeeware%2Fmobile-forge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbeeware%2Fmobile-forge/lists"}