|
| 1 | +How to specify global build defines and options |
| 2 | +=============================================== |
| 3 | + |
| 4 | +To create globally usable macro definitions for a Sketch, create a file |
| 5 | +with a name based on your Sketch’s file name followed by ``.globals.h`` |
| 6 | +in the Sketch folder. For example, if the main Sketch file is named |
| 7 | +``LowWatermark.ino``, its global ``.h`` file would be |
| 8 | +``LowWatermark.ino.globals.h``. This file will be implicitly included |
| 9 | +with every module built for your Sketch. Do not directly include it in |
| 10 | +any of your sketch files or in any other source files. There is no need |
| 11 | +to create empty/dummy files, when not used. |
| 12 | + |
| 13 | +This global ``.h`` also supports embedding compiler command-line options |
| 14 | +in a unique “C” block comment. Compiler options are placed in a “C” |
| 15 | +block comment starting with ``/*@create-file:build.opt@``. This |
| 16 | +signature line must be alone on a single line. The block comment ending |
| 17 | +``*/`` should also be alone on a single line. In between, place your |
| 18 | +compiler command-line options just as you would have for the GCC @file |
| 19 | +command option. |
| 20 | + |
| 21 | +Actions taken in processing comment block to create ``build.opt`` \* for |
| 22 | +each line, white space is trimmed \* blank lines are skipped \* lines |
| 23 | +starting with ``*``, ``//``, or ``#`` are skipped \* the remaining |
| 24 | +results are written to build tree\ ``/core/build.opt`` \* multiple |
| 25 | +``/*@create-file:build.opt@`` ``*/`` comment blocks are not allowed \* |
| 26 | +``build.opt`` is finished with a ``-include ...`` command, which |
| 27 | +references the global .h its contents were extracted from. |
| 28 | + |
| 29 | +Example Sketch: ``LowWatermark.ino`` |
| 30 | + |
| 31 | +.. code:: cpp |
| 32 | +
|
| 33 | + #include <umm_malloc/umm_malloc.h> // has prototype for umm_free_heap_size_min() |
| 34 | +
|
| 35 | + void setup() { |
| 36 | + Serial.begin(115200); |
| 37 | + delay(200); |
| 38 | + #ifdef MYTITLE1 |
| 39 | + Serial.printf("\r\n" MYTITLE1 MYTITLE2 "\r\n"); |
| 40 | + #else |
| 41 | + Serial.println("ERROR: MYTITLE1 not present"); |
| 42 | + #endif |
| 43 | + Serial.printf("Heap Low Watermark %u\r\n", umm_free_heap_size_min()); |
| 44 | + } |
| 45 | +
|
| 46 | + void loop() {} |
| 47 | +
|
| 48 | +Global ``.h`` file: ``LowWatermark.ino.globals.h`` |
| 49 | + |
| 50 | +.. code:: cpp |
| 51 | +
|
| 52 | + /*@create-file:build.opt@ |
| 53 | + // An embedded build.opt file using a "C" block comment. The starting signature |
| 54 | + // must be on a line by itself. The closing block comment pattern should be on a |
| 55 | + // line by itself. Each line within the block comment will be space trimmed and |
| 56 | + // written to build.opt, skipping blank lines and lines starting with '//', '*' |
| 57 | + // or '#'. |
| 58 | +
|
| 59 | + * this line is ignored |
| 60 | + # this line is ignored |
| 61 | + -DMYTITLE1="\"Running on \"" |
| 62 | + -O3 |
| 63 | + //-fanalyzer |
| 64 | + -DUMM_STATS_FULL=1 |
| 65 | + */ |
| 66 | +
|
| 67 | + #ifndef LOWWATERMARK_INO_GLOBALS_H |
| 68 | + #define LOWWATERMARK_INO_GLOBALS_H |
| 69 | +
|
| 70 | + #if !defined(__ASSEMBLER__) |
| 71 | + // Defines kept away from assembler modules |
| 72 | + // i.e. Defines for .cpp, .ino, .c ... modules |
| 73 | + #endif |
| 74 | +
|
| 75 | + #if defined(__cplusplus) |
| 76 | + // Defines kept private to .cpp and .ino modules |
| 77 | + //#pragma message("__cplusplus has been seen") |
| 78 | + #define MYTITLE2 "Empty" |
| 79 | + #endif |
| 80 | +
|
| 81 | + #if !defined(__cplusplus) && !defined(__ASSEMBLER__) |
| 82 | + // Defines kept private to .c modules |
| 83 | + #define MYTITLE2 "Full" |
| 84 | + #endif |
| 85 | +
|
| 86 | + #if defined(__ASSEMBLER__) |
| 87 | + // Defines kept private to assembler modules |
| 88 | + #endif |
| 89 | +
|
| 90 | + #endif |
| 91 | +
|
| 92 | +Aggressively cache compiled core |
| 93 | +================================ |
| 94 | + |
| 95 | +This feature appeared with the release of Arduino IDE 1.8.2. The feature |
| 96 | +“Aggressively Cache Compiled core” refers to sharing a single copy of |
| 97 | +``core.a`` across all Arduino IDE Sketch windows. This feature is on by |
| 98 | +default. ``core.a`` is an archive file containing the compiled objects |
| 99 | +of ``./core/esp8266/*``. Created after your 1ST successful compilation. |
| 100 | +All other open sketch builds use this shared file. When you close all |
| 101 | +Arduino IDE windows, the core archive file is deleted. |
| 102 | + |
| 103 | +This feature is not compatible with using global defines or compiler |
| 104 | +command-line options. Without mediation, bad builds could result, when |
| 105 | +left enabled. When ``#define`` changes require rebuilding ``core.a`` and |
| 106 | +multiple Sketches are open, they can no longer reliably share one cached |
| 107 | +``core.a``. In a simple case: The 1st Sketch to be built has its version |
| 108 | +of ``core.a`` cached. Other sketches will use this cached version for |
| 109 | +their builds. |
| 110 | + |
| 111 | +There are two solutions to this issue: 1. Turn off the “Aggressively |
| 112 | +Cache Compiled core” feature, by setting ``compiler.cache_core=false``. |
| 113 | +2. Rely on the not ideal fail-safe, aggressive cache workaround built |
| 114 | +into the script. |
| 115 | + |
| 116 | +Using “compiler.cache_core=false” |
| 117 | +--------------------------------- |
| 118 | + |
| 119 | +There are two ways to turn off the “Aggressively Cache Compiled core” |
| 120 | +feature: This can be done with the Arduino IDE command-line or a text |
| 121 | +editor. |
| 122 | + |
| 123 | +Using the Arduino IDE command-line from a system command line, enter the |
| 124 | +following: |
| 125 | + |
| 126 | +:: |
| 127 | + |
| 128 | + arduino --pref compiler.cache_core=false --save-prefs |
| 129 | + |
| 130 | +For the text editor, you need to find the location of |
| 131 | +``preferences.txt``. From the Arduino IDE, go to *File->Preferences*. |
| 132 | +Make note of the path to ``prefereces.txt``. You *cannot* edit the file |
| 133 | +while the Arduino IDE is running. Close all Arduino IDE windows and edit |
| 134 | +the file ``preferences.txt``. Change ``compiler.cache_core=true`` to |
| 135 | +``compiler.cache_core=false`` and save. Then each sketch will maintain |
| 136 | +its *own* copy of ``core.a`` built with the customization expressed by |
| 137 | +their respective ``build.opt`` file. |
| 138 | + |
| 139 | +The “workaround” |
| 140 | +---------------- |
| 141 | + |
| 142 | +When the “Aggressively Cache Compiled core” feature is enabled and the |
| 143 | +global define file is detected, a workaround will turn on and stay on. |
| 144 | +When you switch between Sketch windows, core will be recompiled and the |
| 145 | +cache updated. The workaround logic is reset when Arduino IDE is |
| 146 | +completely shutdown and restarted. |
| 147 | + |
| 148 | +The workaround is not perfect. These issues may be of concern: 1. Dirty |
| 149 | +temp space. Arduino build cache files left over from a previous run or |
| 150 | +boot. 2. Arduino command-line options: \* override default |
| 151 | +preferences.txt file. \* override a preference, specifically |
| 152 | +``compiler.cache_core``. 3. Multiple versions of the Arduino IDE running |
| 153 | + |
| 154 | +**Dirty temp space** |
| 155 | + |
| 156 | +A minor concern, the workaround is always on. Not an issue for build |
| 157 | +accuracy, but ``core.a`` maybe rebuild more often than necessary. |
| 158 | + |
| 159 | +Some operating systems are better at cleaning up their temp space than |
| 160 | +others at reboot after a crash. At least for Windows®, you may need to |
| 161 | +manually delete the Arduino temp files and directories after a crash. |
| 162 | +Otherwise, the workaround logic may be left on. There is no harm in the |
| 163 | +workaround being stuck on, the build will be correct; however, the core |
| 164 | +files will occasionally be recompiled when not needed. |
| 165 | + |
| 166 | +For some Windows® systems the temp directory can be found near |
| 167 | +``C:\Users\<user id>\AppData\Local\Temp\arduino*``. Note ``AppData`` is |
| 168 | +a hidden directory. For help with this do an Internet search on |
| 169 | +``windows disk cleanup``. Or, type ``disk cleanup`` in the Windows® |
| 170 | +taskbar search box. |
| 171 | + |
| 172 | +With Linux, this problem could occur after an Arduino IDE crash. The |
| 173 | +problem would be cleared after a reboot. Or you can manually cleanup the |
| 174 | +``/tmp/`` directory before restarting the Arduino IDE. |
| 175 | + |
| 176 | +**Arduino command-line option overrides** |
| 177 | + |
| 178 | +The script needs to know the working value of ``compiler.cache_core`` |
| 179 | +that the Arduino IDE uses when building. This script can learn the state |
| 180 | +through documented locations; however, the Arduino IDE has two |
| 181 | +command-line options that can alter the results the Arduino IDE uses |
| 182 | +internally. And, the Arduino IDE does not provide a means for a script |
| 183 | +to learn the override value. |
| 184 | + |
| 185 | +These two command-line options are the problem: |
| 186 | + |
| 187 | +:: |
| 188 | + |
| 189 | + ./arduino --preferences-file other-preferences.txt |
| 190 | + ./arduino --pref compiler.cache_core=false |
| 191 | + |
| 192 | +Hints for discovering the value of ``compiler.cache_core``, can be |
| 193 | +provided by specifying ``mkbuildoptglobals.extra_flags=...`` in |
| 194 | +``platform.local.txt``. |
| 195 | + |
| 196 | +Examples of hints: |
| 197 | + |
| 198 | +:: |
| 199 | + |
| 200 | + mkbuildoptglobals.extra_flags=--preferences_sketch # assume file preferences.txt in the sketch folder |
| 201 | + mkbuildoptglobals.extra_flags=--preferences_sketch "pref.txt" # is relative to the sketch folder |
| 202 | + mkbuildoptglobals.extra_flags=--no_cache_core |
| 203 | + mkbuildoptglobals.extra_flags=--cache_core |
| 204 | + mkbuildoptglobals.extra_flags=--preferences_file "other-preferences.txt" # relative to IDE or full path |
| 205 | + |
| 206 | +If required, remember to quote file or file paths. |
| 207 | + |
| 208 | +**Multiple versions of the Arduino IDE running** |
| 209 | + |
| 210 | +You can run multiple Arduino IDE windows as long as you run one version |
| 211 | +of the Arduino IDE at a time. When testing different versions, |
| 212 | +completely exit one before starting the next version. For example, |
| 213 | +Arduino IDE 1.8.19 and Arduino IDE 2.0 work with different temp and |
| 214 | +build paths. With this combination, the workaround logic sometimes fails |
| 215 | +to enable. |
| 216 | + |
| 217 | +At the time of this writing, when Arduino IDE 2.0 rc5 exits, it leaves |
| 218 | +the temp space dirty. This keeps the workaround active the next time the |
| 219 | +IDE is started. If this is an issue, manually delete the temp files. |
| 220 | + |
| 221 | +Custom build environments |
| 222 | +========================= |
| 223 | + |
| 224 | +Some custom build environments may have already addressed this issue by |
| 225 | +other means. If you have a custom build environment that does not |
| 226 | +require this feature and would like to turn it off, you can add the |
| 227 | +following lines to the ``platform.local.txt`` used in your build |
| 228 | +environment: |
| 229 | + |
| 230 | +:: |
| 231 | + |
| 232 | + recipe.hooks.prebuild.2.pattern= |
| 233 | + build.opt.flags= |
| 234 | + |
| 235 | +Other build confusion |
| 236 | +===================== |
| 237 | + |
| 238 | +1. Renaming a file does not change the last modified timestamp, possibly |
| 239 | + causing issues when adding a file by renaming and rebuilding. A good |
| 240 | + example of this problem would be to have then fixed a typo in file |
| 241 | + name ``LowWatermark.ino.globals.h``. You need to touch (update |
| 242 | + timestamp) the file so a “rebuild all” is performed. |
| 243 | + |
| 244 | +2. When a ``.h`` file is renamed in the sketch folder, a copy of the old |
| 245 | + file remains in the build sketch folder. This can create confusion if |
| 246 | + you missed an edit in updating an ``#include`` in one or more of your |
| 247 | + modules. That module will continue to use the stale version of the |
| 248 | + ``.h`` until you restart the IDE or other major changes that would |
| 249 | + cause the IDE to delete and recopy the contents from the source |
| 250 | + Sketch directory. Changes on the IDE Tools board settings may cause a |
| 251 | + complete rebuild, clearing the problem. This may be the culprit for |
| 252 | + “What! It built fine last night!” |
0 commit comments