diff --git a/arduino/libraries/librariesresolver/cpp.go b/arduino/libraries/librariesresolver/cpp.go index 94d8b82bf05..05335d7da16 100644 --- a/arduino/libraries/librariesresolver/cpp.go +++ b/arduino/libraries/librariesresolver/cpp.go @@ -20,6 +20,7 @@ import ( "path/filepath" "strings" + "github.com/arduino/arduino-cli/arduino/cores" "github.com/arduino/arduino-cli/arduino/libraries" "github.com/arduino/arduino-cli/arduino/libraries/librariesmanager" "github.com/arduino/arduino-cli/arduino/utils" @@ -53,6 +54,49 @@ func (resolver *Cpp) ScanFromLibrariesManager(lm *librariesmanager.LibrariesMana return nil } +// ScanIDEBuiltinLibraries reads ide-builtin librariers loaded in the LibrariesManager to find +// and cache all C++ headers for later retrieval. +func (resolver *Cpp) ScanIDEBuiltinLibraries(lm *librariesmanager.LibrariesManager) error { + for _, libAlternatives := range lm.Libraries { + for _, lib := range libAlternatives.Alternatives { + if lib.Location == libraries.IDEBuiltIn { + resolver.ScanLibrary(lib) + } + } + } + return nil +} + +// ScanUserAndUnmanagedLibraries reads user/unmanaged librariers loaded in the LibrariesManager to find +// and cache all C++ headers for later retrieval. +func (resolver *Cpp) ScanUserAndUnmanagedLibraries(lm *librariesmanager.LibrariesManager) error { + for _, libAlternatives := range lm.Libraries { + for _, lib := range libAlternatives.Alternatives { + if lib.Location == libraries.User || lib.Location == libraries.Unmanaged { + resolver.ScanLibrary(lib) + } + } + } + return nil +} + +// ScanPlatformLibraries reads platform-bundled libraries for a specific platform loaded in the LibrariesManager +// to find and cache all C++ headers for later retrieval. +func (resolver *Cpp) ScanPlatformLibraries(lm *librariesmanager.LibrariesManager, platform *cores.PlatformRelease) error { + for _, libAlternatives := range lm.Libraries { + for _, lib := range libAlternatives.Alternatives { + if lib.Location != libraries.PlatformBuiltIn && lib.Location != libraries.ReferencedPlatformBuiltIn { + continue + } + if lib.ContainerPlatform != platform { + continue + } + resolver.ScanLibrary(lib) + } + } + return nil +} + // ScanLibrary reads a library to find and cache C++ headers for later retrieval func (resolver *Cpp) ScanLibrary(lib *libraries.Library) error { cppHeaders, err := lib.SourceHeaders() diff --git a/docs/UPGRADING.md b/docs/UPGRADING.md index 7fdbd74c218..36ec080dd36 100644 --- a/docs/UPGRADING.md +++ b/docs/UPGRADING.md @@ -4,6 +4,15 @@ Here you can find a list of migration guides to handle breaking changes between ## 0.23.0 +### Arduino IDE builtin libraries are now excluded from the build when running `arduino-cli` standalone + +Previously the "builtin libraries" in the Arduino IDE 1.8.x were always included in the build process. This wasn't the +intended behaviour, `arduino-cli` should include them only if run as a daemon from the Arduino IDE. Now this is fixed, +but since it has been the default behaviour from a very long time we decided to report it here as a breaking change. + +If a compilation fail for a missing bundled library, you can fix it just by installing the missing library from the +library manager as usual. + ### golang API: PackageManager.DownloadPlatformRelease no longer need `label` parameter ```go diff --git a/legacy/builder/libraries_loader.go b/legacy/builder/libraries_loader.go index 4d5f0c8d5ca..abd59f77318 100644 --- a/legacy/builder/libraries_loader.go +++ b/legacy/builder/libraries_loader.go @@ -38,12 +38,10 @@ func (s *LibrariesLoader) Run(ctx *types.Context) error { lm.AddLibrariesDir(folder, libraries.IDEBuiltIn) } - actualPlatform := ctx.ActualPlatform - platform := ctx.TargetPlatform - if actualPlatform != platform { - lm.AddPlatformReleaseLibrariesDir(actualPlatform, libraries.ReferencedPlatformBuiltIn) + if ctx.ActualPlatform != ctx.TargetPlatform { + lm.AddPlatformReleaseLibrariesDir(ctx.ActualPlatform, libraries.ReferencedPlatformBuiltIn) } - lm.AddPlatformReleaseLibrariesDir(platform, libraries.PlatformBuiltIn) + lm.AddPlatformReleaseLibrariesDir(ctx.TargetPlatform, libraries.PlatformBuiltIn) librariesFolders := ctx.OtherLibrariesDirs if err := librariesFolders.ToAbs(); err != nil { @@ -72,9 +70,20 @@ func (s *LibrariesLoader) Run(ctx *types.Context) error { } resolver := librariesresolver.NewCppResolver() - if err := resolver.ScanFromLibrariesManager(ctx.LibrariesManager); err != nil { + if err := resolver.ScanIDEBuiltinLibraries(ctx.LibrariesManager); err != nil { return errors.WithStack(err) } + if err := resolver.ScanUserAndUnmanagedLibraries(ctx.LibrariesManager); err != nil { + return errors.WithStack(err) + } + if err := resolver.ScanPlatformLibraries(ctx.LibrariesManager, ctx.TargetPlatform); err != nil { + return errors.WithStack(err) + } + if ctx.ActualPlatform != ctx.TargetPlatform { + if err := resolver.ScanPlatformLibraries(ctx.LibrariesManager, ctx.ActualPlatform); err != nil { + return errors.WithStack(err) + } + } ctx.LibrariesResolver = resolver return nil diff --git a/test/test_profiles.py b/test/test_profiles.py index 0402dc00f2c..163adf734f1 100644 --- a/test/test_profiles.py +++ b/test/test_profiles.py @@ -28,3 +28,22 @@ def test_compile_with_profiles(run_command, copy_sketch): # use profile with the required library -> should succeed result = run_command(["compile", "-m", "avr2", sketch_path]) assert result.ok + + +def test_builder_did_not_catch_libs_from_unused_platforms(run_command, copy_sketch): + # Init the environment explicitly + run_command(["core", "update-index"]) + + sketch_path = copy_sketch("sketch_with_error_including_wire") + + # install two platforms with the Wire library bundled + assert run_command(["core", "install", "arduino:avr"]) + assert run_command(["core", "install", "arduino:samd"]) + + # compile for AVR + result = run_command(["compile", "-b", "arduino:avr:uno", sketch_path]) + assert result.failed + + # check that the libary resolver did not take the SAMD bundled Wire library into account + assert "samd" not in result.stdout + assert "samd" not in result.stderr diff --git a/test/testdata/sketch_with_error_including_wire/sketch_with_error_including_wire.ino b/test/testdata/sketch_with_error_including_wire/sketch_with_error_including_wire.ino new file mode 100644 index 00000000000..9d5d4a01b7e --- /dev/null +++ b/test/testdata/sketch_with_error_including_wire/sketch_with_error_including_wire.ino @@ -0,0 +1,3 @@ +#include + +this sketch has syntax errors