# 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.

Contents

- Compatibility

- Infrastructure

- What is new

  - “platformio.ini” (Project Configuration File)

    - Global scope `[env]`

    - External Configuration Files

    - New Options

  - Library Management

  - Build System

    - Package Dependencies

    - Custom Platform Packages

    - Custom Upload Command

    - Shared Cache Directory

- What is changed or removed

  - Command Line Interface

  - “platformio.ini” (Project Configuration File)

## 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