Migrating from 3.x to 4.0

Guidance on how to upgrade from PlatformIO Core (CLI) v3.x to v4.x with emphasis on major changes, what is new, and what has been removed.

Please read PlatformIO 4.0 Release Notes before.

Compatibility

PlatformIO Core 4.0 is fully backward compatible with v3.x. The only major change is a new location for project build artifacts and library dependencies. The previous .pioenvs (build_dir) and .piolibdeps (libdeps_dir) folders were moved to a new workspace_dir.

Note

If you manually added library dependencies to old .piolibdeps folder, please declare them in lib_deps. We do not recommend modifying any files or folders in workspace_dir. This is an internal location for PlatformIO Core artifacts and temporary files. PlatformIO Core 4.0 may delete/cleanup this folder in a service purpose any time.

Infrastructure

Finally, Python 3 interpreter is officially supported! The minimum requirements are Python 2.7 or Python 3.5+.

We also added full support for operating system locales other than UTF-8. So, your project path can contain non-ASCII/non-Latin chars now.

If you are Development Platforms maintainer or you need to show a progress bar (upload progress, connecting status…), PlatformIO Core 4.0 has re-factored target runner where line-buffering was totally removed. Just print any progress information in real time and PlatformIO Core will display it instantly on user the side. For example, a writing progress from Atmel AVR “avrdude” programmer:

...
Looking for upload port...
Auto-detected: /dev/cu.usbmodemFA141
Uploading build/uno/firmware.hex

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "build/uno/firmware.hex"
avrdude: writing flash (930 bytes):

Writing | ##########################

What is new

In this section, we are going to highlight the most important changes and features introduced in PlatformIO Core (CLI) 4.0. Please visit PlatformIO 4.0 Release Notes for more detailed information.

“platformio.ini” (Project Configuration File)

A project configuration parser was rewritten from scratch. It has strict options typing (API) and helps to avoid issues when option values are invalid (for example, invalid Dependency Finder Mode or non-existing debug_svd_path).

Global scope [env]

One of the most requested features was a “global” or “common” project environment (Section [env]) where developers can share common configuration between all declared build environments [env:NAME].

The previous solution in PlatformIO Core 3.0 was using Dynamic variables. As practice has shown, this approach was not good and more advanced “platformio.ini” (Project Configuration File) looked so complicated and hard for managing (for example, open source projects MarlinFirmware, Espurna).

PlatformIO Core 4.0 introduces a new global scope named [env] which allows declaring global options that will be shared between all [env:NAME] sections in “platformio.ini” (Project Configuration File). For example,

[env]
platform = ststm32
framework = stm32cube
board = nucleo_l152re
lib_deps = Dep1, Dep2

[env:release]
build_flags = -D RELEASE
lib_deps =
    ${env.lib_deps}
    Dep3

[env:debug]
build_type = debug
build_flags = -D DEBUG
lib_deps = DepCustom

In this example we have 2 build environments release and debug. This is the same if you duplicate all options (PlatformIO Core 3.0 compatible):

[env:release]
platform = ststm32
framework = stm32cube
board = nucleo_l152re
build_flags = -D RELEASE
lib_deps = Dep1, Dep2, Dep3

[env:debug]
platform = ststm32
framework = stm32cube
board = nucleo_l152re
build_type = debug
build_flags = -D DEBUG
lib_deps = DepCustom

External Configuration Files

To simplify the project configuration process, PlatformIO Core 4.0 adds support for external “platformio.ini” (Project Configuration File). Yes! You can finally extend one configuration file with another or with a list of them. The cool feature is a support for Unix shell-style wildcards. So, you can dynamically generate “platformio.ini” (Project Configuration File) files or load bunch of them from a folder. See extra_configs option for details and a simple example below:

Base “platformio.ini”

[platformio]
extra_configs =
  extra_envs.ini
  extra_debug.ini

[common]
debug_flags = -D RELEASE
lib_flags = -lc -lm

[env:esp-wrover-kit]
platform = espressif32
framework = espidf
board = esp-wrover-kit
build_flags = ${common.debug_flags}

“extra_envs.ini”

[env:esp32dev]
platform = espressif32
framework = espidf
board = esp32dev
build_flags = ${common.lib_flags} ${common.debug_flags}

[env:lolin32]
platform = espressif32
framework = espidf
board = lolin32
build_flags = ${common.debug_flags}

“extra_debug.ini”

# Override base "common.debug_flags"
[common]
debug_flags = -D DEBUG=1

[env:lolin32]
build_flags = -Og

After a parsing process, configuration state will be the next:

[common]
debug_flags = -D DEBUG=1
lib_flags = -lc -lm

[env:esp-wrover-kit]
platform = espressif32
framework = espidf
board = esp-wrover-kit
build_flags = ${common.debug_flags}

[env:esp32dev]
platform = espressif32
framework = espidf
board = esp32dev
build_flags = ${common.lib_flags} ${common.debug_flags}

[env:lolin32]
platform = espressif32
framework = espidf
board = lolin32
build_flags = -Og

New Options

We have added new options and changed some existing ones. Here are the new or updated options.

Section

Option

Description

platformio

extra_configs

Extend base configuration with external “platformio.ini” (Project Configuration File)

platformio

core_dir

Directory where PlatformIO stores development platform packages (toolchains, frameworks, SDKs, upload and debug tools), global libraries for Library Dependency Finder (LDF), and other PlatformIO Core service data

platformio

globallib_dir

Global library storage for PlatfrmIO projects and Library Manager where Library Dependency Finder (LDF) looks for dependencies

platformio

platforms_dir

Global storage where PlatformIO Package Manager installs Development Platforms

platformio

packages_dir

Global storage where PlatformIO Package Manager installs Development Platforms dependencies (toolchains, Frameworks, SDKs, upload and debug tools)

platformio

cache_dir

PlatformIO Core (CLI) uses this folder to store caching information (requests to PlatformIO Registry, downloaded packages and other service information)

platformio

workspace_dir

A path to a project workspace directory where PlatformIO keeps by default compiled objects, static libraries, firmwares, and external library dependencies

platformio

shared_dir

PIO Remote uses this folder to synchronize extra files between remote machine

env

build_type

See extended documentation for Build Configurations

env

monitor_flags

Pass extra flags and options to platformio device monitor command

env

upload_command

Override default Development Platforms upload command with a custom one.

Library Management

Library management brings a few new changes which resolve historical issues presented in PlatformIO 3.0:

  1. .piolibdeps folder was moved to libdeps_dir of project workspace.

    If you manually added library dependencies to old .piolibdeps folder, please declare them in lib_deps. We do not recommend modifying any files or folders in workspace_dir. This is an internal location for PlatformIO Core artifacts and temporary files. PlatformIO Core 4.0 may delete/cleanup this folder in a service purpose any time.

  2. Library Dependency Finder (LDF) now uses isolated library dependency storage per project build environment. It resolves conflicts when the libraries from different build environments declared via lib_deps option were installed into the same .piolibdeps folder.

See Library Management section in PlatformIO Core 4 release notes for more details.

Build System

PlatformIO Core 4.0 uses a new build_dir instead of .pioenvs for compiled objects, archived libraries, firmware binaries and, other artifacts. A new build_type option allows you to control a build process between “Release” and “Debug” modes (see Build Configurations).

See Build System section in PlatformIO Core 4 release notes for more details.

Package Dependencies

PlatformIO has decentralized architecture and allows platform maintainers to create Custom Development Platforms for PlatformIO ecosystem. Each development platform depends on a list of packages (toolchains, SDKs, debugging servers, etc). PlatformIO Package Manager installs these packages automatically and PlatformIO Build System uses them later.

Starting from PlatformIO Core 4.0, developers can see which versions of a development platform or its dependent packages will be used. This is a great addition to track changes (Frameworks, SDKs) between Development Platforms updates. See an example with “staging” (Git) version of Espressif 8266 development platform:

Processing nodemcuv2 (platform: https://github.com/platformio/platform-espressif8266.git#feature/stage; board: nodemcuv2; framework: arduino)
-------------------------------------------------------------------------------
Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/espressif8266/nodemcuv2.html
PLATFORM: Espressif 8266 (Stage) 2.3.0-alpha.1 #990141d > NodeMCU 1.0 (ESP-12E Module)
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES: toolchain-xtensa 2.40802.190218 (4.8.2), tool-esptool 1.413.0 (4.13), tool-esptoolpy 1.20600.0 (2.6.0), framework-arduinoespressif8266 78a1a66
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain+, Compatibility ~ soft
Found 35 compatible libraries
Scanning dependencies...

Custom Platform Packages

Sometimes you need to override default Development Platforms packages or add an extra. PlatformIO Core 4.0 introduces a new configuration option platform_packages per a build environment. Also, using this option you can install external packages and use them later as programmers or upload tools. See a few examples:

[env:override_default_toolchain]
platform = atmelavr
platform_packages =
  ; use GCC AVR 5.0+
  toolchain-gccarmnoneeabi@>1.50000.0

[env:override_framework]
platform = espressif8266
platform_packages =
  ; use upstream Git version
  framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git

[env:external_package]
platform = ststm32
platform_packages =
  ; latest openOCD from PlatformIO Package Registry
  tool-openocd

  ; source code of ST-Link
  tool-stlink-source @ https://github.com/texane/stlink.git

Custom Upload Command

PlatformIO’s Development Platforms have pre-configured settings to program boards or devices. They depend on a type of bootloader or programming interface. PlatformIO Core 4.0 allows you to override default upload command using upload_command option in “platformio.ini” (Project Configuration File):

[env:custom_upload_cmd]
platform = ...
framework = ...
board = ...
upload_command = /my/flasher arg1 arg2 --flag1 $SOURCE

See real examples for upload_command.

Shared Cache Directory

PlatformIO Core 4.0 allows you to configure a shared folder for the derived files (objects, firmwares, ELFs) from a build system using build_cache_dir. You can use it in multi-environments project configuration to avoid multiple compilations of the same source code files.

The example of “platformio.ini” (Project Configuration File) below instructs PlatformIO Build System to check build_cache_dir for already compiled objects for STM32Cube and project source files. The cached object will not be used if the original source file was modified or build environment has a different configuration (new build flags, etc):

[platformio]
; set a path to a cache folder
build_cache_dir = /tmp/platformio-shared-cache

[env:bluepill_f103c6]
platform = ststm32
framework = stm32cube
board = bluepill_f103c6

[env:nucleo_f411re]
platform = ststm32
framework = stm32cube
board = nucleo_f411re

You can also use the same build_cache_dir between different projects if they use the same Development Platforms and Frameworks.

What is changed or removed

Command Line Interface

The following commands have been changed in v4.0.

Command

Description

platformio run

Added platformio run --jobs option

platformio update

Replaced -c, --only-check with platformio update --dry-run

platformio lib update

Replaced -c, --only-check with platformio lib update --dry-run

platformio platform update

Replaced -c, --only-check with platformio platform update --dry-run

platformio remote update

Replaced -c, --only-check with platformio remote update --dry-run

“platformio.ini” (Project Configuration File)

The following options have been changed in v4.0.

Section

Option

Description

platformio

env_default

Renamed to default_envs

platformio

home_dir

Renamed to core_dir

env

debug_load_cmd

Renamed to debug_load_cmds and allowed to pass more than one load command