pio-installer 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pio_installer-1.0.0/LICENSE +201 -0
- pio_installer-1.0.0/PKG-INFO +428 -0
- pio_installer-1.0.0/README.md +410 -0
- pio_installer-1.0.0/pio_installer.egg-info/PKG-INFO +428 -0
- pio_installer-1.0.0/pio_installer.egg-info/SOURCES.txt +29 -0
- pio_installer-1.0.0/pio_installer.egg-info/dependency_links.txt +1 -0
- pio_installer-1.0.0/pio_installer.egg-info/entry_points.txt +2 -0
- pio_installer-1.0.0/pio_installer.egg-info/top_level.txt +1 -0
- pio_installer-1.0.0/pyproject.toml +46 -0
- pio_installer-1.0.0/setup.cfg +4 -0
- pio_installer-1.0.0/src/__init__.py +44 -0
- pio_installer-1.0.0/src/__main__.py +8 -0
- pio_installer-1.0.0/src/cli.py +14 -0
- pio_installer-1.0.0/src/core/__init__.py +12 -0
- pio_installer-1.0.0/src/core/cli.py +1028 -0
- pio_installer-1.0.0/src/core/console.py +132 -0
- pio_installer-1.0.0/src/core/download.py +531 -0
- pio_installer-1.0.0/src/core/files.py +35 -0
- pio_installer-1.0.0/src/core/installer.py +865 -0
- pio_installer-1.0.0/src/core/manifest.py +804 -0
- pio_installer-1.0.0/src/core/target.py +176 -0
- pio_installer-1.0.0/src/core/usercode.py +193 -0
- pio_installer-1.0.0/src/core/yamlreader.py +402 -0
- pio_installer-1.0.0/src/ini.py +275 -0
- pio_installer-1.0.0/src/library_json.py +161 -0
- pio_installer-1.0.0/src/pio.py +200 -0
- pio_installer-1.0.0/test/test_cli.py +151 -0
- pio_installer-1.0.0/test/test_ini.py +133 -0
- pio_installer-1.0.0/test/test_library_json.py +122 -0
- pio_installer-1.0.0/test/test_packaging.py +31 -0
- pio_installer-1.0.0/test/test_uninstall.py +70 -0
|
@@ -0,0 +1,201 @@
|
|
|
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
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright [yyyy] [name of copyright owner]
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pio-installer
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Install embedded C and C++ libraries into a PlatformIO project, for any framework
|
|
5
|
+
Author-email: "Nima Askari (NimaLTD)" <nima.askari@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/nimaltd/pio-installer
|
|
8
|
+
Project-URL: Issues, https://github.com/nimaltd/pio-installer/issues
|
|
9
|
+
Keywords: platformio,pio,library,embedded,arduino,esp-idf,stm32,installer,nimaltd
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# pio-installer
|
|
20
|
+
|
|
21
|
+
Installs embedded C and C++ libraries into a PlatformIO project, from GitHub, from a zip, or from a folder, for any framework.
|
|
22
|
+
|
|
23
|
+
It puts a library into your project's `lib` folder, which PlatformIO builds from for every framework: Arduino, ESP-IDF, STM32Cube, or none at all on the native platform. A library written for any project gets the `library.json` PlatformIO builds it by, the defines it needs go into `platformio.ini`, the libraries it needs go in first, and its settings are kept through every update.
|
|
24
|
+
|
|
25
|
+
It works with any library that has an `installer.yml` at the root of its repository. I wrote it for my own [NimaLTD](https://github.com/nimaltd) libraries, and they all have one, but nothing in it is tied to them: add an `installer.yml` to yours, as shown [below](#for-someone-writing-a-library), and it installs the same way. The same file serves [stm32-installer](https://github.com/nimaltd/stm32-installer), [zephyr-installer](https://github.com/nimaltd/zephyr-installer), [esp32-installer](https://github.com/nimaltd/esp32-installer) and [arduino-installer](https://github.com/nimaltd/arduino-installer).
|
|
26
|
+
|
|
27
|
+
PlatformIO from the command line and the PlatformIO IDE in VS Code both build what it installs, since `lib` is where PlatformIO itself looks.
|
|
28
|
+
|
|
29
|
+
Every command below uses `owner/example`, the library's GitHub owner and name, such as `nimaltd/ee24`. Put the real ones in its place.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installing a library
|
|
34
|
+
|
|
35
|
+
Install the installer once. This needs internet:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install pio-installer
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then, from your project's folder, the one holding `platformio.ini`, install a library by its GitHub owner and name. To see it work first, take [pio-installer-example](https://github.com/nimaltd/pio-installer-example), a library made for trying the installer on:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pio-installer nimaltd/pio-installer-example
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
It builds with every framework, and on the native platform too, so you can run it on your computer with no board at all. Its README walks through a setting kept through an update, an option, and an uninstall. Any other library goes in the same way, as `pio-installer owner/example`.
|
|
48
|
+
|
|
49
|
+
To update it later, `pip install --upgrade pio-installer`. To remove it, `pip uninstall pio-installer`.
|
|
50
|
+
|
|
51
|
+
On Windows, if `pio-installer` is not found after installing, pip put it in a folder that is not on your PATH. `python -m pio_installer owner/example` runs the same thing.
|
|
52
|
+
|
|
53
|
+
### Where a library goes
|
|
54
|
+
|
|
55
|
+
Into `lib`, in a folder of its own:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
my-project/
|
|
59
|
+
platformio.ini the defines of a library that has some, in build_flags
|
|
60
|
+
.pio-installer.json what is installed here, and where
|
|
61
|
+
src/
|
|
62
|
+
main.c
|
|
63
|
+
lib/
|
|
64
|
+
example/
|
|
65
|
+
library.json written by the installer: how PlatformIO builds the library
|
|
66
|
+
src/
|
|
67
|
+
example.h the library's files, as its installer.yml lists them
|
|
68
|
+
example_config.h its settings, between USER CODE lines
|
|
69
|
+
example.c
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
PlatformIO builds a library of `lib` once your code includes one of its headers, for every environment in `platformio.ini`, so the library is your project's own, with your project's settings. You include it by its name:
|
|
73
|
+
|
|
74
|
+
```c
|
|
75
|
+
#include "example.h"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The installer asks for the folder, with `lib/example` as the answer when you just press Enter. A folder outside `lib` works too, given with `--dir`, but PlatformIO does not look there, so the installer says what to add to `platformio.ini`:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
Project
|
|
82
|
+
manual lib_extra_dirs PlatformIO looks for libraries in lib/, and example is not in it.
|
|
83
|
+
Add its folder's parent to lib_extra_dirs in the [env] section of platformio.ini, or install it into lib/ with --dir lib/example.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### library.json
|
|
87
|
+
|
|
88
|
+
PlatformIO builds a library by its `library.json`. A library written for any project has none, so the installer writes one from the library's `installer.yml`, and writes it again on every install:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"name": "example",
|
|
93
|
+
"version": "1.0.0",
|
|
94
|
+
"frameworks": "*",
|
|
95
|
+
"platforms": "*",
|
|
96
|
+
"build": {
|
|
97
|
+
"srcDir": ".",
|
|
98
|
+
"srcFilter": ["-<*>", "+<src/example.c>"],
|
|
99
|
+
"includeDir": "src"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
It names the library's source files one by one, so PlatformIO builds those and nothing else: a test or an example in the library's folder is left alone. Its description, licence, repository and author go in too, and the frameworks, platforms and PlatformIO Registry libraries the library lists, as [below](#for-someone-writing-a-library).
|
|
105
|
+
|
|
106
|
+
A library made for PlatformIO that ships its own `library.json`, listed in its `installer.yml` so it is installed, keeps it: the installer writes one only for a library that has none.
|
|
107
|
+
|
|
108
|
+
### Defines
|
|
109
|
+
|
|
110
|
+
A library that needs a define for the whole build, such as littlefs's `LFS_DEFINES`, lists it in its `installer.yml`, and the installer puts it into `build_flags` in `platformio.ini`, between two lines that say whose it is:
|
|
111
|
+
|
|
112
|
+
```ini
|
|
113
|
+
[env]
|
|
114
|
+
build_flags =
|
|
115
|
+
; >>> pio-installer: example >>>
|
|
116
|
+
-DEXAMPLE_FAST
|
|
117
|
+
; <<< pio-installer: example <<<
|
|
118
|
+
|
|
119
|
+
[env:uno]
|
|
120
|
+
platform = atmelavr
|
|
121
|
+
board = uno
|
|
122
|
+
framework = arduino
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
`[env]` is shared by every environment, so that is where it goes, and the installer adds the section when an environment needs it and the file has none. An environment with `build_flags` of its own does not take them from `[env]`, so it gets the same lines in its own. Everything else in the file is left as you wrote it.
|
|
126
|
+
|
|
127
|
+
Not in `library.json`: PlatformIO gives the `build_flags` of a `library.json` to the library's own files and to nothing else, so your code, which includes the library's header, would not see the define, and the two would not agree on what the header declares.
|
|
128
|
+
|
|
129
|
+
Every install writes the lines again from the library's new `installer.yml`, and an uninstall takes them out, with the section the installer added, so `platformio.ini` is back to the byte it was.
|
|
130
|
+
|
|
131
|
+
### Frameworks and platforms
|
|
132
|
+
|
|
133
|
+
PlatformIO leaves a library out of any build whose framework or platform the library does not list, without a word, and your `#include` then simply finds nothing. So before anything is written, the installer reads every environment in `platformio.ini` and names any the library will not build in:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Requirements
|
|
137
|
+
check [env:esp32] builds with espidf, which example does not list, so PlatformIO leaves it out of that build
|
|
138
|
+
example lists: arduino.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
It is a warning and nothing more. The library still goes in, for the environments it does build in.
|
|
142
|
+
|
|
143
|
+
### A library that needs another
|
|
144
|
+
|
|
145
|
+
What a library needs goes into `lib` too, beside it, and installs first. In `lib` every library finds the others' headers, so nothing else is needed. One already there at a version that will do is left alone. Everything is fetched before anything is installed, so when a library cannot be had, nothing is changed.
|
|
146
|
+
|
|
147
|
+
A library from the [PlatformIO Registry](https://registry.platformio.org), such as ArduinoJson, is a different thing: the library lists it, the installer writes it into the library's `library.json`, and PlatformIO installs it by itself at the next build.
|
|
148
|
+
|
|
149
|
+
### Settings
|
|
150
|
+
|
|
151
|
+
A library's settings are in its configuration header, between `USER CODE BEGIN` and `USER CODE END`:
|
|
152
|
+
|
|
153
|
+
```c
|
|
154
|
+
/* USER CODE BEGIN EXAMPLE_CONFIGURATION */
|
|
155
|
+
#define EXAMPLE_PERIOD_MS 250U
|
|
156
|
+
/* USER CODE END EXAMPLE_CONFIGURATION */
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Change them there. Every install and update keeps what is between those lines. The library is in your project's `lib`, so they are your project's settings, for every environment it builds.
|
|
160
|
+
|
|
161
|
+
### What you see
|
|
162
|
+
|
|
163
|
+
A first install from GitHub, of a library that needs I2C and a define:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
Fetching owner/example ...
|
|
167
|
+
|
|
168
|
+
example 1.2.0
|
|
169
|
+
Driver for the X chip
|
|
170
|
+
driver / storage
|
|
171
|
+
|
|
172
|
+
Requirements
|
|
173
|
+
note EXAMPLE_FAST goes into build_flags in platformio.ini
|
|
174
|
+
note Needs I2C, 400 kHz
|
|
175
|
+
Set it up in your code.
|
|
176
|
+
|
|
177
|
+
Folder to install example into [lib/example]:
|
|
178
|
+
|
|
179
|
+
Files
|
|
180
|
+
written lib/example/src/example.h
|
|
181
|
+
written lib/example/src/example_config.h
|
|
182
|
+
written lib/example/src/example.c
|
|
183
|
+
|
|
184
|
+
Project
|
|
185
|
+
updated library.json Wrote example's library.json, which PlatformIO builds it by.
|
|
186
|
+
updated platformio.ini Added example's defines to platformio.ini, for every environment.
|
|
187
|
+
backup: platformio.ini.20261017-091500.bak
|
|
188
|
+
|
|
189
|
+
Done. #include "example.h" and you are away.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### What to install
|
|
193
|
+
|
|
194
|
+
The argument can be any of these, and you can give several at once:
|
|
195
|
+
|
|
196
|
+
| You have | You type |
|
|
197
|
+
|---|---|
|
|
198
|
+
| Nothing yet, and internet | `pio-installer owner/example` |
|
|
199
|
+
| The library's GitHub address | `pio-installer https://github.com/owner/example` |
|
|
200
|
+
| The zip from GitHub's **Download ZIP** | `pio-installer D:/Downloads/example-main.zip` |
|
|
201
|
+
| That zip unpacked, anywhere on disk | `pio-installer D:/Downloads/example-main` |
|
|
202
|
+
|
|
203
|
+
A bare name with no owner, like `example`, is a NimaLTD library, `nimaltd/example` on GitHub, unless a folder of that name exists where you run it, in which case the folder is used. A path that does not exist is reported as missing rather than looked up on GitHub.
|
|
204
|
+
|
|
205
|
+
### Options
|
|
206
|
+
|
|
207
|
+
| Option | What it does |
|
|
208
|
+
|---|---|
|
|
209
|
+
| `--project D:/projects/blink` | The project's folder, the one holding `platformio.ini`, when you are not running from it |
|
|
210
|
+
| `--dir lib/example2` | The folder to install into, for one library. Asked for when not given, with `lib/` and the library's name as the answer if you just press Enter, or the folder it is already in |
|
|
211
|
+
| `--ref v2.0.0` | A tag, a branch or a commit to take from GitHub. When not given, `main`, or `master` for a repository that has no `main` |
|
|
212
|
+
| `--key github_pat_...` | A GitHub token, for a library in a private repository. See [A private repository](#a-private-repository) |
|
|
213
|
+
| `--uninstall example` | Take the library out. See [Uninstalling a library](#uninstalling-a-library) |
|
|
214
|
+
| `--with uptime` | Take this part of the library without being asked. Give it once for each part |
|
|
215
|
+
| `--without uptime` | Leave this part out, or take it out of a library already installed |
|
|
216
|
+
| `--version` | Show which version of the installer you have, and do nothing else |
|
|
217
|
+
|
|
218
|
+
In a script, where nobody can answer, every question takes the answer offered.
|
|
219
|
+
|
|
220
|
+
### Updating a library
|
|
221
|
+
|
|
222
|
+
Run the same command again. Every file of the library is replaced, so an update updates, and `library.json` and the lines in `platformio.ini` are written again from the new `installer.yml`. What you wrote between `USER CODE BEGIN` and `USER CODE END` is kept. Outside those lines, the next install replaces it, and when that would lose something of yours the file is saved beside it first, as a `.bak`. `platformio.ini` is saved the same way, before each change, as `platformio.ini.<date>-<time>.bak`.
|
|
223
|
+
|
|
224
|
+
The record of what is installed, and where, is `.pio-installer.json`, beside `platformio.ini`.
|
|
225
|
+
|
|
226
|
+
### Uninstalling a library
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
pio-installer --uninstall example
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Its files go, its `library.json`, and its lines in `platformio.ini`. What was yours is saved before it goes, as a `.bak` beside it: a configuration header with your settings in it, or any file of the library you changed by hand. A file you put in the library's folder yourself is left where it is, and the folder with it.
|
|
233
|
+
|
|
234
|
+
A library another one needs stays, and the installer says which needs it. One that came in only because the library needed it stays too, and the installer says how to take it out.
|
|
235
|
+
|
|
236
|
+
### Without internet
|
|
237
|
+
|
|
238
|
+
On a machine that has internet, `pip download pio-installer` saves one file, the installer, which needs nothing else. Download the library too, from the green **Code** button, **Download ZIP**. Then, on the machine with no internet:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
pip install pio_installer-1.0.0-py3-none-any.whl
|
|
242
|
+
pio-installer D:/Downloads/example-main.zip
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
If the library needs another, give that zip on the same line. A library that needs one from the PlatformIO Registry needs internet for the first build, when PlatformIO fetches it. Behind a proxy, set `HTTPS_PROXY` to its address.
|
|
246
|
+
|
|
247
|
+
### A private repository
|
|
248
|
+
|
|
249
|
+
A library in a private repository installs the same way, given a GitHub token that can read it. Make one once:
|
|
250
|
+
|
|
251
|
+
1. Open [github.com/settings/personal-access-tokens](https://github.com/settings/personal-access-tokens) and click **Generate new token**.
|
|
252
|
+
2. Give it a name and an expiry. Under **Resource owner**, pick the account or the organisation that owns the repository.
|
|
253
|
+
3. Under **Repository access**, choose **Only select repositories** and pick the library's repository.
|
|
254
|
+
4. Under **Permissions**, set **Contents** to **Read-only**:
|
|
255
|
+
- Older layout: open **Repository permissions** and change **Contents** from **No access** to **Read-only**.
|
|
256
|
+
- Newer layout: click **+ Add permissions**, tick **Contents**, then set its access to **Read-only**.
|
|
257
|
+
|
|
258
|
+
**Metadata** comes with it by itself. Contents is the one that matters: without it the token can see the repository but not read a file of it.
|
|
259
|
+
5. Click **Generate token**, and copy it. GitHub shows it only once.
|
|
260
|
+
|
|
261
|
+
Then give it with `--key`:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
pio-installer owner/example --key github_pat_...
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Or put it in `GITHUB_TOKEN` once, and install by name as usual. That keeps it out of your shell's history, where `--key` leaves it:
|
|
268
|
+
|
|
269
|
+
**Windows, PowerShell:**
|
|
270
|
+
|
|
271
|
+
```powershell
|
|
272
|
+
$env:GITHUB_TOKEN = "github_pat_..."
|
|
273
|
+
pio-installer owner/example
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
**Windows, Command Prompt:**
|
|
277
|
+
|
|
278
|
+
```bat
|
|
279
|
+
set GITHUB_TOKEN=github_pat_...
|
|
280
|
+
pio-installer owner/example
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**Linux and macOS:**
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
export GITHUB_TOKEN=github_pat_...
|
|
287
|
+
pio-installer owner/example
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`--key` comes first when both are there. `GH_TOKEN` works as well, and if you use the `gh` command, `gh auth token` prints the token you are signed in with. Whichever way it comes, the token is sent to GitHub and nowhere else.
|
|
291
|
+
|
|
292
|
+
When the token cannot read the library, the installer says which of these it is:
|
|
293
|
+
|
|
294
|
+
- **It can see the repository, but cannot read its files.** The token has no Contents permission, only Metadata. Edit the token, and its value stays the same, so the command you ran keeps working: open the tokens page, click the token's name, click **Edit**, set Contents to **Read-only** as in step 4, and click **Update** at the bottom of the page. Then run the same command again.
|
|
295
|
+
- **It cannot see the repository.** The repository is not in the token's Repository access. Edit the token as above and add it.
|
|
296
|
+
- **GitHub did not accept the token.** It has expired, been revoked, or was copied with a character missing. Make a new one.
|
|
297
|
+
|
|
298
|
+
A repository of an organisation can need one more step: an organisation that asks for fine-grained tokens to be approved shows the token nothing of its repositories until an owner of the organisation approves it, under its settings, **Personal access tokens**, **Pending requests**.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## For someone writing a library
|
|
305
|
+
|
|
306
|
+
Put an `installer.yml` at the root of the repository. Any library can have one, whoever wrote it, and the one file serves pio-installer and the other installers alike: each reads its own keys and leaves the others' alone.
|
|
307
|
+
|
|
308
|
+
Every key pio-installer reads is below, each with what it does. Only `name` and `files` are required; leave out what your library does not need. For a working one to copy, see [pio-installer-example](https://github.com/nimaltd/pio-installer-example).
|
|
309
|
+
|
|
310
|
+
```yaml
|
|
311
|
+
name: example # the library's name, and its folder in lib/
|
|
312
|
+
description: Driver for the X chip # one line: shown while installing, and in library.json
|
|
313
|
+
repository: https://github.com/owner/example # where it comes from; its owner is the author
|
|
314
|
+
license: Apache-2.0 # the licence's SPDX name
|
|
315
|
+
version: 1.0.0 # only when the first header has no @version tag
|
|
316
|
+
|
|
317
|
+
kind: driver # driver, middleware, rtos, protocol, filesystem,
|
|
318
|
+
# utility or bsp: library.json's keywords
|
|
319
|
+
category: storage # sensor, storage, display, communication, wireless,
|
|
320
|
+
# rtos, timing, power, input, math or system
|
|
321
|
+
provides: [] # what it gives other libraries: [rtos] for an RTOS
|
|
322
|
+
|
|
323
|
+
requires:
|
|
324
|
+
pio_installer: 1.0.0 # the oldest pio-installer that reads this file
|
|
325
|
+
libraries: # other libraries, installed first into lib/
|
|
326
|
+
- osal >= 1.0.0 # no owner means nimaltd
|
|
327
|
+
- owner/lib # anyone else's, as owner/name
|
|
328
|
+
peripherals: # hardware it uses, named to the user
|
|
329
|
+
- type: i2c # what it is
|
|
330
|
+
note: 400 kHz # how to set it up
|
|
331
|
+
|
|
332
|
+
install:
|
|
333
|
+
layout: mirror # mirror keeps the repository's folders,
|
|
334
|
+
# flat (the default) puts every file at the top
|
|
335
|
+
include_dirs: [src, src/port] # include folders, only when the guess is wrong:
|
|
336
|
+
# the first is library.json's includeDir
|
|
337
|
+
defines: # build_flags in platformio.ini, for every environment
|
|
338
|
+
- EXAMPLE_FAST # NAME, or NAME=value
|
|
339
|
+
|
|
340
|
+
files:
|
|
341
|
+
headers: # .h files; the first is the one to #include
|
|
342
|
+
- src/example.h
|
|
343
|
+
- src/example_config.h # its settings, in USER CODE lines kept on update
|
|
344
|
+
sources: # .c and .cpp files, the only ones PlatformIO builds
|
|
345
|
+
- src/example.c
|
|
346
|
+
- from: src/port/spi.c # a file that goes somewhere of its own,
|
|
347
|
+
to: src/port/spi.c # whatever the layout says
|
|
348
|
+
|
|
349
|
+
options: # parts the user chooses at install
|
|
350
|
+
uptime: # the name typed after --with
|
|
351
|
+
description: Uptime in hours, minutes and seconds # the question asked
|
|
352
|
+
libraries: [] # libraries this part needs, installed first
|
|
353
|
+
files: # its files, written like files above
|
|
354
|
+
sources:
|
|
355
|
+
- src/example_uptime.c
|
|
356
|
+
|
|
357
|
+
extras: # copied as they are, never compiled
|
|
358
|
+
- LICENSE.md # LICENSE.md and NOTICE are the default,
|
|
359
|
+
- NOTICE # so leave this out if that is all
|
|
360
|
+
- README.md
|
|
361
|
+
|
|
362
|
+
pio: # read by pio-installer only, for library.json
|
|
363
|
+
frameworks: [arduino, espidf] # the frameworks it builds with, as platformio.ini
|
|
364
|
+
# names them; any, "*", when left out
|
|
365
|
+
platforms: [espressif32] # the platforms it builds for; any, "*", when left out
|
|
366
|
+
dependencies: # PlatformIO Registry libraries it needs, as
|
|
367
|
+
- bblanchon/ArduinoJson@^7 # owner/name, with @version when one is needed.
|
|
368
|
+
# PlatformIO installs them by itself
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Keys only the other installers read, such as `requires.installer`, `zephyr`, `esp32` and `arduino`, can stay in the same file. This installer skips them.
|
|
372
|
+
|
|
373
|
+
Leave `version` out. The installer reads the version from the `@version` tag in the file comment of the first header listed, so it is written in the code and nowhere else.
|
|
374
|
+
|
|
375
|
+
`requires.pio_installer` is the oldest pio-installer that reads the file correctly. It is checked before anything else in the file is read, so an older installer stops with a message saying to update, rather than read the file wrongly. Write it as three numbers, `1.0.0`: unquoted, YAML reads `1.10` as the decimal number `1.1`, and that is refused.
|
|
376
|
+
|
|
377
|
+
In YAML, `*` alone starts something else, so write any as `"*"` or `["*"]`, or leave the key out.
|
|
378
|
+
|
|
379
|
+
### What PlatformIO needs of a library
|
|
380
|
+
|
|
381
|
+
- **The header to include first in `headers`.** `library.json` names one include folder, the one the first header listed is in, unless `install.include_dirs` names the folders. A header in any other folder is found too: the installer adds that folder to `library.json` as `-I`, which PlatformIO gives the library and your project alike.
|
|
382
|
+
- **`extern "C"` in every header of C code**, when a project in C++ may use it, as one with the Arduino framework does. Without it the linker cannot find a function of a `.c` file.
|
|
383
|
+
- **Settings in a configuration header**, between `USER CODE` lines the installer keeps.
|
|
384
|
+
- **A define in `install.defines` only when the whole build needs it.** It goes into every environment of the project. A setting that only the library reads belongs in its configuration header.
|
|
385
|
+
- **`frameworks` and `platforms` that are true.** Listing too few hides the library from a build that could use it, and the installer warns about it; listing too many lets a build try and fail.
|
|
386
|
+
|
|
387
|
+
A library made for PlatformIO that ships its own `library.json`, listed under `extras` or `files` so it is installed, keeps it: the installer writes one only for a library that has none.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## Running the tests
|
|
392
|
+
|
|
393
|
+
The shared core, [core-installer](https://github.com/nimaltd/core-installer), is a git submodule in `src/core`, so clone with it:
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
git clone --recursive https://github.com/nimaltd/pio-installer.git
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
In a clone made without `--recursive`, `git submodule update --init` fetches it. Then:
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
python test/run_tests.py
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
CI also installs a small library from `test/e2e/`, and the one it needs, with the installer it just built, into a project with two environments: one with `build_flags` of its own, and one without. It changes the library's setting and installs again, builds both environments with PlatformIO on the native platform, and runs them: the library's header stops the build when its define did not arrive, and the program prints a number made from the setting the update had to keep. Then it takes the library out, and checks `platformio.ini` is back to the byte it was. So every release is known to work with real PlatformIO.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Support
|
|
410
|
+
|
|
411
|
+
I write these tools and libraries in my own time and give them away, because good tools should be easy to get. If this one saved you an afternoon, there are two things that genuinely help:
|
|
412
|
+
|
|
413
|
+
**Star the repo.** It costs you one click, it helps other engineers find the tool, and it is the main reason I keep going.
|
|
414
|
+
|
|
415
|
+
**[Buy me a coffee on Ko-fi](https://ko-fi.com/nimaltd).** Any amount is a real motivation to keep writing, documenting and maintaining this work.
|
|
416
|
+
|
|
417
|
+
[](https://github.com/NimaLTD)
|
|
418
|
+
[](https://youtube.com/@nimaltd)
|
|
419
|
+
[](https://instagram.com/github.nimaltd)
|
|
420
|
+
[](https://linkedin.com/in/nimaltd)
|
|
421
|
+
[](mailto:nima.askari@gmail.com)
|
|
422
|
+
[](https://ko-fi.com/nimaltd)
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## License
|
|
427
|
+
|
|
428
|
+
Apache License 2.0. See [LICENSE](https://github.com/nimaltd/pio-installer/blob/main/LICENSE).
|