├── .github └── workflows │ ├── build-and-test.yaml │ ├── check-formatting.yaml │ └── reuse-lint.yaml ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── LICENSES ├── Apache-2.0.txt ├── CC-BY-4.0.txt ├── CC0-1.0.txt └── LGPL-2.1-or-later.txt ├── Makefile ├── README.md ├── UPDATING.md ├── assets └── init_shim.erl ├── examples ├── myapp │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── rebar.config │ └── src │ │ ├── myapp.app.src │ │ └── myapp.erl └── otp_application │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── rebar.config │ └── src │ ├── otp_application.app.src │ ├── otp_application_app.erl │ ├── otp_application_sup.erl │ └── otp_application_worker.erl ├── priv ├── .gitignore ├── LICENSE ├── README.md ├── atomvm_app.template ├── rebar.config └── src │ ├── atomvm_app.app.src │ └── atomvm_app.erl ├── rebar.config ├── src ├── atomvm_bootstrap_provider.erl ├── atomvm_esp32_flash_provider.erl ├── atomvm_packbeam_provider.erl ├── atomvm_pico_flash_provider.erl ├── atomvm_rebar3_plugin.app.src ├── atomvm_rebar3_plugin.erl ├── atomvm_stm32_flash_provider.erl ├── atomvm_uf2create_provider.erl ├── atomvm_version_provider.erl ├── legacy_esp32_flash_provider.erl ├── legacy_packbeam_provider.erl └── legacy_stm32_flash_provider.erl └── test ├── driver ├── apps │ ├── bootstrap │ │ ├── bootstrap │ │ │ └── application.erl │ │ ├── rebar.config │ │ └── src │ │ │ ├── myapp.app.src │ │ │ ├── myapp.erl │ │ │ └── start.erl │ ├── multi-start │ │ ├── rebar.config │ │ └── src │ │ │ ├── myapp.app.src │ │ │ ├── myapp.erl │ │ │ └── start.erl │ ├── myapp │ │ ├── rebar.config │ │ └── src │ │ │ ├── myapp.app.src │ │ │ └── myapp.erl │ ├── otp_application │ │ ├── rebar.config │ │ └── src │ │ │ ├── my_app.app.src │ │ │ └── my_app.erl │ ├── prune │ │ ├── rebar.config │ │ └── src │ │ │ ├── a.erl │ │ │ ├── b.erl │ │ │ ├── c.erl │ │ │ ├── d.erl │ │ │ ├── myapp.app.src │ │ │ └── myapp.erl │ └── rebar_overrides │ │ ├── rebar.config │ │ └── src │ │ ├── myapp.app.src │ │ ├── myapp.erl │ │ └── start.erl ├── rebar.config ├── scripts │ ├── clean.sh │ └── prepare.sh └── src │ ├── bootstrap_tests.erl │ ├── driver.app.src │ ├── driver.erl │ ├── esp32_flash_tests.erl │ ├── packbeam_tests.erl │ ├── stm32_flash_tests.erl │ └── test.erl └── run.sh /.github/workflows/build-and-test.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 Fred Dushin 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 5 | # 6 | 7 | name: Build and Test 8 | 9 | on: [push, pull_request] 10 | 11 | jobs: 12 | build-and-test: 13 | runs-on: "ubuntu-22.04" 14 | strategy: 15 | matrix: 16 | otp: ["25", "26", "27", "28"] 17 | 18 | steps: 19 | # Setup 20 | - name: "Checkout repo" 21 | uses: actions/checkout@v2 22 | with: 23 | submodules: 'recursive' 24 | 25 | - uses: erlef/setup-beam@v1 26 | with: 27 | otp-version: ${{ matrix.otp }} 28 | 29 | # Builder info 30 | - name: "System info" 31 | run: | 32 | echo "**uname:**" 33 | uname -a 34 | echo "**OTP version:**" 35 | cat $(dirname $(which erlc))/../releases/RELEASES || true 36 | 37 | - name: "Install deps" 38 | run: | 39 | sudo apt install -y make git 40 | 41 | - name: "Build rebar3" 42 | run: | 43 | cd /tmp 44 | git clone https://github.com/erlang/rebar3.git 45 | cd rebar3 46 | ./bootstrap 47 | 48 | # Build 49 | - name: "Make" 50 | run: PATH="/tmp/rebar3:${PATH}" make all 51 | -------------------------------------------------------------------------------- /.github/workflows/check-formatting.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 Davide Bettio 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 5 | # 6 | 7 | name: "Check formatting" 8 | 9 | on: 10 | push: 11 | paths: 12 | - '**/*.erl' 13 | pull_request: 14 | paths: 15 | - '**/*.erl' 16 | 17 | concurrency: 18 | group: ${{ github.workflow }}-${{ github.ref != 'refs/heads/master' && github.ref || github.run_id }} 19 | cancel-in-progress: true 20 | 21 | jobs: 22 | erlfmt-check: 23 | runs-on: ubuntu-24.04 24 | container: erlang:27 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: "Check formatting with Erlang fmt" 29 | run: | 30 | cd .. 31 | git clone --depth 1 -b v1.1.0 https://github.com/WhatsApp/erlfmt.git 32 | cd erlfmt 33 | rebar3 as release escriptize 34 | cd ../atomvm_rebar3_plugin 35 | find . -name *.erl | xargs ../erlfmt/_build/release/bin/erlfmt -c 36 | -------------------------------------------------------------------------------- /.github/workflows/reuse-lint.yaml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V. 2 | # 3 | # SPDX-License-Identifier: CC0-1.0 4 | 5 | name: REUSE Compliance Check 6 | 7 | on: [push, pull_request] 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref != 'refs/heads/master' && github.ref || github.run_id }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | test: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: REUSE Compliance Check 19 | uses: fsfe/reuse-action@v1 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## 2 | ## Copyright 2020-2023 Fred Dushin 3 | ## 4 | ## SPDX-License-Identifier: Apache-2.0 5 | ## 6 | 7 | **/_build/** 8 | **/_checkouts/** 9 | **/rebar.lock 10 | **/rebar3.crashdump 11 | **/erl_crash.dump 12 | !priv/.gitignore 13 | !examples/myapp/.gitignore 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Changelog 8 | 9 | All notable changes to this project will be documented in this file. 10 | 11 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 12 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 13 | 14 | ## [0.7.5] (2025.05.27) 15 | 16 | ### Fixed 17 | - Fixed broken dependencies when pulling from hex.pm 18 | 19 | ## [0.7.4] (2025.05.25) 20 | 21 | ### Added 22 | - Added support for the `--application` (or `-a`) option to support AtomVM OTP applications. 23 | - Support for OTP 28 (in updated atomvm_packeam 0.7.4) 24 | 25 | ### Fixed 26 | - Fixed the `rebar3 new atomvm_app` template rebar.config file to use the provided app name for the start module. 27 | 28 | ### Changed 29 | 30 | - Using the `-s init` option is still supported but deprecated. Use the `--application` (or `-a`) option to generate OTP applications using AtomVM. 31 | - Replace `atomvm_uf2create_provider` uf2 creation code with [upstream `uf2tool`](https://github.com/pguyot/uf2tool) 32 | - `pico_flash` task now uses picotool to reset the rp2040 device if a serial monitor is attached. 33 | - Update `atomvm_packbeam` dependency to 0.7.4. 34 | 35 | ## [0.7.3] (2023.11.25) 36 | 37 | - Added support for compiling "bootstrap" erlang files that `rebar3` otherwise cannot compile. 38 | - Added profiles to minimize downstream dependencies 39 | - Misc license cleanup 40 | 41 | ## [0.7.2] (2023.10.24) 42 | 43 | - Updated to depend on `atomvm_packbeam` version `0.7.1`, to make use of `packbeam_api` changes. 44 | - Added tests for `packbeam`, `esp32`, and `stm32` tasks. 45 | - Generate `ex_doc` documentation instead of `edoc`. 46 | - Added `version` task to print the version of the plugin to the console 47 | 48 | ## [0.7.1] (2023.10.18) 49 | 50 | - Fixed a bug whereby a missing `atomvm_rebar3_plugin` entry in `rebar.config` would crash the `packbeam` task. 51 | 52 | ## [0.7.0] (2023.10.18) 53 | 54 | - Moved atomvm tasks under the `atomvm` namespace (with support for deprecated tasks in the default namespace) 55 | - Added `utf2create` and `pico_flash` tasks, for Raspberry Pico support 56 | - Added support for setting options in `rebar.config` 57 | - Added `--list` (`-l`) option to `packbeam` to to display contents of generated AVM files. 58 | 59 | ## [0.6.1] (2023.07.16) 60 | 61 | ### Added 62 | 63 | - Added `stm32_flash` rebar3 task 64 | - Added `-r|--remove_lines` command line option to `packbeam` task 65 | 66 | ### Changed 67 | - Updated dependency on `atomvm_packbeam` 0.6 or later 68 | - Changed default to not remove lines from generated AVM files 69 | 70 | ## [0.6.0] (2022.12.18) 71 | 72 | ### Added 73 | - Added ability to include `<<"Line">>` chunks in BEAM files in generated AVM files 74 | 75 | ### Changed 76 | - Updated dependency on `atomvm_packbeam` 0.6.0 77 | 78 | ## [0.5.1] (2022.08.31) 79 | 80 | ### Fixed 81 | - Fixed Hex dependency on atomvm_packbeam 0.5.0 82 | 83 | ## [0.5.0] (2022.08.28) 84 | 85 | ### Added 86 | - Added packing of application bin file to packbeam file. 87 | 88 | ## [0.4.1] (2022.06.19) 89 | 90 | ### Changed 91 | - Updated dependency on `atomvm_packbeam` 0.4.1 92 | 93 | ## [0.4.0] (2022.05.21) 94 | 95 | ### Added 96 | - Added `erlfmt` plugin and formatted code. 97 | - Added `--chip` option to `esp32_flash` task 98 | 99 | ### Fixed 100 | - Fixed a bug that prevented files in directories inside of the `priv` directory to be included in packbeam files. 101 | 102 | ## [0.3.0] (2022.05.18) 103 | 104 | ### Changed 105 | - Updated dependency on `atomvm_packbeam` `0.3.0` 106 | 107 | ## [0.2.0] (?) 108 | 109 | ### Added 110 | - Added plugin template for generating applications 111 | - Added support for deployment to hex 112 | - Added support for `--start` flag 113 | 114 | ### Changed 115 | - Updated default flash location 116 | 117 | ## [0.1.0] (2020.05.17) 118 | - Initial Release 119 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Contributor Covenant Code of Conduct 8 | 9 | ## Our Pledge 10 | 11 | We as members, contributors, and leaders pledge to make participation in our 12 | community a harassment-free experience for everyone, regardless of age, body 13 | size, visible or invisible disability, ethnicity, sex characteristics, gender 14 | identity and expression, level of experience, education, socio-economic status, 15 | nationality, personal appearance, race, religion, or sexual identity 16 | and orientation. 17 | 18 | We pledge to act and interact in ways that contribute to an open, welcoming, 19 | diverse, inclusive, and healthy community. 20 | 21 | ## Our Standards 22 | 23 | Examples of behavior that contributes to a positive environment for our 24 | community include: 25 | 26 | * Demonstrating empathy and kindness toward other people 27 | * Being respectful of differing opinions, viewpoints, and experiences 28 | * Giving and gracefully accepting constructive feedback 29 | * Accepting responsibility and apologizing to those affected by our mistakes, 30 | and learning from the experience 31 | * Focusing on what is best not just for us as individuals, but for the 32 | overall community 33 | 34 | Examples of unacceptable behavior include: 35 | 36 | * The use of sexualized language or imagery, and sexual attention or 37 | advances of any kind 38 | * Trolling, insulting or derogatory comments, and personal or political attacks 39 | * Public or private harassment 40 | * Publishing others' private information, such as a physical or email 41 | address, without their explicit permission 42 | * Other conduct which could reasonably be considered inappropriate in a 43 | professional setting 44 | 45 | ## Enforcement Responsibilities 46 | 47 | Community leaders are responsible for clarifying and enforcing our standards of 48 | acceptable behavior and will take appropriate and fair corrective action in 49 | response to any behavior that they deem inappropriate, threatening, offensive, 50 | or harmful. 51 | 52 | Community leaders have the right and responsibility to remove, edit, or reject 53 | comments, commits, code, wiki edits, issues, and other contributions that are 54 | not aligned to this Code of Conduct, and will communicate reasons for moderation 55 | decisions when appropriate. 56 | 57 | ## Scope 58 | 59 | This Code of Conduct applies within all community spaces, and also applies when 60 | an individual is officially representing the community in public spaces. 61 | Examples of representing our community include using an official e-mail address, 62 | posting via an official social media account, or acting as an appointed 63 | representative at an online or offline event. 64 | 65 | ## Enforcement 66 | 67 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 68 | reported to the community leaders responsible for enforcement at 69 | davide AT uninstall.it. 70 | All complaints will be reviewed and investigated promptly and fairly. 71 | 72 | All community leaders are obligated to respect the privacy and security of the 73 | reporter of any incident. 74 | 75 | ## Enforcement Guidelines 76 | 77 | Community leaders will follow these Community Impact Guidelines in determining 78 | the consequences for any action they deem in violation of this Code of Conduct: 79 | 80 | ### 1. Correction 81 | 82 | **Community Impact**: Use of inappropriate language or other behavior deemed 83 | unprofessional or unwelcome in the community. 84 | 85 | **Consequence**: A private, written warning from community leaders, providing 86 | clarity around the nature of the violation and an explanation of why the 87 | behavior was inappropriate. A public apology may be requested. 88 | 89 | ### 2. Warning 90 | 91 | **Community Impact**: A violation through a single incident or series 92 | of actions. 93 | 94 | **Consequence**: A warning with consequences for continued behavior. No 95 | interaction with the people involved, including unsolicited interaction with 96 | those enforcing the Code of Conduct, for a specified period of time. This 97 | includes avoiding interactions in community spaces as well as external channels 98 | like social media. Violating these terms may lead to a temporary or 99 | permanent ban. 100 | 101 | ### 3. Temporary Ban 102 | 103 | **Community Impact**: A serious violation of community standards, including 104 | sustained inappropriate behavior. 105 | 106 | **Consequence**: A temporary ban from any sort of interaction or public 107 | communication with the community for a specified period of time. No public or 108 | private interaction with the people involved, including unsolicited interaction 109 | with those enforcing the Code of Conduct, is allowed during this period. 110 | Violating these terms may lead to a permanent ban. 111 | 112 | ### 4. Permanent Ban 113 | 114 | **Community Impact**: Demonstrating a pattern of violation of community 115 | standards, including sustained inappropriate behavior, harassment of an 116 | individual, or aggression toward or disparagement of classes of individuals. 117 | 118 | **Consequence**: A permanent ban from any sort of public interaction within 119 | the community. 120 | 121 | ## Attribution 122 | 123 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 124 | version 2.0, available at 125 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 126 | 127 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 128 | enforcement ladder](https://github.com/mozilla/diversity). 129 | 130 | [homepage]: https://www.contributor-covenant.org 131 | 132 | For answers to common questions about this code of conduct, see the FAQ at 133 | https://www.contributor-covenant.org/faq. Translations are available at 134 | https://www.contributor-covenant.org/translations. 135 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # Contributing 8 | 9 | Before contributing, please read carefully our [Code of Conduct](CODE_OF_CONDUCT.md) and 10 | the following contribution guidelines. 11 | 12 | Please, also make sure to understand the [Apache-2.0 license](LICENSE.md) and the 13 | [Developer Certificate of Origin](https://developercertificate.org/). 14 | 15 | Last but not least, **do not use GitHub issues for vulnerability reports**, read instead the 16 | [security policy](SECURITY.md) for instructions. 17 | 18 | ## Git Recommended Practises 19 | 20 | * Commit messages should have a 21 | * [summary and a description](https://github.com/erlang/otp/wiki/writing-good-commit-messages) 22 | * Avoid trailing white spaces 23 | * Always `git pull --rebase` 24 | * [Clean up your branch history](https://git-scm.com/book/id/v2/Git-Tools-Rewriting-History) with 25 | `git rebase -i` 26 | * All your intermediate commits should build 27 | 28 | ## Coding Style 29 | 30 | ### C Code 31 | 32 | #### Identation 33 | 34 | * [K&R identation and braces style](https://en.wikipedia.org/wiki/Indentation_style#K&R_style) 35 | * [Mandatory braces](https://en.wikipedia.org/wiki/Indentation_style#Variant:_mandatory_braces) 36 | * 4 spaces identation 37 | 38 | Good: 39 | ``` 40 | void f(int reverse) 41 | { 42 | if (reverse) { 43 | puts("!dlroW olleH"); 44 | } else { 45 | puts("Hello world"); 46 | } 47 | } 48 | ``` 49 | 50 | Bad: 51 | ``` 52 | void f(int reverse) { 53 | if (reverse) 54 | puts ("!dlroW olleH"); 55 | else 56 | puts ("Hello world"); 57 | } 58 | ``` 59 | 60 | #### Names 61 | 62 | * Struct names are PascalCase (e.g. Context) 63 | * Scalar types are lower case (e.g. term) 64 | * All other names (e.g. functions and variables) are snake_case (e.g. term_is_integer) 65 | * Always prefix function names (e.g. term_is_nil, term_is_integer, context_new, context_destroy) 66 | 67 | #### Other Coding Conventions 68 | * Pointer * should be with the variable name rather than with the type (e.g. `char *name`, not 69 | `char* name`) 70 | * Avoid long lines, use intermediate variables with meaningful names. 71 | 72 | ### Elixir Code 73 | 74 | Just use Elixir formatter enforced style. 75 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright 2020, Fred Dushin . 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /LICENSES/CC0-1.0.txt: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | ## Copyright (c) dushin.net 3 | ## All rights reserved. 4 | ## 5 | # SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 6 | 7 | 8 | all: compile etest doc 9 | 10 | compile: 11 | rebar3 compile 12 | 13 | doc: 14 | rebar3 as doc ex_doc 15 | 16 | etest: 17 | cd test && ./run.sh 18 | 19 | clean: 20 | rm -rf _build 21 | 22 | publish: doc 23 | rebar3 as publish hex publish --doc-dir docs 24 | -------------------------------------------------------------------------------- /UPDATING.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # `atomvm_rebar3_plugin` Update Instructions 8 | 9 | ## 0.6.* -> 0.7.* 10 | 11 | - The `atomvm_rebar3_plugin` tasks have been moved into the `atomvm` namespace (from the [`rebar3`](https://rebar3.org) `default` namespace). The "legacy" tasks in the `default` namespace are deprecated, and users will be issued a warning when used. Be sure to use the `atomvm` namespace in any future usage of this plugin, as the deprecated tasks may be removed without warning. E.g., `rebar3 atomvm packbeam ...` 12 | 13 | - The default behavior of not generating line number information in BEAM files has changed. By default, line number information will be generated in BEAM files. You can remove line number information using from BEAM files by using the `-r` (or `--remove_lines`) flags to the `packbeam` task. Note that in versions 0.6 of this tool, the `--include_lines` flag was ignored due to a bug in the code. 14 | -------------------------------------------------------------------------------- /assets/init_shim.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | -module(init_shim). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | init:boot(). 26 | -------------------------------------------------------------------------------- /examples/myapp/.gitignore: -------------------------------------------------------------------------------- 1 | ## 2 | ## Copyright 2023 3 | ## 4 | ## SPDX-License-Identifier: Apache-2.0 5 | ## 6 | 7 | _build/* 8 | _checkouts/* 9 | rebar.lock 10 | rebar3.crashdump 11 | erl_crash.dump 12 | -------------------------------------------------------------------------------- /examples/myapp/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright 2023 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /examples/myapp/README.md: -------------------------------------------------------------------------------- 1 | 6 | # myapp 7 | 8 | Welcome to the myapp AtomVM application. 9 | 10 | For information about how to build and flash this application, see the [`atomvm_rebar3_plugin`](https://github.com/atomvm/atomvm_rebar3_plugin) Github repository. 11 | -------------------------------------------------------------------------------- /examples/myapp/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, [{start, myapp}, prune]} 28 | ]}. 29 | -------------------------------------------------------------------------------- /examples/myapp/src/myapp.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, myapp, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /examples/myapp/src/myapp.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(myapp). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /examples/otp_application/.gitignore: -------------------------------------------------------------------------------- 1 | ## 2 | ## Copyright 2023 3 | ## 4 | ## SPDX-License-Identifier: Apache-2.0 5 | ## 6 | 7 | _build/* 8 | _checkouts/* 9 | rebar.lock 10 | rebar3.crashdump 11 | erl_crash.dump 12 | -------------------------------------------------------------------------------- /examples/otp_application/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright 2023 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /examples/otp_application/README.md: -------------------------------------------------------------------------------- 1 | 6 | 7 | # otp_application 8 | 9 | Welcome to the `otp_application` AtomVM application. 10 | 11 | This application demonstrates how to build and deploy an AtomVM application that leverages the OTP application behavior. 12 | 13 | This application consists of the `otp_application_app` module, which implements the OTP [Application](https://www.erlang.org/doc/design_principles/applications) behavior, the `otp_application_sup` module, which implements the OTP [Supervisor](https://www.erlang.org/doc/design_principles/sup_princ), and the `otp_application_worker` module, which implements the OTP [GenServer](https://www.erlang.org/doc/design_principles/gen_server_concepts) behavior. 14 | 15 | The application and its dependencies are automatically started when the AtomVM application is run. The worker module in this example is designed to send a tick message to itself once/second. After 5 ticks, the application deliberately crashes and is restarted by the application's supervisor. 16 | 17 | Note the definition of the application in the `otp_application.app.src` file: 18 | 19 | {application, otp_application, [ 20 | {description, "An AtomVM application"}, 21 | {vsn, "0.1.0"}, 22 | {registered, []}, 23 | {mod, {otp_application_app, #{crash_interval => 5}}}, 24 | {applications, [ 25 | kernel, stdlib 26 | ]}, 27 | {env,[]}, 28 | {modules, []}, 29 | {licenses, ["Apache-2.0"]}, 30 | {links, []} 31 | ]}. 32 | 33 | Specifically, the `mod` entry tells the OTP framework which application entrypoint to load the run when AtomVM starts. 34 | 35 | Note also the `packbeam` properties of the `atomvm_rebar3_plguin` entry in the `rebar3.config` file: 36 | 37 | {atomvm_rebar3_plugin, [ 38 | {packbeam, [application, prune]} 39 | ]}. 40 | 41 | This property tell the `atomvm_rebar3_plugin` to treat this project as an OTP application. In this case, the project is expected to implement the OTP application behavior. In addition, users need not (and should not) specify a start entrypoint for the application; starting the OTP application and its dependencies is performed automatically by the OTP framework. 42 | 43 | ## Building and running this application 44 | 45 | To build the application, issue the `packbeam` task under the `atomvm` namespace to the [`rebar3`](https://rebar3.org) tool: 46 | 47 | shell$ rebar3 atomvm packbeam 48 | 49 | If you have AtomVM installed on a generic UNIX host, you can run this application on the command line, supplying the generated AtomVM AVM file as an argument: 50 | 51 | shell$ atomvm _build/default/lib/otp_application.avm 52 | Starting otp_application_app with start type normal and start args #{crash_interval => 5} ... 53 | Starting otp_application_sup with args #{crash_interval => 5} ... 54 | Application otp_application started 55 | tick 56 | tick 57 | tick 58 | tick 59 | tick 60 | boom! 61 | CRASH 62 | ====== 63 | pid: <0.5.0> 64 | 65 | Stacktrace: 66 | [{otp_application_worker,handle_info,2,[{file,"/home/joe/atomvm_rebar3_plugin/examples/otp_application/src/otp_application_worker.erl"},{line,56}]},{gen_server,loop,2,[{file,"/home/runner/AtomVM/libs/estdlib/bootstrap/gen_server.erl"},{line,468}]}] 67 | 68 | For more information about how to build and flash this application on other platforms, see the [`atomvm_rebar3_plugin`](https://github.com/atomvm/atomvm_rebar3_plugin) Github repository. 69 | -------------------------------------------------------------------------------- /examples/otp_application/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, [application, prune]} 28 | ]}. 29 | -------------------------------------------------------------------------------- /examples/otp_application/src/otp_application.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {application, otp_application, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {mod, {otp_application_app, #{crash_interval => 5}}}, 26 | {applications, [ 27 | kernel, stdlib 28 | ]}, 29 | {env,[]}, 30 | {modules, []}, 31 | {licenses, ["Apache-2.0"]}, 32 | {links, []} 33 | ]}. 34 | -------------------------------------------------------------------------------- /examples/otp_application/src/otp_application_app.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | -module(otp_application_app). 21 | 22 | -export([start/2, stop/1]). 23 | 24 | start(StartType, StartArgs) -> 25 | io:format("Starting otp_application_app with start type ~p and start args ~p ...~n", [ 26 | StartType, StartArgs 27 | ]), 28 | otp_application_sup:start(StartArgs). 29 | 30 | stop(_State) -> 31 | ok. 32 | -------------------------------------------------------------------------------- /examples/otp_application/src/otp_application_sup.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | -module(otp_application_sup). 21 | 22 | -export([start/1, init/1]). 23 | 24 | start(Args) -> 25 | io:format("Starting otp_application_sup with args ~p ...~n", [Args]), 26 | supervisor:start_link({local, ?MODULE}, ?MODULE, Args). 27 | 28 | %% 29 | %% supervisor implementation 30 | %% 31 | 32 | init(Args) -> 33 | {ok, 34 | { 35 | {one_for_one, 1, 1}, [ 36 | { 37 | otp_application_worker, 38 | {otp_application_worker, start_link, [Args]}, 39 | permanent, 40 | brutal_kill, 41 | worker, 42 | [] 43 | } 44 | ] 45 | }}. 46 | -------------------------------------------------------------------------------- /examples/otp_application/src/otp_application_worker.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | -module(otp_application_worker). 21 | 22 | -export([start_link/1]). 23 | 24 | -behavior(gen_server). 25 | -export([init/1, handle_cast/2, handle_call/3, handle_info/2, terminate/2]). 26 | 27 | %% 28 | %% api 29 | %% 30 | 31 | start_link(Args) -> 32 | gen_server:start_link(?MODULE, Args, []). 33 | 34 | %% 35 | %% gen_server implementation 36 | %% 37 | 38 | -record(state, { 39 | crash_interval, 40 | counter = 0 41 | }). 42 | 43 | %% @hidden 44 | init(Args) -> 45 | send_tick(), 46 | {ok, #state{crash_interval = maps:get(crash_interval, Args, 5)}}. 47 | 48 | %% @hidden 49 | handle_cast(_Request, State) -> 50 | {noreply, State}. 51 | 52 | %% @hidden 53 | handle_call(_Request, _From, State) -> 54 | {reply, {error, unimplemented}, State}. 55 | 56 | %% @hidden 57 | handle_info(tick, #state{counter = X, crash_interval = X} = State) -> 58 | io:format("boom!~n"), 59 | exit(boom), 60 | {noreply, State}; 61 | handle_info(tick, State) -> 62 | io:format("tick~n"), 63 | send_tick(), 64 | {noreply, State#state{counter = State#state.counter + 1}}; 65 | handle_info(_Msg, State) -> 66 | {noreply, State}. 67 | 68 | %% @hidden 69 | terminate(_Reason, _State) -> 70 | ok. 71 | 72 | %% 73 | %% internal implementation 74 | %% 75 | 76 | %% @private 77 | send_tick() -> 78 | erlang:send_after(1000, self(), tick). 79 | -------------------------------------------------------------------------------- /priv/.gitignore: -------------------------------------------------------------------------------- 1 | ## 2 | ## Copyright {{copyright_year}} <{{author_email}}> 3 | ## 4 | ## SPDX-License-Identifier: Apache-2.0 5 | ## 6 | 7 | _build/* 8 | _checkouts/* 9 | rebar.lock 10 | rebar3.crashdump 11 | erl_crash.dump 12 | -------------------------------------------------------------------------------- /priv/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | Copyright {{copyright_year}} <{{author_email}}> 179 | 180 | Licensed under the Apache License, Version 2.0 (the "License"); 181 | you may not use this file except in compliance with the License. 182 | You may obtain a copy of the License at 183 | 184 | http://www.apache.org/licenses/LICENSE-2.0 185 | 186 | Unless required by applicable law or agreed to in writing, software 187 | distributed under the License is distributed on an "AS IS" BASIS, 188 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 189 | See the License for the specific language governing permissions and 190 | limitations under the License. 191 | -------------------------------------------------------------------------------- /priv/README.md: -------------------------------------------------------------------------------- 1 | 6 | # {{name}} 7 | 8 | Welcome to the {{name}} AtomVM application. 9 | 10 | For information about how to build and flash this application, see the [`atomvm_rebar3_plugin`](https://github.com/atomvm/atomvm_rebar3_plugin) Github repository. 11 | -------------------------------------------------------------------------------- /priv/atomvm_app.template: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) {{copyright_year}} <{{author_email}}> 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {description, "A minimal AtomVM application"}. 22 | 23 | {variables, [ 24 | {name, "atomvm_app", "Name of the AtomVM application"} 25 | ]}. 26 | 27 | {template, ".gitignore", "{{name}}/.gitignore"}. 28 | {template, "LICENSE", "{{name}}/LICENSE"}. 29 | {template, "rebar.config", "{{name}}/rebar.config"}. 30 | {template, "README.md", "{{name}}/README.md"}. 31 | 32 | {dir, "{{name}}/src"}. 33 | {template, "src/atomvm_app.erl", "{{name}}/src/{{name}}.erl"}. 34 | {template, "src/atomvm_app.app.src", "{{name}}/src/{{name}}.app.src"}. 35 | -------------------------------------------------------------------------------- /priv/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) {{copyright_year}} <{{author_email}}> 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, [{start, {{name}}}, prune]} 28 | ]}. 29 | -------------------------------------------------------------------------------- /priv/src/atomvm_app.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) {{copyright_year}} <{{author_email}}> 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {application, {{name}}, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /priv/src/atomvm_app.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) {{copyright_year}} <{{author_email}}> 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | -module({{name}}). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2020-2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | {erl_opts, [debug_info]}. 21 | 22 | {deps, [ 23 | {atomvm_packbeam, "0.7.4"}, 24 | {uf2tool, "1.1.0"} 25 | ]}. 26 | 27 | {ex_doc, [ 28 | {source_url, <<"https://github.com/atomvm/atomvm_rebar3_plugin">>}, 29 | {extras, [ 30 | <<"README.md">>, 31 | <<"CHANGELOG.md">>, 32 | <<"UPDATING.md">>, 33 | <<"LICENSE">>, 34 | <<"CONTRIBUTING.md">>, 35 | <<"CODE_OF_CONDUCT.md">> 36 | ]}, 37 | {main, <<"README.md">>}, 38 | {output, "docs"}, 39 | {api_reference, false}, 40 | {skip_undefined_reference_warnings_on, ["README.md"]} 41 | ]}. 42 | 43 | {profiles, [ 44 | {doc, [ 45 | {plugins, [rebar3_ex_doc]} 46 | ]}, 47 | {publish, [ 48 | {plugins, [rebar3_hex, rebar3_ex_doc]}, 49 | {hex, [ 50 | {doc, #{provider => ex_doc}} 51 | ]} 52 | ]} 53 | ]}. 54 | -------------------------------------------------------------------------------- /src/atomvm_bootstrap_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(atomvm_bootstrap_provider). 21 | 22 | -behaviour(provider). 23 | 24 | -export([init/1, do/1, format_error/1]). 25 | 26 | -define(PROVIDER, bootstrap). 27 | -define(DEPS, [{default, compile}]). 28 | -define(OPTS, [ 29 | {bootstrap_dir, $b, "bootstrap_dir", boolean, "Bootstrap directory"}, 30 | {force, $f, "force", boolean, "Force rebuild"} 31 | ]). 32 | 33 | -define(DEFAULT_OPTS, #{ 34 | bootstrap_dir => undefined, 35 | force => false 36 | }). 37 | 38 | -include_lib("kernel/include/file.hrl"). 39 | 40 | %% 41 | %% provider implementation 42 | %% 43 | 44 | %% @hidden 45 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 46 | init(State) -> 47 | Provider = providers:create([ 48 | % The atomvm namespace 49 | {namespace, atomvm}, 50 | % The 'user friendly' name of the task 51 | {name, ?PROVIDER}, 52 | % The module implementation of the task 53 | {module, ?MODULE}, 54 | % The task can be run by the user, always true 55 | {bare, true}, 56 | % The list of dependencies 57 | {deps, ?DEPS}, 58 | % How to use the plugin 59 | {example, "rebar3 atomvm bootstrap"}, 60 | % list of options understood by the plugin 61 | {opts, ?OPTS}, 62 | {short_desc, "Compiles bootstrap .erl files"}, 63 | {desc, 64 | "~n" 65 | "This plugin is used internally by the atomvm packbeam task to compile~n" 66 | "modules that cannot be compiled directly by rebar.~n" 67 | "~n" 68 | "Users typically have no reason to use this task directly.~n"} 69 | ]), 70 | {ok, rebar_state:add_provider(State, Provider)}. 71 | 72 | %% @hidden 73 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 74 | do(State) -> 75 | try 76 | Opts = get_opts(State), 77 | rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Opts]), 78 | ok = do_bootstrap( 79 | rebar_state:project_apps(State), 80 | maps:get(bootstrap_dir, Opts), 81 | maps:get(force, Opts) 82 | ), 83 | {ok, State} 84 | catch 85 | C:E:S -> 86 | rebar_api:error( 87 | "An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [ 88 | ?PROVIDER, C, E, S 89 | ] 90 | ), 91 | {error, E} 92 | end. 93 | 94 | %% @hidden 95 | -spec format_error(any()) -> iolist(). 96 | format_error(Reason) -> 97 | io_lib:format("~p", [Reason]). 98 | 99 | %% 100 | %% internal functions 101 | %% 102 | 103 | %% @private 104 | get_opts(State) -> 105 | {ParsedArgs, _} = rebar_state:command_parsed_args(State), 106 | RebarOpts = atomvm_rebar3_plugin:get_atomvm_rebar_provider_config(State, ?PROVIDER), 107 | ParsedOpts = atomvm_rebar3_plugin:proplist_to_map(ParsedArgs), 108 | maps:merge( 109 | ?DEFAULT_OPTS, 110 | maps:merge(RebarOpts, ParsedOpts) 111 | ). 112 | 113 | %% @private 114 | do_bootstrap(ProjectApps, BootstrapDir, Force) -> 115 | lists:foreach( 116 | fun(ProjectApp) -> 117 | do_bootstrap_app(ProjectApp, BootstrapDir, Force) 118 | end, 119 | ProjectApps 120 | ). 121 | 122 | %% @private 123 | do_bootstrap_app(App, undefined, Force) -> 124 | Dir = rebar_app_info:dir(App), 125 | do_bootstrap_app(App, filename:join(Dir, "bootstrap"), Force); 126 | do_bootstrap_app(App, BootstrapDir, Force) -> 127 | % Dir = rebar_app_info:dir(App), 128 | case filelib:is_dir(BootstrapDir) of 129 | true -> 130 | BootstrapFiles = [ 131 | filename:join(BootstrapDir, Mod) 132 | || Mod <- filelib:wildcard("*.erl", BootstrapDir) 133 | ], 134 | lists:foreach( 135 | fun(BootstrapFile) -> 136 | do_bootstrap_file(App, BootstrapFile, Force) 137 | end, 138 | BootstrapFiles 139 | ); 140 | _ -> 141 | rebar_api:debug("No bootstrap dir ~s. Skipping...", [BootstrapDir]), 142 | ok 143 | end. 144 | 145 | %% @private 146 | do_bootstrap_file(App, BootstrapFile, Force) -> 147 | OutDir = rebar_app_info:out_dir(App), 148 | EBinDir = filename:join(OutDir, "bootstrap_ebin"), 149 | ok = ensure_path(EBinDir), 150 | maybe_compile(App, BootstrapFile, EBinDir, Force). 151 | 152 | %% @private 153 | ensure_path(Dir) -> 154 | case filelib:is_dir(Dir) of 155 | true -> 156 | ok; 157 | _ -> 158 | ok = filelib:ensure_dir(Dir), 159 | ok = file:make_dir(Dir) 160 | end. 161 | 162 | %% @private 163 | maybe_compile(App, BootstrapFile, EBinDir, Force) -> 164 | Basename = filename:basename(BootstrapFile, ".erl"), 165 | BeamFile = filename:join(EBinDir, Basename ++ ".beam"), 166 | case Force orelse needs_build(BootstrapFile, BeamFile) of 167 | true -> 168 | CompilerOptions = 169 | [{outdir, EBinDir}, report] ++ 170 | get_compiler_options(App), 171 | rebar_api:debug("Compiling bootstrap file ~s with options ~p ...", [ 172 | BootstrapFile, CompilerOptions 173 | ]), 174 | case 175 | compile:file( 176 | BootstrapFile, CompilerOptions 177 | ) 178 | of 179 | {ok, ModuleName} -> 180 | rebar_api:debug("Compiled bootstrap module ~p", [ModuleName]), 181 | ok; 182 | Error -> 183 | rebar_api:error("Failed to compile bootstrap file ~s: ~p", [ 184 | BootstrapFile, Error 185 | ]), 186 | Error 187 | end; 188 | _ -> 189 | rebar_api:debug("bootstrap file ~s not in need of rebuild", [BootstrapFile]), 190 | ok 191 | end. 192 | 193 | %% @private 194 | get_compiler_options(App) -> 195 | Opts = rebar_app_info:opts(App), 196 | case dict:find(erl_opts, Opts) of 197 | {ok, ErlOpts} -> 198 | ErlOpts; 199 | _ -> 200 | [] 201 | end. 202 | 203 | %% @private 204 | needs_build(Path, BeamFile) -> 205 | not filelib:is_file(BeamFile) orelse 206 | modified_time(Path) > modified_time(BeamFile). 207 | 208 | %% @private 209 | modified_time(Path) -> 210 | {ok, #file_info{mtime = MTime}} = file:read_file_info(Path, [{time, posix}]), 211 | MTime. 212 | -------------------------------------------------------------------------------- /src/atomvm_esp32_flash_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2020-2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(atomvm_esp32_flash_provider). 21 | 22 | -behaviour(provider). 23 | 24 | -export([init/1, do/1, format_error/1]). 25 | 26 | -include_lib("kernel/include/file.hrl"). 27 | 28 | -define(PROVIDER, esp32_flash). 29 | -define(DEPS, [packbeam]). 30 | -define(OPTS, [ 31 | {esptool, $e, "esptool", string, "Path to esptool.py"}, 32 | {chip, $c, "chip", string, "ESP chip (default auto)"}, 33 | {port, $p, "port", string, "Device port (default /dev/ttyUSB0)"}, 34 | {baud, $b, "baud", integer, "Baud rate (default 115200)"}, 35 | {offset, $o, "offset", string, "Offset (default 0x210000)"} 36 | ]). 37 | 38 | -define(DEFAULT_OPTS, #{ 39 | esptool => "esptool.py", 40 | chip => "auto", 41 | port => "/dev/ttyUSB0", 42 | baud => 115200, 43 | offset => "0x210000" 44 | }). 45 | 46 | %% 47 | %% provider implementation 48 | %% 49 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 50 | init(State) -> 51 | Provider = providers:create([ 52 | % The atomvm namespace 53 | {namespace, atomvm}, 54 | % The 'user friendly' name of the task 55 | {name, ?PROVIDER}, 56 | % The module implementation of the task 57 | {module, ?MODULE}, 58 | % The task can be run by the user, always true 59 | {bare, true}, 60 | % The list of dependencies 61 | {deps, ?DEPS}, 62 | % How to use the plugin 63 | {example, "rebar3 atomvm esp32_flash"}, 64 | % list of options understood by the plugin 65 | {opts, ?OPTS}, 66 | {short_desc, "Flash an AtomVM packbeam to an ESP32 device"}, 67 | {desc, 68 | "~n" 69 | "Use this plugin to flash an AtomVM packbeam file to an ESP32 device.~n"} 70 | ]), 71 | {ok, rebar_state:add_provider(State, Provider)}. 72 | 73 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 74 | do(State) -> 75 | try 76 | Opts = get_opts(State), 77 | rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Opts]), 78 | ok = do_flash( 79 | rebar_state:project_apps(State), 80 | maps:get(esptool, Opts), 81 | maps:get(chip, Opts), 82 | maps:get(port, Opts), 83 | maps:get(baud, Opts), 84 | maps:get(offset, Opts) 85 | ), 86 | {ok, State} 87 | catch 88 | C:E:S -> 89 | rebar_api:error( 90 | "An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [ 91 | ?PROVIDER, C, E, S 92 | ] 93 | ), 94 | {error, E} 95 | end. 96 | 97 | -spec format_error(any()) -> iolist(). 98 | format_error(Reason) -> 99 | io_lib:format("~p", [Reason]). 100 | 101 | %% 102 | %% internal functions 103 | %% 104 | 105 | %% @private 106 | get_opts(State) -> 107 | {ParsedArgs, _} = rebar_state:command_parsed_args(State), 108 | RebarOpts = atomvm_rebar3_plugin:get_atomvm_rebar_provider_config(State, ?PROVIDER), 109 | ParsedOpts = atomvm_rebar3_plugin:proplist_to_map(ParsedArgs), 110 | maps:merge( 111 | env_opts(), 112 | maps:merge(RebarOpts, ParsedOpts) 113 | ). 114 | 115 | %% @private 116 | env_opts() -> 117 | #{ 118 | esptool => os:getenv( 119 | "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_ESPTOOL", 120 | maps:get(esptool, ?DEFAULT_OPTS) 121 | ), 122 | chip => os:getenv( 123 | "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_CHIP", 124 | maps:get(chip, ?DEFAULT_OPTS) 125 | ), 126 | port => os:getenv( 127 | "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_PORT", 128 | maps:get(port, ?DEFAULT_OPTS) 129 | ), 130 | baud => maybe_convert_string( 131 | os:getenv( 132 | "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_BAUD", 133 | maps:get(baud, ?DEFAULT_OPTS) 134 | ) 135 | ), 136 | offset => os:getenv( 137 | "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_OFFSET", 138 | maps:get(offset, ?DEFAULT_OPTS) 139 | ) 140 | }. 141 | 142 | %% @private 143 | maybe_convert_string(S) when is_list(S) -> 144 | list_to_integer(S); 145 | maybe_convert_string(I) -> 146 | I. 147 | 148 | %% @private 149 | do_flash(ProjectApps, EspTool, Chip, Port, Baud, Offset) -> 150 | [ProjectAppAVM | _] = [get_avm_file(ProjectApp) || ProjectApp <- ProjectApps], 151 | Portparam = 152 | case Port of 153 | "auto" -> ""; 154 | _ -> ["--port ", Port] 155 | end, 156 | Cmd = lists:join(" ", [ 157 | EspTool, 158 | "--chip", 159 | Chip, 160 | Portparam, 161 | "--baud", 162 | integer_to_list(Baud), 163 | "--before", 164 | "default_reset", 165 | "--after", 166 | "hard_reset", 167 | "write_flash", 168 | "-u", 169 | "--flash_mode", 170 | "keep", 171 | "--flash_freq", 172 | "keep", 173 | "--flash_size", 174 | "detect", 175 | Offset, 176 | ProjectAppAVM 177 | ]), 178 | rebar_api:info("~s~n", [Cmd]), 179 | rebar_api:console("~s", [os:cmd(Cmd)]), 180 | ok. 181 | 182 | %% @private 183 | get_avm_file(App) -> 184 | OutDir = rebar_app_info:out_dir(App), 185 | Name = binary_to_list(rebar_app_info:name(App)), 186 | DirName = filename:dirname(OutDir), 187 | filename:join(DirName, Name ++ ".avm"). 188 | -------------------------------------------------------------------------------- /src/atomvm_packbeam_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2020-2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(atomvm_packbeam_provider). 21 | 22 | -behaviour(provider). 23 | 24 | -export([init/1, do/1, format_error/1]). 25 | 26 | -include_lib("kernel/include/file.hrl"). 27 | 28 | -define(PROVIDER, packbeam). 29 | -define(DEPS, [bootstrap]). 30 | -define(OPTS, [ 31 | {external, $e, "external", string, "External AVM modules"}, 32 | {force, $f, "force", boolean, "Force rebuild"}, 33 | {prune, $p, "prune", boolean, "Prune unreferenced BEAM files"}, 34 | {start, $s, "start", atom, "Start module"}, 35 | {application, $a, "application", boolean, "Build a OTP application"}, 36 | {remove_lines, $r, "remove_lines", boolean, 37 | "Remove line information from generated AVM files (off by default)"}, 38 | {list, $l, "list", boolean, "List the contents of AVM files after creation"} 39 | ]). 40 | 41 | -define(DEFAULT_OPTS, #{ 42 | external => [], 43 | force => false, 44 | prune => false, 45 | start => undefined, 46 | application => false, 47 | remove_lines => false, 48 | list => false 49 | }). 50 | 51 | %% abstract representation of a simple shim that 52 | %% delegates to `init:start/0`. This form will 53 | %% be compiled and inserted into the AVM if the 54 | %% user has indicated that the project is an (OTP) 55 | %% application. 56 | %% 57 | %% This form was generated from the init_shim.erl 58 | %% asset, as follows: 59 | %% 60 | %% epp:parse_file("assets/init_shim.erl", []). 61 | %% 62 | -define(INIT_SHIM_FORMS, [ 63 | {attribute, 1, file, {"assets/init_shim.erl", 1}}, 64 | {attribute, 1, module, init_shim}, 65 | {attribute, 3, export, [{start, 0}]}, 66 | {function, 5, start, 0, [ 67 | {clause, 5, [], [], [{call, 6, {remote, 6, {atom, 6, init}, {atom, 6, boot}}, []}]} 68 | ]}, 69 | {eof, 7} 70 | ]). 71 | 72 | -record(file_set, { 73 | name, out_dir, beam_files, priv_files, app_file 74 | }). 75 | 76 | %% 77 | %% provider implementation 78 | %% 79 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 80 | init(State) -> 81 | Provider = providers:create([ 82 | % The atomvm namespace 83 | {namespace, atomvm}, 84 | % The 'user friendly' name of the task 85 | {name, ?PROVIDER}, 86 | % The module implementation of the task 87 | {module, ?MODULE}, 88 | % The task can be run by the user, always true 89 | {bare, true}, 90 | % The list of dependencies 91 | {deps, ?DEPS}, 92 | % How to use the plugin 93 | {example, "rebar3 atomvm packbeam"}, 94 | % list of options understood by the plugin 95 | {opts, ?OPTS}, 96 | {short_desc, "Create an AtomVM packbeam file"}, 97 | {desc, 98 | "~n" 99 | "Use this plugin to create an AtomVM packbeam file from your rebar3 project.~n"} 100 | ]), 101 | {ok, rebar_state:add_provider(State, Provider)}. 102 | 103 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 104 | do(State) -> 105 | try 106 | Opts = get_opts(State), 107 | rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Opts]), 108 | ok = do_packbeam( 109 | rebar_state:project_apps(State), 110 | lists:usort(rebar_state:all_deps(State)), 111 | maps:get(external, Opts), 112 | maps:get(prune, Opts), 113 | maps:get(force, Opts), 114 | get_start_module(Opts), 115 | maps:get(application, Opts), 116 | not maps:get(remove_lines, Opts), 117 | maps:get(list, Opts) 118 | ), 119 | {ok, State} 120 | catch 121 | C:E:S -> 122 | rebar_api:error( 123 | "An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [ 124 | ?PROVIDER, C, E, S 125 | ] 126 | ), 127 | {error, E} 128 | end. 129 | 130 | get_start_module(Opts) -> 131 | case maps:get(start, Opts, undefined) of 132 | undefined -> undefined; 133 | StartModule -> StartModule 134 | end. 135 | 136 | -spec format_error(any()) -> iolist(). 137 | format_error(Reason) -> 138 | io_lib:format("~p", [Reason]). 139 | 140 | %% 141 | %% internal functions 142 | %% 143 | 144 | %% @private 145 | get_opts(State) -> 146 | {ParsedArgs, _} = rebar_state:command_parsed_args(State), 147 | RebarOpts = atomvm_rebar3_plugin:get_atomvm_rebar_provider_config(State, ?PROVIDER), 148 | SquashedOpts = atomvm_rebar3_plugin:proplist_to_map(squash_external_avms(ParsedArgs)), 149 | maps:merge(?DEFAULT_OPTS, maps:merge(RebarOpts, SquashedOpts)). 150 | 151 | %% @private 152 | squash_external_avm({external, AVMPath}, Accum) -> 153 | StrippedPath = filename:absname(string:strip(AVMPath, both)), 154 | case filelib:is_file(StrippedPath) of 155 | true -> 156 | case proplists:get_value(external, Accum) of 157 | undefined -> 158 | [{external, [StrippedPath]} | Accum]; 159 | OtherAVMs -> 160 | [ 161 | {external, [StrippedPath | OtherAVMs]} 162 | | proplists:delete(external, Accum) 163 | ] 164 | end; 165 | _ -> 166 | throw({enoent, StrippedPath}) 167 | end; 168 | squash_external_avm(Any, Accum) -> 169 | [Any | Accum]. 170 | 171 | %% @private 172 | squash_external_avms(ParsedArgs) -> 173 | lists:foldl( 174 | fun squash_external_avm/2, 175 | [], 176 | ParsedArgs 177 | ). 178 | 179 | %% @private 180 | do_packbeam( 181 | ProjectApps, Deps, ExternalAVMs, Prune, Force, StartModule, IsApplication, IncludeLines, List 182 | ) -> 183 | DepFileSets = [get_files(Dep) || Dep <- Deps], 184 | ProjectAppFileSets = [get_files(ProjectApp) || ProjectApp <- ProjectApps], 185 | DepsAvms = [ 186 | maybe_create_packbeam(DepFileSet, [], false, Force, undefined, false, IncludeLines, false) 187 | || DepFileSet <- DepFileSets 188 | ], 189 | [ 190 | maybe_create_packbeam( 191 | ProjectAppFileSet, 192 | DepsAvms ++ ExternalAVMs, 193 | Prune, 194 | Force, 195 | StartModule, 196 | IsApplication, 197 | IncludeLines, 198 | List 199 | ) 200 | || ProjectAppFileSet <- ProjectAppFileSets 201 | ], 202 | ok. 203 | 204 | %% @private 205 | get_files(App) -> 206 | OutDir = rebar_app_info:out_dir(App), 207 | EBinDir = rebar_app_info:ebin_dir(App), 208 | TestDir = filename:join([rebar_app_info:dir(App), "test"]), 209 | BootstrapEBinDir = filename:join(OutDir, "bootstrap_ebin"), 210 | BeamFiles = 211 | get_beam_files(EBinDir) ++ get_beam_files(BootstrapEBinDir) ++ get_beam_files(TestDir), 212 | AppFile = get_app_file(EBinDir), 213 | PrivFiles = get_all_files(filename:join(OutDir, "priv")), 214 | Name = binary_to_list(rebar_app_info:name(App)), 215 | % rebar_api:info("BEAM files for App ~p from OutDir ~p: ~p", [rebar_app_info:name(App), OutDir, BeamFiles]), 216 | #file_set{ 217 | name = Name, 218 | out_dir = OutDir, 219 | beam_files = BeamFiles, 220 | app_file = AppFile, 221 | priv_files = PrivFiles 222 | }. 223 | 224 | %% @private 225 | get_beam_files(Dir) -> 226 | case filelib:is_dir(Dir) of 227 | true -> 228 | [filename:join(Dir, Mod) || Mod <- filelib:wildcard("*.beam", Dir)]; 229 | _ -> 230 | [] 231 | end. 232 | 233 | %% @private 234 | get_app_file(Dir) -> 235 | AppFiles = [filename:join(Dir, Mod) || Mod <- filelib:wildcard("*.app", Dir)], 236 | case AppFiles of 237 | [] -> 238 | rebar_api:warn("No .app files in ~s", [Dir]), 239 | undefined; 240 | [AppFile] -> 241 | AppFile; 242 | [AppFile | _] -> 243 | rebar_api:warn("Multiple .app files in ~s (using first): ~p", [Dir, AppFiles]), 244 | AppFile 245 | end. 246 | 247 | %% @private 248 | get_all_files(Dir) -> 249 | AllFiles = [filename:join(Dir, Mod) || Mod <- filelib:wildcard("*", Dir)], 250 | RegularFiles = lists:filter( 251 | fun(Path) -> 252 | filelib:is_regular(Path) 253 | end, 254 | AllFiles 255 | ), 256 | SubDirs = lists:filter( 257 | fun(Path) -> 258 | filelib:is_dir(Path) 259 | end, 260 | AllFiles 261 | ), 262 | SubFiles = lists:foldl( 263 | fun(SubDir, Accum) -> 264 | get_all_files(SubDir) ++ Accum 265 | end, 266 | [], 267 | SubDirs 268 | ), 269 | RegularFiles ++ SubFiles. 270 | 271 | %% @private 272 | maybe_create_packbeam( 273 | FileSet, AvmFiles, Prune, Force, StartModule, IsApplication, IncludeLines, List 274 | ) -> 275 | #file_set{ 276 | name = Name, 277 | out_dir = OutDir, 278 | beam_files = BeamFiles, 279 | app_file = AppFile, 280 | priv_files = PrivFiles 281 | } = FileSet, 282 | DirName = filename:dirname(OutDir), 283 | TargetAVM = filename:join(DirName, Name ++ ".avm"), 284 | AppFiles = 285 | case AppFile of 286 | undefined -> []; 287 | _ -> [AppFile] 288 | end, 289 | case Force orelse needs_build(TargetAVM, BeamFiles ++ PrivFiles ++ AvmFiles ++ AppFiles) of 290 | true -> 291 | create_packbeam( 292 | FileSet, AvmFiles, Prune, StartModule, IsApplication, IncludeLines, List 293 | ); 294 | _ -> 295 | rebar_api:debug("No packbeam build needed.", []), 296 | TargetAVM 297 | end. 298 | 299 | %% @private 300 | needs_build(Path, PathList) -> 301 | not filelib:is_file(Path) orelse 302 | modified_time(Path) < latest_modified_time(PathList). 303 | 304 | %% @private 305 | modified_time(Path) -> 306 | {ok, #file_info{mtime = MTime}} = file:read_file_info(Path, [{time, posix}]), 307 | MTime. 308 | 309 | %% @private 310 | latest_modified_time(PathList) -> 311 | lists:max([modified_time(Path) || Path <- PathList]). 312 | 313 | %% @private 314 | create_packbeam(FileSet, AvmFiles, Prune, StartModule, IsApplication, IncludeLines, List) -> 315 | #file_set{ 316 | name = Name, 317 | out_dir = OutDir, 318 | beam_files = BeamFiles, 319 | app_file = AppFile, 320 | priv_files = PrivFiles 321 | } = FileSet, 322 | N = length(OutDir) + 1, 323 | PrivFilesRelative = [filename:join(Name, string:slice(PrivFile, N)) || PrivFile <- PrivFiles], 324 | {ApplicationModule, AppFileBinFiles} = create_app_file_bin_files(Name, OutDir, AppFile), 325 | BootFiles = 326 | case IsApplication of 327 | true -> 328 | [create_boot_file(OutDir, ApplicationModule), create_init_shim(OutDir)]; 329 | _ -> 330 | case StartModule of 331 | init -> 332 | rebar_api:warn( 333 | "Specifying `init` as the start module to generate an OTP application is deprecated. " 334 | "Use the `--application` (or `-a`) option, instead.", 335 | [] 336 | ), 337 | [create_boot_file(OutDir, ApplicationModule)]; 338 | _ -> 339 | [] 340 | end 341 | end, 342 | Cwd = rebar_dir:get_cwd(), 343 | try 344 | DirName = filename:dirname(OutDir), 345 | ok = file:set_cwd(DirName), 346 | AvmFilename = Name ++ ".avm", 347 | FileList = 348 | reorder_beamfiles(BeamFiles) ++ AppFileBinFiles ++ BootFiles ++ PrivFilesRelative ++ 349 | AvmFiles, 350 | Opts = #{ 351 | prune => Prune, 352 | start_module => effective_start_module(StartModule, IsApplication), 353 | application_module => ApplicationModule, 354 | include_lines => IncludeLines 355 | }, 356 | rebar_api:debug( 357 | "Creating AVM file ~p from FileList ~p. Opts: ~p", 358 | [AvmFilename, FileSet, Opts] 359 | ), 360 | packbeam_api:create( 361 | AvmFilename, FileList, Opts 362 | ), 363 | rebar_api:info("AVM file written to ~s/~s", [DirName, AvmFilename]), 364 | maybe_list(DirName ++ "/" ++ AvmFilename, List), 365 | filename:join(DirName, AvmFilename) 366 | after 367 | ok = file:set_cwd(Cwd) 368 | end. 369 | 370 | %% @private 371 | effective_start_module(_StartModule, true) -> 372 | init_shim; 373 | effective_start_module(StartModule, _) -> 374 | StartModule. 375 | 376 | %% @private 377 | maybe_list(_, false) -> 378 | ok; 379 | maybe_list(AvmPath, _) -> 380 | AVMElements = packbeam_api:list(AvmPath), 381 | rebar_api:console("AVM contents~n============", []), 382 | lists:foreach( 383 | fun list_element/1, 384 | AVMElements 385 | ). 386 | 387 | %% @private 388 | list_element(AVMElement) -> 389 | ElementName = packbeam_api:get_element_name(AVMElement), 390 | ElementData = packbeam_api:get_element_data(AVMElement), 391 | rebar_api:console( 392 | "~s~s [~p]", [ 393 | ElementName, 394 | case packbeam_api:is_entrypoint(AVMElement) of 395 | true -> " *"; 396 | _ -> "" 397 | end, 398 | byte_size(ElementData) 399 | ] 400 | ). 401 | 402 | %% @private 403 | create_app_file_bin_files(_AppName, _OutDir, undefined) -> 404 | {undefined, []}; 405 | create_app_file_bin_files(AppName, OutDir, AppFile) -> 406 | case file:consult(AppFile) of 407 | {ok, Term} -> 408 | case Term of 409 | [{application, ApplicationModule, _Properties} = ApplicationSpec] -> 410 | WritePath = filename:join([OutDir, "application.bin"]), 411 | Bin = erlang:term_to_binary(ApplicationSpec), 412 | ok = file:write_file(WritePath, Bin), 413 | {ApplicationModule, [ 414 | {WritePath, filename:join([AppName, "priv", "application.bin"])} 415 | ]}; 416 | _ -> 417 | rebar_api:warn("Consulted app file (~s) does not appear to be an app spec.", [ 418 | AppFile 419 | ]), 420 | {undefined, []} 421 | end; 422 | Error -> 423 | rebar_api:warn("Failed to consult app file : ~s Error: ~p", [AppFile, Error]), 424 | {undefined, []} 425 | end. 426 | 427 | %% @private 428 | create_boot_file(OutDir, ApplicationModule) -> 429 | %% TODO 430 | Version = {0, 1, 0}, 431 | BootSpec = {boot, Version, #{applications => [ApplicationModule]}}, 432 | WritePath = filename:join([OutDir, "start.boot"]), 433 | Bin = erlang:term_to_binary(BootSpec), 434 | ok = file:write_file(WritePath, Bin), 435 | StartBootPath = filename:join(["init", "priv", "start.boot"]), 436 | rebar_api:debug("Created boot file ~s in ~s", [StartBootPath, WritePath]), 437 | {WritePath, StartBootPath}. 438 | 439 | %% @private 440 | create_init_shim(OutDir) -> 441 | EBinDir = filename:join([OutDir, "ebin"]), 442 | {ok, init_shim, Data} = compile:forms(?INIT_SHIM_FORMS, []), 443 | WritePath = filename:join([EBinDir, "init_shim.beam"]), 444 | ok = file:write_file(WritePath, Data), 445 | rebar_api:debug("Created init_shim.beam in ~s", [WritePath]), 446 | {WritePath, "init_shim.beam"}. 447 | 448 | %% @private 449 | reorder_beamfiles(BeamFiles) -> 450 | ExportPaths = [{exports(Path), Path} || Path <- BeamFiles], 451 | SortedExportPaths = lists:sort(fun compare_beams/2, ExportPaths), 452 | [Path || {_Exports, Path} <- SortedExportPaths]. 453 | 454 | %% @private 455 | exports(Path) -> 456 | {ok, {_Module, ExportChunk}} = beam_lib:chunks(Path, [exports]), 457 | proplists:get_value(exports, ExportChunk). 458 | 459 | %% @private 460 | compare_beams({Exports1, _}, _) -> 461 | lists:member({start, 0}, Exports1). 462 | -------------------------------------------------------------------------------- /src/atomvm_pico_flash_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023-2024 Uncle Grumpy 3 | %% All rights reserved. 4 | %% 5 | %% Based on esp32_flash_provider.erl 6 | %% Copyright (c) dushin.net 7 | %% 8 | %% Licensed under the Apache License, Version 2.0 (the "License"); 9 | %% you may not use this file except in compliance with the License. 10 | %% You may obtain a copy of the License at 11 | %% 12 | %% http://www.apache.org/licenses/LICENSE-2.0 13 | %% 14 | %% Unless required by applicable law or agreed to in writing, software 15 | %% distributed under the License is distributed on an "AS IS" BASIS, 16 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | %% See the License for the specific language governing permissions and 18 | %% limitations under the License. 19 | %% 20 | %% 21 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 22 | %% 23 | -module(atomvm_pico_flash_provider). 24 | 25 | -behaviour(provider). 26 | 27 | -export([init/1, do/1, format_error/1]). 28 | 29 | -include_lib("kernel/include/file.hrl"). 30 | 31 | -define(PROVIDER, pico_flash). 32 | -define(DEPS, [uf2create]). 33 | -define(OPTS, [ 34 | {path, $p, "path", string, 35 | "Path to pico device (Defaults Linux: /run/media/${USER}/RPI-RP2, MacOS: /Volumes/RPI-RP2)"}, 36 | {reset, $r, "reset", string, 37 | "Path to serial device to reset before flashing (Defaults Linux: /dev/ttyACM0, MacOS: /dev/cu.usbmodem14*)"} 38 | ]). 39 | 40 | %% 41 | %% provider implementation 42 | %% 43 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 44 | init(State) -> 45 | Provider = providers:create([ 46 | % The atomvm namespace 47 | {namespace, atomvm}, 48 | % The 'user friendly' name of the task 49 | {name, ?PROVIDER}, 50 | % The module implementation of the task 51 | {module, ?MODULE}, 52 | % The task can be run by the user, always true 53 | {bare, true}, 54 | % The list of dependencies 55 | {deps, ?DEPS}, 56 | % How to use the plugin 57 | {example, "rebar3 atomvm pico_flash"}, 58 | % list of options understood by the plugin 59 | {opts, ?OPTS}, 60 | {short_desc, "Convert an AtomVM packbeam file to uf2 and copy to an rp2040 device"}, 61 | {desc, 62 | "~n" 63 | "Use this plugin to convert an AtomVM packbeam file to a uf2 file and copy to an rp2040 device.~n"} 64 | ]), 65 | {ok, rebar_state:add_provider(State, Provider)}. 66 | 67 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 68 | do(State) -> 69 | try 70 | Opts = get_opts(State), 71 | rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Opts]), 72 | ok = do_flash( 73 | rebar_state:project_apps(State), 74 | maps:get(path, Opts), 75 | maps:get(reset, Opts) 76 | ), 77 | {ok, State} 78 | catch 79 | _C:E:_S -> 80 | rebar_api:error("An error occurred in the ~p task. Error=~p~n", [?PROVIDER, E]), 81 | {error, E} 82 | end. 83 | 84 | -spec format_error(any()) -> iolist(). 85 | format_error(Reason) -> 86 | io_lib:format("~p", [Reason]). 87 | 88 | %% 89 | %% internal functions 90 | %% 91 | 92 | %% @private 93 | get_opts(State) -> 94 | {ParsedArgs, _} = rebar_state:command_parsed_args(State), 95 | RebarOpts = atomvm_rebar3_plugin:get_atomvm_rebar_provider_config(State, ?PROVIDER), 96 | ParsedOpts = atomvm_rebar3_plugin:proplist_to_map(ParsedArgs), 97 | maps:merge( 98 | env_opts(), 99 | maps:merge(RebarOpts, ParsedOpts) 100 | ). 101 | 102 | %% @private 103 | env_opts() -> 104 | #{ 105 | path => os:getenv( 106 | "ATOMVM_REBAR3_PLUGIN_PICO_MOUNT_PATH", 107 | get_default_mount() 108 | ), 109 | reset => os:getenv( 110 | "ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV", 111 | get_reset_base() 112 | ) 113 | }. 114 | 115 | %% @private 116 | get_stty_file_flag() -> 117 | {_Fam, System} = os:type(), 118 | case System of 119 | linux -> 120 | "-F"; 121 | _Other -> 122 | "-f" 123 | end. 124 | 125 | %% @private 126 | get_reset_base() -> 127 | {_Fam, System} = os:type(), 128 | Base = 129 | case System of 130 | linux -> 131 | "/dev/ttyACM*"; 132 | darwin -> 133 | "/dev/cu.usbmodem14*"; 134 | _Other -> 135 | "" 136 | end, 137 | os:getenv("ATOMVM_PICO_RESET_DEV", Base). 138 | 139 | %% @private 140 | get_default_mount() -> 141 | {_Fam, System} = os:type(), 142 | Default = 143 | case System of 144 | linux -> 145 | "/run/media/" ++ os:getenv("USER") ++ "/RPI-RP2"; 146 | darwin -> 147 | "/Volumes/RPI-RP2"; 148 | _Other -> 149 | "" 150 | end, 151 | os:getenv("ATOMVM_PICO_MOUNT_PATH", Default). 152 | 153 | %% @private 154 | wait_for_mount(Mount, Count) when Count < 30 -> 155 | try 156 | case file:read_link_info(Mount) of 157 | {ok, #file_info{type = directory} = _Info} -> 158 | ok; 159 | _ -> 160 | timer:sleep(1000), 161 | wait_for_mount(Mount, Count + 1) 162 | end 163 | catch 164 | _ -> 165 | timer:sleep(1000), 166 | wait_for_mount(Mount, Count + 1) 167 | end; 168 | wait_for_mount(Mount, 30) -> 169 | rebar_api:error("Pico not mounted at ~s after 30 seconds. giving up...", [Mount]), 170 | erlang:throw(mount_error). 171 | 172 | %% @private 173 | check_pico_mount(Mount) -> 174 | try 175 | case file:read_link_info(Mount) of 176 | {ok, #file_info{type = directory} = _Info} -> 177 | rebar_api:debug("Pico mounted at ~s.", [Mount]), 178 | ok; 179 | _ -> 180 | rebar_api:error("Pico not mounted at ~s.", [Mount]), 181 | erlang:throw(no_device) 182 | end 183 | catch 184 | _ -> 185 | rebar_api:error("Pico not mounted at ~s.", [Mount]), 186 | erlang:throw(no_device) 187 | end. 188 | 189 | %% @private 190 | needs_reset(ResetBase) -> 191 | case filelib:wildcard(ResetBase) of 192 | [] -> 193 | false; 194 | [ResetPort | _T] -> 195 | case file:read_link_info(ResetPort) of 196 | {ok, #file_info{type = device} = _Info} -> 197 | {true, ResetPort}; 198 | _ -> 199 | false 200 | end; 201 | _ -> 202 | false 203 | end. 204 | 205 | %% @private 206 | do_reset(ResetPort) -> 207 | Flag = get_stty_file_flag(), 208 | BootselMode = lists:join(" ", [ 209 | "stty", Flag, ResetPort, "1200" 210 | ]), 211 | rebar_api:debug("Resetting device at path ~s", [ResetPort]), 212 | ResetStatus = os:cmd(BootselMode), 213 | case ResetStatus of 214 | "" -> 215 | ok; 216 | Error -> 217 | case os:find_executable(picotool) of 218 | false -> 219 | rebar_api:error( 220 | "Warning: ~s~nUnable to locate 'picotool', close the serial monitor before flashing, or install picotool for automatic disconnect and BOOTSEL mode.", 221 | [Error] 222 | ), 223 | erlang:throw(reset_error); 224 | Picotool -> 225 | rebar_api:warn( 226 | "Warning: ~s~nFor faster flashing remember to disconnect serial monitor first.", 227 | [Error] 228 | ), 229 | DevReset = lists:join(" ", [ 230 | Picotool, "reboot", "-f", "-u" 231 | ]), 232 | rebar_api:warn("Disconnecting serial monitor with: `~s' in 5 seconds...", [ 233 | DevReset 234 | ]), 235 | timer:sleep(5000), 236 | RebootReturn = os:cmd(DevReset), 237 | RebootStatus = string:trim(RebootReturn), 238 | case RebootStatus of 239 | "The device was asked to reboot into BOOTSEL mode." -> 240 | ok; 241 | BootError -> 242 | rebar_api:error("Failed to prepare pico for flashing: ~s", [BootError]), 243 | erlang:throw(picoflash_reboot_error) 244 | end 245 | end 246 | end. 247 | 248 | %% @private 249 | get_uf2_file(ProjectApps) -> 250 | [App | _] = [ProjectApp || ProjectApp <- ProjectApps], 251 | OutDir = rebar_app_info:out_dir(App), 252 | Name = binary_to_list(rebar_app_info:name(App)), 253 | DirName = filename:dirname(OutDir), 254 | filename:join(DirName, Name ++ ".uf2"). 255 | 256 | %% @private 257 | get_uf2_appname(ProjectApps) -> 258 | [App | _] = [ProjectApp || ProjectApp <- ProjectApps], 259 | binary_to_list(rebar_app_info:name(App)). 260 | 261 | %% @private 262 | do_flash(ProjectApps, PicoPath, ResetBase) -> 263 | case needs_reset(ResetBase) of 264 | false -> 265 | rebar_api:debug("No Pico found matching ~s.", [ResetBase]), 266 | ok; 267 | {true, ResetPort} -> 268 | rebar_api:debug("Pico at ~s needs reset...", [ResetPort]), 269 | do_reset(ResetPort), 270 | rebar_api:info("Waiting for the device at path ~s to settle and mount...", [ 271 | string:trim(PicoPath) 272 | ]), 273 | wait_for_mount(PicoPath, 0) 274 | end, 275 | check_pico_mount(PicoPath), 276 | TargetUF2 = get_uf2_file(ProjectApps), 277 | App = get_uf2_appname(ProjectApps), 278 | File = App ++ ".uf2", 279 | Dest = filename:join(PicoPath, File), 280 | rebar_api:info("Copying ~s", [File]), 281 | case file:copy(TargetUF2, Dest) of 282 | {ok, _Size} -> 283 | ok; 284 | CopyError -> 285 | rebar_api:error("Failed to copy application file ~s to pico: ~s", [File, CopyError]), 286 | erlang:throw(picoflash_copy_error) 287 | end, 288 | rebar_api:info("Successfully loaded ~s application to device at path ~s.", [App, PicoPath]), 289 | ok. 290 | -------------------------------------------------------------------------------- /src/atomvm_rebar3_plugin.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2020-2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | {application, atomvm_rebar3_plugin, [ 21 | {description, "A rebar plugin for manipulating AtomVM AVM files"}, 22 | {vsn, "0.7.5"}, 23 | {registered, []}, 24 | {applications, [kernel, stdlib]}, 25 | {env, []}, 26 | {modules, []}, 27 | {licenses, ["Apache-2.0"]}, 28 | {pkg_name, "atomvm_rebar3_plugin"}, 29 | {links, [{"github", "https://github.com/atomvm/atomvm_rebar3_plugin"}]} 30 | ]}. 31 | -------------------------------------------------------------------------------- /src/atomvm_rebar3_plugin.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2020-2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | -module(atomvm_rebar3_plugin). 21 | 22 | -export([init/1]). 23 | 24 | %% internal API 25 | -export([proplist_to_map/1, get_atomvm_rebar_provider_config/2]). 26 | 27 | -define(PROVIDERS, [ 28 | atomvm_bootstrap_provider, 29 | atomvm_packbeam_provider, 30 | atomvm_esp32_flash_provider, 31 | atomvm_pico_flash_provider, 32 | atomvm_stm32_flash_provider, 33 | atomvm_uf2create_provider, 34 | atomvm_version_provider, 35 | legacy_packbeam_provider, 36 | legacy_esp32_flash_provider, 37 | legacy_stm32_flash_provider 38 | ]). 39 | 40 | -type proplist() :: [{term(), term()} | term()]. 41 | 42 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 43 | init(State) -> 44 | lists:foldl( 45 | fun(Cmd, {ok, StateAcc}) -> 46 | apply(Cmd, init, [StateAcc]) 47 | end, 48 | {ok, State}, 49 | ?PROVIDERS 50 | ). 51 | 52 | -spec proplist_to_map(Proplist :: proplist()) -> map(). 53 | proplist_to_map(Proplist) -> 54 | proplist_to_map(Proplist, #{}). 55 | 56 | %% @private 57 | proplist_to_map([], Accum) -> 58 | Accum; 59 | proplist_to_map([{K, V} | T], Accum) -> 60 | proplist_to_map(T, Accum#{K => V}); 61 | proplist_to_map([K | T], Accum) -> 62 | proplist_to_map(T, Accum#{K => true}). 63 | 64 | -spec get_atomvm_rebar_provider_config(State :: term(), Provider :: atom()) -> map(). 65 | get_atomvm_rebar_provider_config(State, Provider) -> 66 | case rebar_state:get(State, ?MODULE, undefined) of 67 | undefined -> 68 | #{}; 69 | AtomVM -> 70 | proplist_to_map(proplists:get_value(Provider, AtomVM, [])) 71 | end. 72 | -------------------------------------------------------------------------------- /src/atomvm_stm32_flash_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Uncle Grumpy 3 | %% All rights reserved. 4 | %% 5 | %% Based on esp32_flash_provider.erl 6 | %% Copyright (c) dushin.net 7 | %% 8 | %% Licensed under the Apache License, Version 2.0 (the "License"); 9 | %% you may not use this file except in compliance with the License. 10 | %% You may obtain a copy of the License at 11 | %% 12 | %% http://www.apache.org/licenses/LICENSE-2.0 13 | %% 14 | %% Unless required by applicable law or agreed to in writing, software 15 | %% distributed under the License is distributed on an "AS IS" BASIS, 16 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | %% See the License for the specific language governing permissions and 18 | %% limitations under the License. 19 | %% 20 | %% 21 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 22 | %% 23 | -module(atomvm_stm32_flash_provider). 24 | 25 | -behaviour(provider). 26 | 27 | -export([init/1, do/1, format_error/1]). 28 | 29 | -include_lib("kernel/include/file.hrl"). 30 | 31 | -define(PROVIDER, stm32_flash). 32 | -define(DEPS, [packbeam]). 33 | -define(OPTS, [ 34 | {stflash, $s, "stflash", string, "Path to st-flash"}, 35 | {offset, $o, "offset", string, "Offset (default 0x8080000)"} 36 | ]). 37 | 38 | -define(DEFAULT_OPTS, #{ 39 | stflash => "st-flash", 40 | offset => "0x8080000" 41 | }). 42 | 43 | %% 44 | %% provider implementation 45 | %% 46 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 47 | init(State) -> 48 | Provider = providers:create([ 49 | % The atomvm namespace 50 | {namespace, atomvm}, 51 | % The 'user friendly' name of the task 52 | {name, ?PROVIDER}, 53 | % The module implementation of the task 54 | {module, ?MODULE}, 55 | % The task can be run by the user, always true 56 | {bare, true}, 57 | % The list of dependencies 58 | {deps, ?DEPS}, 59 | % How to use the plugin 60 | {example, "rebar3 atomvm stm32_flash"}, 61 | % list of options understood by the plugin 62 | {opts, ?OPTS}, 63 | {short_desc, "Flash an AtomVM packbeam file to an STM32 device"}, 64 | {desc, 65 | "~n" 66 | "Use this plugin to flash an AtomVM packbeam file to an STM32 device.~n"} 67 | ]), 68 | {ok, rebar_state:add_provider(State, Provider)}. 69 | 70 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 71 | do(State) -> 72 | try 73 | Opts = get_opts(State), 74 | rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Opts]), 75 | ok = do_flash( 76 | rebar_state:project_apps(State), 77 | maps:get(stflash, Opts), 78 | maps:get(offset, Opts) 79 | ), 80 | {ok, State} 81 | catch 82 | C:E:S -> 83 | rebar_api:error( 84 | "An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [ 85 | ?PROVIDER, C, E, S 86 | ] 87 | ), 88 | {error, E} 89 | end. 90 | 91 | -spec format_error(any()) -> iolist(). 92 | format_error(Reason) -> 93 | io_lib:format("~p", [Reason]). 94 | 95 | %% 96 | %% internal functions 97 | %% 98 | 99 | %% @private 100 | get_opts(State) -> 101 | {ParsedArgs, _} = rebar_state:command_parsed_args(State), 102 | RebarOpts = atomvm_rebar3_plugin:get_atomvm_rebar_provider_config(State, ?PROVIDER), 103 | ParsedOpts = atomvm_rebar3_plugin:proplist_to_map(ParsedArgs), 104 | maps:merge( 105 | env_opts(), 106 | maps:merge(RebarOpts, ParsedOpts) 107 | ). 108 | 109 | %% @private 110 | env_opts() -> 111 | #{ 112 | stflash => os:getenv( 113 | "ATOMVM_REBAR3_PLUGIN_STM32_STFLASH", 114 | maps:get(stflash, ?DEFAULT_OPTS) 115 | ), 116 | offset => os:getenv( 117 | "ATOMVM_REBAR3_PLUGIN_STM32_FLASH_OFFSET", 118 | maps:get(offset, ?DEFAULT_OPTS) 119 | ) 120 | }. 121 | 122 | %% @private 123 | do_flash(ProjectApps, StFlash, Offset) -> 124 | [ProjectAppAVM | _] = [get_avm_file(ProjectApp) || ProjectApp <- ProjectApps], 125 | Cmd = lists:join(" ", [ 126 | StFlash, 127 | "--reset", 128 | "write", 129 | ProjectAppAVM, 130 | Offset 131 | ]), 132 | rebar_api:info("~s~n", [Cmd]), 133 | rebar_api:console("~s", [os:cmd(Cmd)]), 134 | ok. 135 | 136 | %% @private 137 | get_avm_file(App) -> 138 | OutDir = rebar_app_info:out_dir(App), 139 | Name = binary_to_list(rebar_app_info:name(App)), 140 | DirName = filename:dirname(OutDir), 141 | filename:join(DirName, Name ++ ".avm"). 142 | -------------------------------------------------------------------------------- /src/atomvm_uf2create_provider.erl: -------------------------------------------------------------------------------- 1 | % 2 | % This file is part of AtomVM. 3 | % 4 | % Copyright 2023-24 Winford (UncleGrumpy) 5 | % 6 | % Licensed under the Apache License, Version 2.0 (the "License"); 7 | % you may not use this file except in compliance with the License. 8 | % You may obtain a copy of the License at 9 | % 10 | % http://www.apache.org/licenses/LICENSE-2.0 11 | % 12 | % Unless required by applicable law or agreed to in writing, software 13 | % distributed under the License is distributed on an "AS IS" BASIS, 14 | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | % See the License for the specific language governing permissions and 16 | % limitations under the License. 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | -module(atomvm_uf2create_provider). 22 | 23 | -behaviour(provider). 24 | 25 | -export([init/1, do/1, format_error/1]). 26 | 27 | -include_lib("kernel/include/file.hrl"). 28 | 29 | -define(PROVIDER, uf2create). 30 | -define(DEPS, [packbeam]). 31 | -define(OPTS, [ 32 | {family_id, $f, "family_id", string, 33 | "Device family or flavor of uf2 file to create (default rp2040)"}, 34 | {output, $o, "output", string, "Output path/name"}, 35 | {start, $s, "start", string, "Start address for the uf2 binary (default 0x10180000)"}, 36 | {input, $i, "input", string, "Input avm file to convert to uf2"} 37 | ]). 38 | 39 | -define(DEFAULT_OPTS, #{ 40 | start => os:getenv("ATOMVM_PICO_APP_START", "0x10180000"), 41 | family_id => os:getenv("ATOMVM_PICO_UF2_FAMILY", rp2040) 42 | }). 43 | 44 | %% 45 | %% provider implementation 46 | %% 47 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 48 | init(State) -> 49 | Provider = providers:create([ 50 | % The atomvm namespace 51 | {namespace, atomvm}, 52 | % The 'user friendly' name of the task 53 | {name, ?PROVIDER}, 54 | % The module implementation of the task 55 | {module, ?MODULE}, 56 | % The task can be run by the user, always true 57 | {bare, true}, 58 | % The list of dependencies 59 | {deps, ?DEPS}, 60 | % How to use the plugin 61 | {example, "rebar3 atomvm uf2create"}, 62 | % list of options understood by the plugin 63 | {opts, ?OPTS}, 64 | {short_desc, "Create a Raspberry Pico uf2 file from an AtomVM packbeam file"}, 65 | {desc, 66 | "~n" 67 | "Use this plugin to create Raspberry Pico uf2 files from an AtomVM packbeam file.~n"} 68 | ]), 69 | {ok, rebar_state:add_provider(State, Provider)}. 70 | 71 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 72 | do(State) -> 73 | try 74 | Opts = get_opts(State), 75 | rebar_api:debug("Effective opts for ~p: ~p", [?PROVIDER, Opts]), 76 | OutFile = get_out_file(State), 77 | TargetAVM = get_avm_file(State), 78 | Output = maps:get(output, Opts, OutFile), 79 | StartAddrStr = parse_addr(maps:get(start, Opts)), 80 | Image = maps:get(input, Opts, TargetAVM), 81 | Uf2Flavor = validate_flavor(maps:get(family_id, Opts)), 82 | ok = uf2tool:uf2create(Output, Uf2Flavor, StartAddrStr, Image), 83 | {ok, State} 84 | catch 85 | C:E:S -> 86 | rebar_api:error( 87 | "An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [ 88 | ?PROVIDER, C, E, S 89 | ] 90 | ), 91 | {error, E} 92 | end. 93 | 94 | -spec format_error(any()) -> iolist(). 95 | format_error(Reason) -> 96 | io_lib:format("~p", [Reason]). 97 | 98 | %% 99 | %% internal functions 100 | %% 101 | 102 | %% @private 103 | get_opts(State) -> 104 | {ParsedArgs, _} = rebar_state:command_parsed_args(State), 105 | RebarOpts = atomvm_rebar3_plugin:get_atomvm_rebar_provider_config(State, ?PROVIDER), 106 | ParsedOpts = atomvm_rebar3_plugin:proplist_to_map(ParsedArgs), 107 | maps:merge( 108 | env_opts(), 109 | maps:merge(RebarOpts, ParsedOpts) 110 | ). 111 | 112 | %% @private 113 | env_opts() -> 114 | #{ 115 | start => os:getenv( 116 | "ATOMVM_REBAR3_PLUGIN_UF2CREATE_START", 117 | maps:get(start, ?DEFAULT_OPTS) 118 | ), 119 | family_id => os:getenv( 120 | "ATOMVM_REBAR3_PLUGIN_UF2_FAMILY", 121 | maps:get(family_id, ?DEFAULT_OPTS) 122 | ) 123 | }. 124 | 125 | %% @private 126 | get_avm_file(State) -> 127 | [App] = [ProjectApp || ProjectApp <- rebar_state:project_apps(State)], 128 | OutDir = rebar_app_info:out_dir(App), 129 | Name = binary_to_list(rebar_app_info:name(App)), 130 | DirName = filename:dirname(OutDir), 131 | filename:join(DirName, Name ++ ".avm"). 132 | 133 | %% @private 134 | get_out_file(State) -> 135 | [App] = [ProjectApp || ProjectApp <- rebar_state:project_apps(State)], 136 | OutDir = rebar_app_info:out_dir(App), 137 | Name = binary_to_list(rebar_app_info:name(App)), 138 | DirName = filename:dirname(OutDir), 139 | filename:join(DirName, Name ++ ".uf2"). 140 | 141 | %% @private 142 | parse_addr("0x" ++ AddrHex) -> 143 | list_to_integer(AddrHex, 16); 144 | parse_addr("16#" ++ AddrHex) -> 145 | list_to_integer(AddrHex, 16); 146 | parse_addr(AddrDec) -> 147 | list_to_integer(AddrDec). 148 | 149 | %% @private 150 | validate_flavor(Flavor) -> 151 | case Flavor of 152 | rp2040 -> 153 | rp2040; 154 | "rp2040" -> 155 | rp2040; 156 | rp2035 -> 157 | data; 158 | "rp2035" -> 159 | data; 160 | data -> 161 | data; 162 | "data" -> 163 | data; 164 | universal -> 165 | universal; 166 | "universal" -> 167 | universal; 168 | Family -> 169 | rebar_api:error("An error occurred in the ~p task. Invalid family_id ~p~n", [ 170 | ?PROVIDER, Family 171 | ]) 172 | end. 173 | -------------------------------------------------------------------------------- /src/atomvm_version_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2020-2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(atomvm_version_provider). 21 | 22 | -behaviour(provider). 23 | 24 | -export([init/1, do/1, format_error/1]). 25 | 26 | -include_lib("kernel/include/file.hrl"). 27 | 28 | -define(PROVIDER, version). 29 | -define(DEPS, []). 30 | -define(OPTS, []). 31 | 32 | %% 33 | %% provider implementation 34 | %% 35 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 36 | init(State) -> 37 | Provider = providers:create([ 38 | % The atomvm namespace 39 | {namespace, atomvm}, 40 | % The 'user friendly' name of the task 41 | {name, ?PROVIDER}, 42 | % The module implementation of the task 43 | {module, ?MODULE}, 44 | % The task can be run by the user, always true 45 | {bare, true}, 46 | % The list of dependencies 47 | {deps, ?DEPS}, 48 | % How to use the plugin 49 | {example, "rebar3 atomvm version"}, 50 | % list of options understood by the plugin 51 | {opts, ?OPTS}, 52 | {short_desc, "Print the version of this plugin to the console."}, 53 | {desc, 54 | "~n" 55 | "Use this task to print the version of this plugin to the console.~n"} 56 | ]), 57 | {ok, rebar_state:add_provider(State, Provider)}. 58 | 59 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 60 | do(State) -> 61 | try 62 | case lists:keyfind(atomvm_rebar3_plugin, 1, application:loaded_applications()) of 63 | {_, _, Version} -> 64 | rebar_api:console(Version, []); 65 | false -> 66 | rebar_api:error( 67 | "Error! Unable to find atomvm_rebar3_plugin in loaded applications", [] 68 | ) 69 | end, 70 | {ok, State} 71 | catch 72 | C:E:S -> 73 | rebar_api:error( 74 | "An error occurred in the ~p task. Class=~p Error=~p Stacktrace=~p~n", [ 75 | ?PROVIDER, C, E, S 76 | ] 77 | ), 78 | {error, E} 79 | end. 80 | 81 | -spec format_error(any()) -> iolist(). 82 | format_error(Reason) -> 83 | io_lib:format("~p", [Reason]). 84 | -------------------------------------------------------------------------------- /src/legacy_esp32_flash_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(legacy_esp32_flash_provider). 21 | 22 | -behaviour(provider). 23 | 24 | -export([init/1, do/1, format_error/1]). 25 | 26 | -include_lib("kernel/include/file.hrl"). 27 | 28 | -define(PROVIDER, esp32_flash). 29 | -define(DEPS, [packbeam]). 30 | -define(OPTS, [ 31 | {esptool, $e, "esptool", string, "Path to esptool.py"}, 32 | {chip, $c, "chip", string, "ESP chip (default auto)"}, 33 | {port, $p, "port", string, "Device port (default /dev/ttyUSB0)"}, 34 | {baud, $b, "baud", string, "Baud rate (default 115200)"}, 35 | {offset, $o, "offset", string, "Offset (default 0x210000)"} 36 | ]). 37 | 38 | %% 39 | %% provider implementation 40 | %% 41 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 42 | init(State) -> 43 | Provider = providers:create([ 44 | % The 'user friendly' name of the task 45 | {name, ?PROVIDER}, 46 | % The module implementation of the task 47 | {module, ?MODULE}, 48 | % The task can be run by the user, always true 49 | {bare, true}, 50 | % The list of dependencies 51 | {deps, ?DEPS}, 52 | % How to use the plugin 53 | {example, "rebar3 esp32_flash"}, 54 | % list of options understood by the plugin 55 | {opts, ?OPTS}, 56 | {short_desc, "A rebar plugin to flash packbeam files to ESP32 devices (DEPRECATED)"}, 57 | {desc, 58 | "A rebar plugin to flash packbeam files to ESP32 devices.~n~n" 59 | "IMPORTANT! this plugin has been DEPRECATED!~n" 60 | "Use `rebar3 atomvm esp32_flash`, instead.~n"} 61 | ]), 62 | {ok, rebar_state:add_provider(State, Provider)}. 63 | 64 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 65 | do(State) -> 66 | rebar_api:warn("DEPRECATED The esp32_flash tool has been moved under the atomvm namespace", []), 67 | atomvm_esp32_flash_provider:do(State). 68 | 69 | -spec format_error(any()) -> iolist(). 70 | format_error(Reason) -> 71 | atomvm_esp32_flash_provider:format_error(Reason). 72 | -------------------------------------------------------------------------------- /src/legacy_packbeam_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(legacy_packbeam_provider). 21 | 22 | -behaviour(provider). 23 | 24 | -export([init/1, do/1, format_error/1]). 25 | 26 | -define(PROVIDER, packbeam). 27 | -define(DEPS, [{default, compile}]). 28 | -define(OPTS, [ 29 | {external, $e, "external", string, "External AVM modules"}, 30 | {force, $f, "force", boolean, "Force rebuild"}, 31 | {prune, $p, "prune", boolean, "Prune unreferenced BEAM files"}, 32 | {include_lines, $i, "include_lines", boolean, 33 | "Include line information in generated AVM files (DEPRECATED)"}, 34 | {remove_lines, $r, "remove_lines", boolean, 35 | "Remove line information from generated AVM files (off by default)"}, 36 | {start, $s, "start", atom, "Start module"} 37 | ]). 38 | 39 | %% 40 | %% provider implementation 41 | %% 42 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 43 | init(State) -> 44 | Provider = providers:create([ 45 | % The 'user friendly' name of the task 46 | {name, ?PROVIDER}, 47 | % The module implementation of the task 48 | {module, ?MODULE}, 49 | % The task can be run by the user, always true 50 | {bare, true}, 51 | % The list of dependencies 52 | {deps, ?DEPS}, 53 | % How to use the plugin 54 | {example, "rebar3 packbeam"}, 55 | % list of options understood by the plugin 56 | {opts, ?OPTS}, 57 | {short_desc, "A rebar plugin to create packbeam files (DEPRECATED)"}, 58 | {desc, 59 | "A rebar plugin to create packbeam files.~n~n" 60 | "IMPORTANT! this plugin has been DEPRECATED!~n" 61 | "Use `rebar3 atomvm packbeam`, instead.~n"} 62 | ]), 63 | {ok, rebar_state:add_provider(State, Provider)}. 64 | 65 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 66 | do(State) -> 67 | rebar_api:warn("DEPRECATED The packbeam tool has been moved under the atomvm namespace", []), 68 | atomvm_packbeam_provider:do(State). 69 | 70 | -spec format_error(any()) -> iolist(). 71 | format_error(Reason) -> 72 | atomvm_packbeam_provider:format_error(Reason). 73 | -------------------------------------------------------------------------------- /src/legacy_stm32_flash_provider.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Uncle Grumpy 3 | %% All rights reserved. 4 | %% 5 | %% Based on esp32_flash_provider.erl 6 | %% Copyright (c) dushin.net 7 | %% 8 | %% Licensed under the Apache License, Version 2.0 (the "License"); 9 | %% you may not use this file except in compliance with the License. 10 | %% You may obtain a copy of the License at 11 | %% 12 | %% http://www.apache.org/licenses/LICENSE-2.0 13 | %% 14 | %% Unless required by applicable law or agreed to in writing, software 15 | %% distributed under the License is distributed on an "AS IS" BASIS, 16 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | %% See the License for the specific language governing permissions and 18 | %% limitations under the License. 19 | %% 20 | % 21 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 22 | % 23 | -module(legacy_stm32_flash_provider). 24 | 25 | -behaviour(provider). 26 | 27 | -export([init/1, do/1, format_error/1]). 28 | 29 | -define(PROVIDER, stm32_flash). 30 | -define(DEPS, [packbeam]). 31 | -define(OPTS, [ 32 | {stflash, $s, "stflash", string, "Path to st-flash"}, 33 | {offset, $o, "offset", string, "Offset (default 0x8080000)"} 34 | ]). 35 | 36 | %% 37 | %% provider implementation 38 | %% 39 | -spec init(rebar_state:t()) -> {ok, rebar_state:t()}. 40 | init(State) -> 41 | Provider = providers:create([ 42 | % The 'user friendly' name of the task 43 | {name, ?PROVIDER}, 44 | % The module implementation of the task 45 | {module, ?MODULE}, 46 | % The task can be run by the user, always true 47 | {bare, true}, 48 | % The list of dependencies 49 | {deps, ?DEPS}, 50 | % How to use the plugin 51 | {example, "rebar3 stm32_flash"}, 52 | % list of options understood by the plugin 53 | {opts, ?OPTS}, 54 | {short_desc, "A rebar plugin to flash packbeam files to STM32 devices (DEPRECATED)"}, 55 | {desc, 56 | "A rebar plugin to flash packbeam files to STM32 devices.~n~n" 57 | "IMPORTANT! this plugin has been DEPRECATED!~n" 58 | "Use `rebar3 atomvm stm32_flash`, instead.~n"} 59 | ]), 60 | {ok, rebar_state:add_provider(State, Provider)}. 61 | 62 | -spec do(rebar_state:t()) -> {ok, rebar_state:t()} | {error, string()}. 63 | do(State) -> 64 | rebar_api:warn("DEPRECATED The stm32_flash tool has been moved under the atomvm namespace", []), 65 | atomvm_stm32_flash_provider:do(State). 66 | 67 | -spec format_error(any()) -> iolist(). 68 | format_error(Reason) -> 69 | atomvm_stm32_flash_provider:format_error(Reason). 70 | -------------------------------------------------------------------------------- /test/driver/apps/bootstrap/bootstrap/application.erl: -------------------------------------------------------------------------------- 1 | % 2 | % This file is part of AtomVM. 3 | % 4 | % Copyright 2023 Fred Dushin 5 | % 6 | % Licensed under the Apache License, Version 2.0 (the "License"); 7 | % you may not use this file except in compliance with the License. 8 | % You may obtain a copy of the License at 9 | % 10 | % http://www.apache.org/licenses/LICENSE-2.0 11 | % 12 | % Unless required by applicable law or agreed to in writing, software 13 | % distributed under the License is distributed on an "AS IS" BASIS, 14 | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | % See the License for the specific language governing permissions and 16 | % limitations under the License. 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(application). 21 | 22 | -export([ 23 | start/1, stop/1, get_env/2, get_env/3, set_env/3, set_env/4, ensure_all_started/1 24 | ]). 25 | 26 | start(Application) -> 27 | avm_application_controller:start_application(Application). 28 | 29 | stop(Application) -> 30 | avm_application_controller:stop_application(Application). 31 | 32 | get_env(Application, Key) -> 33 | avm_env:get_env(Application, Key). 34 | 35 | get_env(Application, Key, Default) -> 36 | avm_env:get_env(Application, Key, Default). 37 | 38 | set_env(Application, Key, Value) -> 39 | avm_env:set_env(Application, Key, Value). 40 | 41 | set_env(Application, Key, Value, Opts) -> 42 | avm_env:set_env(Application, Key, Value, Opts). 43 | 44 | ensure_all_started(Application) -> 45 | avm_application_controller:ensure_all_started(Application). 46 | -------------------------------------------------------------------------------- /test/driver/apps/bootstrap/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, []} 28 | ]}. 29 | -------------------------------------------------------------------------------- /test/driver/apps/bootstrap/src/myapp.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, myapp, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /test/driver/apps/bootstrap/src/myapp.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(myapp). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/bootstrap/src/start.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(start). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/multi-start/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, []}. 27 | -------------------------------------------------------------------------------- /test/driver/apps/multi-start/src/myapp.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, myapp, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /test/driver/apps/multi-start/src/myapp.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(myapp). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/multi-start/src/start.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(start). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/myapp/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, [{start, myapp}, prune]} 28 | ]}. 29 | -------------------------------------------------------------------------------- /test/driver/apps/myapp/src/myapp.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, myapp, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /test/driver/apps/myapp/src/myapp.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(myapp). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/otp_application/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, [application, prune]} 28 | ]}. 29 | -------------------------------------------------------------------------------- /test/driver/apps/otp_application/src/my_app.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, my_app, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {mod, {my_app, #{foo => bar}}}, 29 | {env,[]}, 30 | {modules, []}, 31 | {licenses, ["Apache-2.0"]}, 32 | {links, []} 33 | ]}. 34 | -------------------------------------------------------------------------------- /test/driver/apps/otp_application/src/my_app.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | -module(my_app). 22 | 23 | -export([start/2, stop/1]). 24 | 25 | start(_StartType, _StartArgs) -> 26 | {ok, dummy_pid}. 27 | 28 | stop(_State) -> 29 | ok. 30 | -------------------------------------------------------------------------------- /test/driver/apps/prune/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, []}. 27 | -------------------------------------------------------------------------------- /test/driver/apps/prune/src/a.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(a). 21 | 22 | -export([do/0]). 23 | 24 | do() -> 25 | b:do(id(c)). 26 | 27 | id(X) -> 28 | X. 29 | -------------------------------------------------------------------------------- /test/driver/apps/prune/src/b.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(b). 21 | 22 | -export([do/1]). 23 | 24 | do(_) -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/prune/src/c.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(c). 21 | 22 | -export([do/0]). 23 | 24 | do() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/prune/src/d.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(d). 21 | 22 | -export([do/0]). 23 | 24 | do() -> 25 | no_one_calls_me. 26 | -------------------------------------------------------------------------------- /test/driver/apps/prune/src/myapp.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, myapp, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /test/driver/apps/prune/src/myapp.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(myapp). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | a:do(). 26 | -------------------------------------------------------------------------------- /test/driver/apps/rebar_overrides/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {erl_opts, [debug_info]}. 22 | {deps, []}. 23 | {plugins, [ 24 | atomvm_rebar3_plugin 25 | ]}. 26 | {atomvm_rebar3_plugin, [ 27 | {packbeam, [{start, start}]}, 28 | {esp32_flash, [{chip, "esp32c3"}]}, 29 | {stm32_flash, [{offset, "0x1234"}]} 30 | ]}. 31 | -------------------------------------------------------------------------------- /test/driver/apps/rebar_overrides/src/myapp.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | 21 | {application, myapp, [ 22 | {description, "An AtomVM application"}, 23 | {vsn, "0.1.0"}, 24 | {registered, []}, 25 | {applications, [ 26 | kernel, stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | {licenses, ["Apache-2.0"]}, 31 | {links, []} 32 | ]}. 33 | -------------------------------------------------------------------------------- /test/driver/apps/rebar_overrides/src/myapp.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(myapp). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/apps/rebar_overrides/src/start.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(start). 21 | 22 | -export([start/0]). 23 | 24 | start() -> 25 | ok. 26 | -------------------------------------------------------------------------------- /test/driver/rebar.config: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 Fred Dushin 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | %% 18 | %% SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | %% 20 | {erl_opts, [no_debug_info]}. 21 | {deps, [atomvm_packbeam]}. 22 | 23 | {escript_incl_apps, [ 24 | driver, 25 | atomvm_packbeam 26 | ]}. 27 | {escript_main_app, driver}. 28 | {escript_name, driver}. 29 | {escript_emu_args, "%%! +sbtu +A1\n"}. 30 | 31 | %% Profiles 32 | {profiles, [ 33 | {test, [ 34 | {erl_opts, [debug_info]} 35 | ]} 36 | ]}. 37 | -------------------------------------------------------------------------------- /test/driver/scripts/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## 3 | ## Copyright (c) dushin.net 4 | ## All rights reserved. 5 | ## 6 | # SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 7 | 8 | root_dir="$(cd $(dirname $0)/.. && pwd)" 9 | apps_dir="${root_dir}/apps" 10 | 11 | rm -rf ${root_dir}/_build 12 | 13 | for app in $(/bin/ls ${apps_dir}); do 14 | cd ${apps_dir}/${app} 15 | rm -rf _build 16 | rm -rf _checkouts 17 | done 18 | 19 | echo "done" 20 | -------------------------------------------------------------------------------- /test/driver/scripts/prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## 3 | ## Copyright (c) dushin.net 4 | ## All rights reserved. 5 | ## 6 | # SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 7 | 8 | root_dir="$(cd $(dirname $0)/.. && pwd)" 9 | apps_dir="${root_dir}/apps" 10 | 11 | for app in $(/bin/ls ${apps_dir}); do 12 | cd ${apps_dir}/${app} 13 | rm -rf _build 14 | rm -rf _checkouts 15 | mkdir _checkouts 16 | cd _checkouts 17 | ln -s ../../../../.. atomvm_rebar3_plugin 18 | done 19 | 20 | echo "done" 21 | -------------------------------------------------------------------------------- /test/driver/src/bootstrap_tests.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(bootstrap_tests). 21 | 22 | -export([run/1]). 23 | 24 | run(Opts) -> 25 | ok = test_bootstrap_task(Opts), 26 | ok = test_packbeam_with_bootstrap(Opts), 27 | ok. 28 | 29 | %% @private 30 | test_bootstrap_task(Opts) -> 31 | AppsDir = maps:get(apps_dir, Opts), 32 | AppDir = test:make_path([AppsDir, "bootstrap"]), 33 | 34 | Cmd = create_bootstrap_cmd(AppDir, ["-f"], []), 35 | Output = test:execute_cmd(Cmd, Opts), 36 | test:debug(Output, Opts), 37 | 38 | AppblicationBeamPath = test:make_path([ 39 | AppDir, "_build/default/lib/myapp/bootstrap_ebin/application.beam" 40 | ]), 41 | ok = test:file_exists(AppblicationBeamPath), 42 | 43 | test:tick(). 44 | 45 | test_packbeam_with_bootstrap(Opts) -> 46 | AppsDir = maps:get(apps_dir, Opts), 47 | AppDir = test:make_path([AppsDir, "bootstrap"]), 48 | 49 | Cmd = create_packbeam_cmd(AppDir, ["-f"], []), 50 | Output = test:execute_cmd(Cmd, Opts), 51 | test:debug(Output, Opts), 52 | 53 | ok = test:expect_contains("AVM file written to", Output), 54 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 55 | AVMPath = test:make_path([AppDir, "_build/default/lib/myapp.avm"]), 56 | ok = test:file_exists(AVMPath), 57 | AVMElements = test:get_avm_elements(AVMPath), 58 | 59 | 4 = length(AVMElements), 60 | [_MyAppBeam, _StartBeam, ApplicationBeam, _MyAppApplicationBin] = AVMElements, 61 | 62 | true = packbeam_api:is_beam(ApplicationBeam), 63 | false = packbeam_api:is_entrypoint(ApplicationBeam), 64 | application = packbeam_api:get_element_module(ApplicationBeam), 65 | 66 | test:tick(). 67 | 68 | %% @private 69 | create_bootstrap_cmd(AppDir, Opts, Env) -> 70 | test:create_rebar3_cmd(AppDir, bootstrap, Opts, Env). 71 | 72 | %% @private 73 | create_packbeam_cmd(AppDir, Opts, Env) -> 74 | test:create_rebar3_cmd(AppDir, packbeam, Opts, Env). 75 | -------------------------------------------------------------------------------- /test/driver/src/driver.app.src: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | {application, driver, 21 | [{description, "An escript"}, 22 | {vsn, "0.1.0"}, 23 | {registered, []}, 24 | {applications, 25 | [kernel, 26 | stdlib 27 | ]}, 28 | {env,[]}, 29 | {modules, []}, 30 | 31 | {licenses, ["Apache-2.0"]}, 32 | {links, []} 33 | ]}. 34 | -------------------------------------------------------------------------------- /test/driver/src/driver.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(driver). 21 | 22 | -export([main/1]). 23 | 24 | -define(DEFAULT_OPTS, #{ 25 | root => ".", 26 | verbose => false, 27 | debug => false 28 | }). 29 | 30 | main(Args) -> 31 | {Opts, _PositionalArgs} = parse_args(Args), 32 | case test:run(augment_opts(Opts)) of 33 | ok -> 34 | io:format("Tests passed!~n"), 35 | erlang:halt(0); 36 | Error -> 37 | io:format("Tests failed with error ~p~n", [Error]), 38 | erlang:halt(1) 39 | end. 40 | 41 | %% @private 42 | parse_args(Args) -> 43 | parse_args(Args, ?DEFAULT_OPTS, []). 44 | 45 | %% @private 46 | parse_args([], Accum, PArgs) -> 47 | {Accum, lists:reverse(PArgs)}; 48 | parse_args(["-r", Root | T], Accum, Pargs) -> 49 | parse_args(T, Accum#{root => Root}, Pargs); 50 | parse_args(["-v" | T], Accum, Pargs) -> 51 | parse_args(T, Accum#{verbose => true}, Pargs); 52 | parse_args(["-d" | T], Accum, Pargs) -> 53 | parse_args(T, Accum#{debug => true}, Pargs); 54 | parse_args([H | T], Accum, Pargs) -> 55 | parse_args(T, Accum, [H | Pargs]). 56 | 57 | %% @private 58 | augment_opts(Opts) -> 59 | Root = maps:get(root, Opts), 60 | Opts#{ 61 | apps_dir => test:make_path([Root, "apps"]) 62 | }. 63 | -------------------------------------------------------------------------------- /test/driver/src/esp32_flash_tests.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(esp32_flash_tests). 21 | 22 | -export([run/1]). 23 | 24 | run(Opts) -> 25 | ok = test_flags(Opts), 26 | ok = test_env_overrides(Opts), 27 | ok = test_rebar_overrides(Opts), 28 | ok. 29 | 30 | %% @private 31 | test_flags(Opts) -> 32 | test_flags(Opts, [], [ 33 | {"--chip", "auto"}, 34 | {"--port", "/dev/ttyUSB0"}, 35 | {"--baud", "115200"}, 36 | {"--offset", "0x210000"} 37 | ]), 38 | 39 | test_flags( 40 | Opts, 41 | [ 42 | {"-c", "esp32c3"}, 43 | {"-p", "/dev/tty.usbserial-0001"} 44 | ], 45 | [ 46 | {"--chip", "esp32c3"}, 47 | {"--port", "tty.usbserial-0001"}, 48 | {"--baud", "115200"}, 49 | {"--offset", "0x210000"} 50 | ] 51 | ), 52 | 53 | ok. 54 | 55 | %% @private 56 | test_flags(Opts, Flags, FlagExpectList) -> 57 | AppsDir = maps:get(apps_dir, Opts), 58 | AppDir = test:make_path([AppsDir, "myapp"]), 59 | 60 | Cmd = create_esp32_flash_cmd(AppDir, Flags, []), 61 | Output = test:execute_cmd(Cmd, Opts), 62 | test:debug(Output, Opts), 63 | 64 | lists:foreach( 65 | fun({Flag, Value}) -> 66 | test:expect_contains(io_lib:format("~s ~s", [Flag, Value]), Output) 67 | end, 68 | FlagExpectList 69 | ), 70 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 71 | 72 | test:tick(). 73 | 74 | %% @private 75 | test_env_overrides(Opts) -> 76 | test_env_overrides( 77 | Opts, "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_PORT", "/dev/tty.usbserial-0001", "--port" 78 | ), 79 | test_env_overrides(Opts, "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_CHIP", "esp32", "--chip"), 80 | test_env_overrides(Opts, "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_BAUD", "921600", "--baud"), 81 | test_env_overrides(Opts, "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_OFFSET", "0x1000", ""), 82 | ok. 83 | 84 | %% @private 85 | test_env_overrides(Opts, EnvVar, Value, Flag) -> 86 | AppsDir = maps:get(apps_dir, Opts), 87 | AppDir = test:make_path([AppsDir, "myapp"]), 88 | 89 | Cmd = create_esp32_flash_cmd(AppDir, [], [{EnvVar, Value}]), 90 | Output = test:execute_cmd(Cmd, Opts), 91 | test:debug(Output, Opts), 92 | 93 | ok = test:expect_contains(io_lib:format("~s ~s", [Flag, Value]), Output), 94 | 95 | test:tick(). 96 | 97 | %% @private 98 | test_rebar_overrides(Opts) -> 99 | %% the rebar_overrides rebar.config specifies tge esp32c3 chip 100 | test_rebar_overrides( 101 | Opts, [], "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_CHIP", "esp32", "--chip", "esp32c3" 102 | ), 103 | test_rebar_overrides( 104 | Opts, 105 | [{"-c", "esp32h2"}], 106 | "ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_CHIP", 107 | "esp32", 108 | "--chip", 109 | "esp32h2" 110 | ), 111 | ok. 112 | 113 | %% @private 114 | test_rebar_overrides(Opts, Flags, EnvVar, Value, Flag, ExpectedValue) -> 115 | AppsDir = maps:get(apps_dir, Opts), 116 | AppDir = test:make_path([AppsDir, "rebar_overrides"]), 117 | 118 | Cmd = create_esp32_flash_cmd(AppDir, Flags, [{EnvVar, Value}]), 119 | Output = test:execute_cmd(Cmd, Opts), 120 | test:debug(Output, Opts), 121 | 122 | ok = test:expect_contains(io_lib:format("~s ~s", [Flag, ExpectedValue]), Output), 123 | 124 | test:tick(). 125 | 126 | %% @private 127 | create_esp32_flash_cmd(AppDir, Opts, Env) -> 128 | test:create_rebar3_cmd(AppDir, esp32_flash, [{"-e", "echo"} | Opts], Env). 129 | -------------------------------------------------------------------------------- /test/driver/src/packbeam_tests.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(packbeam_tests). 21 | 22 | -export([run/1]). 23 | 24 | run(Opts) -> 25 | ok = test_defaults(Opts), 26 | ok = test_start(Opts), 27 | ok = test_prune(Opts), 28 | ok = test_rebar_overrides(Opts), 29 | ok = test_otp_application(Opts), 30 | ok. 31 | 32 | %% @private 33 | test_defaults(Opts) -> 34 | AppsDir = maps:get(apps_dir, Opts), 35 | AppDir = test:make_path([AppsDir, "myapp"]), 36 | 37 | %% -f temporary during dev 38 | Cmd = create_packbeam_cmd(AppDir, ["-f"], []), 39 | Output = test:execute_cmd(Cmd, Opts), 40 | test:debug(Output, Opts), 41 | 42 | ok = test:expect_contains("AVM file written to", Output), 43 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 44 | AVMPath = test:make_path([AppDir, "_build/default/lib/myapp.avm"]), 45 | ok = test:file_exists(AVMPath), 46 | AVMElements = test:get_avm_elements(AVMPath), 47 | 48 | 2 = length(AVMElements), 49 | [MyAppBeam, MyAppApplicationBin] = AVMElements, 50 | 51 | true = packbeam_api:is_beam(MyAppBeam), 52 | true = packbeam_api:is_entrypoint(MyAppBeam), 53 | 54 | false = packbeam_api:is_beam(MyAppApplicationBin), 55 | false = packbeam_api:is_entrypoint(MyAppApplicationBin), 56 | 57 | test:tick(). 58 | 59 | %% @private 60 | test_start(Opts) -> 61 | AppsDir = maps:get(apps_dir, Opts), 62 | AppDir = test:make_path([AppsDir, "multi-start"]), 63 | 64 | %% -f temporary during dev 65 | Cmd = create_packbeam_cmd(AppDir, ["-f"], []), 66 | Output = test:execute_cmd(Cmd, Opts), 67 | test:debug(Output, Opts), 68 | 69 | ok = test:expect_contains("AVM file written to", Output), 70 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 71 | AVMPath = test:make_path([AppDir, "_build/default/lib/myapp.avm"]), 72 | ok = test:file_exists(AVMPath), 73 | AVMElements = test:get_avm_elements(AVMPath), 74 | 75 | 3 = length(AVMElements), 76 | [MyAppBeam, StartBeam, MyAppApplicationBin] = AVMElements, 77 | 78 | true = packbeam_api:is_beam(MyAppBeam), 79 | true = packbeam_api:is_entrypoint(MyAppBeam), 80 | 81 | true = packbeam_api:is_beam(StartBeam), 82 | true = packbeam_api:is_entrypoint(StartBeam), 83 | 84 | false = packbeam_api:is_beam(MyAppApplicationBin), 85 | false = packbeam_api:is_entrypoint(MyAppApplicationBin), 86 | 87 | %% 88 | %% Now specify `-s start` to get the start module first 89 | %% 90 | 91 | Cmd2 = create_packbeam_cmd(AppDir, ["-f", {"-s", "start"}], []), 92 | _Output2 = test:execute_cmd(Cmd2, Opts), 93 | AVMElements2 = test:get_avm_elements(AVMPath), 94 | 95 | 3 = length(AVMElements2), 96 | [StartBeam, MyAppBeam, MyAppApplicationBin] = AVMElements2, 97 | 98 | test:tick(). 99 | 100 | %% @private 101 | test_prune(Opts) -> 102 | AppsDir = maps:get(apps_dir, Opts), 103 | AppDir = test:make_path([AppsDir, "prune"]), 104 | 105 | %% -f temporary during dev 106 | Cmd = create_packbeam_cmd(AppDir, ["-f"], []), 107 | Output = test:execute_cmd(Cmd, Opts), 108 | test:debug(Output, Opts), 109 | 110 | ok = test:expect_contains("AVM file written to", Output), 111 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 112 | AVMPath = test:make_path([AppDir, "_build/default/lib/myapp.avm"]), 113 | ok = test:file_exists(AVMPath), 114 | AVMElements = test:get_avm_elements(AVMPath), 115 | 116 | 6 = length(AVMElements), 117 | 118 | {value, ABeam} = test:find_avm_element_by_name("a.beam", AVMElements), 119 | {value, BBeam} = test:find_avm_element_by_name("b.beam", AVMElements), 120 | {value, CBeam} = test:find_avm_element_by_name("c.beam", AVMElements), 121 | {value, DBeam} = test:find_avm_element_by_name("d.beam", AVMElements), 122 | 123 | true = packbeam_api:is_beam(ABeam), 124 | true = packbeam_api:is_beam(BBeam), 125 | true = packbeam_api:is_beam(CBeam), 126 | true = packbeam_api:is_beam(DBeam), 127 | 128 | %% 129 | %% Now specify `-p` to prune out d.beam, since no one references him 130 | %% 131 | 132 | Cmd2 = create_packbeam_cmd(AppDir, ["-f", "-p"], []), 133 | _Output2 = test:execute_cmd(Cmd2, Opts), 134 | AVMElements2 = test:get_avm_elements(AVMPath), 135 | 136 | 5 = length(AVMElements2), 137 | {value, ABeam} = test:find_avm_element_by_name("a.beam", AVMElements2), 138 | {value, BBeam} = test:find_avm_element_by_name("b.beam", AVMElements2), 139 | {value, CBeam} = test:find_avm_element_by_name("c.beam", AVMElements2), 140 | false = test:find_avm_element_by_name("d.beam", AVMElements2), 141 | 142 | test:tick(). 143 | 144 | %% @private 145 | test_rebar_overrides(Opts) -> 146 | AppsDir = maps:get(apps_dir, Opts), 147 | AppDir = test:make_path([AppsDir, "rebar_overrides"]), 148 | 149 | %% -f temporary during dev 150 | Cmd = create_packbeam_cmd(AppDir, ["-f"], []), 151 | Output = test:execute_cmd(Cmd, Opts), 152 | test:debug(Output, Opts), 153 | 154 | ok = test:expect_contains("AVM file written to", Output), 155 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 156 | AVMPath = test:make_path([AppDir, "_build/default/lib/myapp.avm"]), 157 | ok = test:file_exists(AVMPath), 158 | AVMElements = test:get_avm_elements(AVMPath), 159 | 160 | 3 = length(AVMElements), 161 | [StartBeam, MyAppBeam, MyAppApplicationBin] = AVMElements, 162 | 163 | true = packbeam_api:is_beam(MyAppBeam), 164 | true = packbeam_api:is_entrypoint(MyAppBeam), 165 | 166 | true = packbeam_api:is_beam(StartBeam), 167 | true = packbeam_api:is_entrypoint(StartBeam), 168 | 169 | false = packbeam_api:is_beam(MyAppApplicationBin), 170 | false = packbeam_api:is_entrypoint(MyAppApplicationBin), 171 | 172 | %% 173 | %% Now specify `-s myapp` to get the myapp module first 174 | %% 175 | 176 | Cmd2 = create_packbeam_cmd(AppDir, ["-f", {"-s", "myapp"}], []), 177 | _Output2 = test:execute_cmd(Cmd2, Opts), 178 | AVMElements2 = test:get_avm_elements(AVMPath), 179 | 180 | 3 = length(AVMElements2), 181 | [MyAppBeam, StartBeam, MyAppApplicationBin] = AVMElements2, 182 | 183 | test:tick(). 184 | 185 | %% @private 186 | test_otp_application(Opts) -> 187 | AppsDir = maps:get(apps_dir, Opts), 188 | AppDir = test:make_path([AppsDir, "otp_application"]), 189 | 190 | %% -f temporary during dev 191 | Cmd = create_packbeam_cmd(AppDir, ["-f"], []), 192 | Output = test:execute_cmd(Cmd, Opts), 193 | test:debug(Output, Opts), 194 | 195 | ok = test:expect_contains("AVM file written to", Output), 196 | ok = test:expect_contains("_build/default/lib/my_app.avm", Output), 197 | AVMPath = test:make_path([AppDir, "_build/default/lib/my_app.avm"]), 198 | ok = test:file_exists(AVMPath), 199 | AVMElements = test:get_avm_elements(AVMPath), 200 | 201 | [InitShimBeam | _Rest] = AVMElements, 202 | true = packbeam_api:is_beam(InitShimBeam), 203 | true = packbeam_api:is_entrypoint(InitShimBeam), 204 | 205 | {value, StartBoot} = test:find_avm_element_by_name("init/priv/start.boot", AVMElements), 206 | false = packbeam_api:is_beam(StartBoot), 207 | 208 | {value, MyAppBeam} = test:find_avm_element_by_name("my_app.beam", AVMElements), 209 | true = packbeam_api:is_beam(MyAppBeam), 210 | false = packbeam_api:is_entrypoint(MyAppBeam), 211 | 212 | {value, MyAppApplicationBin} = test:find_avm_element_by_name( 213 | "my_app/priv/application.bin", AVMElements 214 | ), 215 | false = packbeam_api:is_beam(MyAppApplicationBin), 216 | false = packbeam_api:is_entrypoint(MyAppApplicationBin), 217 | 218 | test:tick(). 219 | 220 | %% @private 221 | create_packbeam_cmd(AppDir, Opts, Env) -> 222 | test:create_rebar3_cmd(AppDir, packbeam, Opts, Env). 223 | -------------------------------------------------------------------------------- /test/driver/src/stm32_flash_tests.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(stm32_flash_tests). 21 | 22 | -export([run/1]). 23 | 24 | run(Opts) -> 25 | ok = test_flags(Opts), 26 | ok = test_env_overrides(Opts), 27 | ok = test_rebar_overrides(Opts), 28 | ok. 29 | 30 | %% @private 31 | test_flags(Opts) -> 32 | test_flags(Opts, [], [ 33 | {"", "0x8080000"} 34 | ]), 35 | 36 | test_flags( 37 | Opts, 38 | [ 39 | {"-o", "0x1234"} 40 | ], 41 | [ 42 | {"", "0x1234"} 43 | ] 44 | ), 45 | 46 | ok. 47 | 48 | %% @private 49 | test_flags(Opts, Flags, FlagExpectList) -> 50 | AppsDir = maps:get(apps_dir, Opts), 51 | AppDir = test:make_path([AppsDir, "myapp"]), 52 | 53 | Cmd = create_stm32_flash_cmd(AppDir, Flags, []), 54 | Output = test:execute_cmd(Cmd, Opts), 55 | test:debug(Output, Opts), 56 | 57 | lists:foreach( 58 | fun({Flag, Value}) -> 59 | test:expect_contains(io_lib:format("~s ~s", [Flag, Value]), Output) 60 | end, 61 | FlagExpectList 62 | ), 63 | ok = test:expect_contains("_build/default/lib/myapp.avm", Output), 64 | 65 | test:tick(). 66 | 67 | %% @private 68 | test_env_overrides(Opts) -> 69 | test_env_overrides(Opts, "ATOMVM_REBAR3_PLUGIN_STM32_FLASH_OFFSET", "0x1234", ""), 70 | ok. 71 | 72 | %% @private 73 | test_env_overrides(Opts, EnvVar, Value, Flag) -> 74 | AppsDir = maps:get(apps_dir, Opts), 75 | AppDir = test:make_path([AppsDir, "myapp"]), 76 | 77 | Cmd = create_stm32_flash_cmd(AppDir, [], [{EnvVar, Value}]), 78 | Output = test:execute_cmd(Cmd, Opts), 79 | test:debug(Output, Opts), 80 | 81 | ok = test:expect_contains(io_lib:format("~s ~s", [Flag, Value]), Output), 82 | 83 | test:tick(). 84 | 85 | %% @private 86 | test_rebar_overrides(Opts) -> 87 | %% the rebar_overrides rebar.config specifies a 0x1234 offset 88 | test_rebar_overrides( 89 | Opts, [], "ATOMVM_REBAR3_PLUGIN_STM32_FLASH_OFFSET", "0x54321", "", "0x1234" 90 | ), 91 | ok. 92 | 93 | %% @private 94 | test_rebar_overrides(Opts, Flags, EnvVar, Value, Flag, ExpectedValue) -> 95 | AppsDir = maps:get(apps_dir, Opts), 96 | AppDir = test:make_path([AppsDir, "rebar_overrides"]), 97 | 98 | Cmd = create_stm32_flash_cmd(AppDir, Flags, [{EnvVar, Value}]), 99 | Output = test:execute_cmd(Cmd, Opts), 100 | test:debug(Output, Opts), 101 | 102 | ok = test:expect_contains(io_lib:format("~s ~s", [Flag, ExpectedValue]), Output), 103 | 104 | test:tick(). 105 | 106 | %% @private 107 | create_stm32_flash_cmd(AppDir, Opts, Env) -> 108 | test:create_rebar3_cmd(AppDir, stm32_flash, [{"-s", "echo"} | Opts], Env). 109 | -------------------------------------------------------------------------------- /test/driver/src/test.erl: -------------------------------------------------------------------------------- 1 | %% 2 | %% Copyright (c) 2023 3 | %% All rights reserved. 4 | %% 5 | %% Licensed under the Apache License, Version 2.0 (the "License"); 6 | %% you may not use this file except in compliance with the License. 7 | %% You may obtain a copy of the License at 8 | %% 9 | %% http://www.apache.org/licenses/LICENSE-2.0 10 | %% 11 | %% Unless required by applicable law or agreed to in writing, software 12 | %% distributed under the License is distributed on an "AS IS" BASIS, 13 | %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | %% See the License for the specific language governing permissions and 15 | %% limitations under the License. 16 | %% 17 | % 18 | % SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 19 | % 20 | -module(test). 21 | 22 | -export([run/1]). 23 | 24 | -export([ 25 | create_rebar3_cmd/4, 26 | debug/2, 27 | execute_cmd/1, 28 | execute_cmd/2, 29 | expect_contains/2, 30 | expect_equal/2, 31 | file_exists/1, 32 | find_avm_element_by_name/2, 33 | get_avm_elements/1, 34 | make_path/1, 35 | tick/0 36 | ]). 37 | 38 | run(Opts) -> 39 | try 40 | prepare_tests(), 41 | run_tests(Opts) 42 | catch 43 | C:E:S -> 44 | {{class, C}, {error, E}, {stacktrace, S}} 45 | end. 46 | 47 | %% @private 48 | prepare_tests() -> 49 | expect_equal("done", string:strip(os:cmd("scripts/prepare.sh"), both)), 50 | ok. 51 | 52 | %% @private 53 | run_tests(Opts) -> 54 | io:put_chars("packbeam_tests: "), 55 | ok = packbeam_tests:run(Opts), 56 | io:put_chars("\n"), 57 | 58 | io:put_chars("esp32_flash_tests: "), 59 | ok = esp32_flash_tests:run(Opts), 60 | io:put_chars("\n"), 61 | 62 | io:put_chars("stm32_flash_tests: "), 63 | ok = stm32_flash_tests:run(Opts), 64 | io:put_chars("\n"), 65 | 66 | io:put_chars("bootstrap_tests: "), 67 | ok = bootstrap_tests:run(Opts), 68 | io:put_chars("\n"), 69 | 70 | ok. 71 | 72 | make_path(Elements) -> 73 | lists:flatten(lists:join("/", Elements)). 74 | 75 | tick() -> 76 | io:put_chars("."). 77 | 78 | expect_contains(String, Output) -> 79 | case string:find(Output, String) of 80 | nomatch -> 81 | {error, {expected, String, contained_in, Output}}; 82 | _ -> 83 | ok 84 | end. 85 | 86 | expect_equal(String, Output) -> 87 | case string:equal(Output, String) of 88 | false -> 89 | {error, {expected, String, equal_to, Output}}; 90 | _ -> 91 | ok 92 | end. 93 | 94 | file_exists(Path) -> 95 | case filelib:is_regular(Path) of 96 | true -> 97 | ok; 98 | _ -> 99 | {error, {expected, Path, to_exist}} 100 | end. 101 | 102 | create_rebar3_cmd(AppPath, Task, Opts, Env) -> 103 | io_lib:format("cd ~s && ~s rebar3 atomvm ~p ~s", [AppPath, make_env(Env), Task, make_opts(Opts)]). 104 | 105 | make_env(Env) -> 106 | lists:foldl( 107 | fun({Key, Value}, Accum) -> 108 | io_lib:format("~s=~s ", [Key, Value]) ++ Accum 109 | end, 110 | [], 111 | Env 112 | ). 113 | 114 | make_opts(Opts) -> 115 | lists:foldl( 116 | fun 117 | ({Key, Value}, Accum) -> 118 | io_lib:format("~s ~s ", [Key, Value]) ++ Accum; 119 | (Key, Accum) -> 120 | io_lib:format("~s ", [Key]) ++ Accum 121 | end, 122 | [], 123 | Opts 124 | ). 125 | 126 | execute_cmd(Cmd) -> 127 | execute_cmd(Cmd, false). 128 | 129 | execute_cmd(Cmd, Opts) -> 130 | case maps:get(verbose, Opts) orelse maps:get(debug, Opts) of 131 | true -> 132 | io:format("#executing> ~s~n", [Cmd]); 133 | _ -> 134 | ok 135 | end, 136 | %% TODO make this a port 137 | os:cmd(Cmd). 138 | 139 | debug(Msg, Opts) -> 140 | case maps:get(debug, Opts) of 141 | true -> 142 | io:format("~s~n", [Msg]); 143 | _ -> 144 | ok 145 | end. 146 | 147 | get_avm_elements(AVMPath) -> 148 | packbeam_api:list(AVMPath). 149 | 150 | find_avm_element_by_name(AVMElementName, AVMElements) -> 151 | lists:search( 152 | fun(AVMElement) -> 153 | string:equal( 154 | packbeam_api:get_element_name(AVMElement), 155 | AVMElementName 156 | ) 157 | end, 158 | AVMElements 159 | ). 160 | -------------------------------------------------------------------------------- /test/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ## 3 | ## Copyright (c) dushin.net 4 | ## All rights reserved. 5 | ## 6 | # SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later 7 | 8 | set -e 9 | 10 | curr_dir=$(cd $(dirname $0) && pwd) 11 | test_dir="${curr_dir}/driver" 12 | 13 | unset ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_ESPTOOL 14 | unset ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_CHIP 15 | unset ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_PORT 16 | unset ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_BAUD 17 | unset ATOMVM_REBAR3_PLUGIN_ESP32_FLASH_OFFSET 18 | 19 | unset ATOMVM_REBAR3_PLUGIN_STM32_STFLASH 20 | unset ATOMVM_REBAR3_PLUGIN_STM32_FLASH_OFFSET 21 | 22 | unset ATOMVM_REBAR3_PLUGIN_PICO_MOUNT_PATH 23 | unset ATOMVM_REBAR3_PLUGIN_PICO_RESET_DEV 24 | 25 | unset ATOMVM_REBAR3_PLUGIN_UF2CREATE_START 26 | 27 | cd "${test_dir}" 28 | rebar3 escriptize 29 | ./_build/default/bin/driver -r "$(pwd)" "$@" 30 | --------------------------------------------------------------------------------