diff --git a/arduino/libraries/librariesresolver/cpp.go b/arduino/libraries/librariesresolver/cpp.go index 63da69f2772..4afbd399169 100644 --- a/arduino/libraries/librariesresolver/cpp.go +++ b/arduino/libraries/librariesresolver/cpp.go @@ -212,7 +212,8 @@ func ComputePriority(lib *libraries.Library, header, arch string) int { case libraries.User: priority += 3 case libraries.Unmanaged: - priority += 4 + // Bonus for libraries specified via --libraries flags, those libraries gets the highest priority + priority += 10000 default: panic(fmt.Sprintf("Invalid library location: %d", lib.Location)) } diff --git a/docs/sketch-build-process.md b/docs/sketch-build-process.md index a533f631fb5..2f1486eff79 100644 --- a/docs/sketch-build-process.md +++ b/docs/sketch-build-process.md @@ -52,6 +52,8 @@ generated for the path to each library dependency and appended to the If multiple libraries contain a file that matches the `#include` directive, the priority is determined by applying the following rules, one by one in this order, until a rule determines a winner: +1. A library that has been specified using the [`--library` option](commands/arduino-cli_compile.md#options) of + `arduino-cli compile` wins against a library in other locations 1. A library that is architecture compatible wins against a library that is not architecture compatible (see [**Architecture Matching**](#architecture-matching)) 1. A library with both [library name](#library-name-priority) and [folder name](#folder-name-priority) matching the @@ -120,8 +122,6 @@ The "folder name priority" is determined as follows (in order of highest to lowe The "location priority" is determined as follows (in order of highest to lowest priority): -1. The library is specified using the [`--library` option](commands/arduino-cli_compile.md#options) of - `arduino-cli compile` 1. The library is under a custom libraries path specified via the [`--libraries` option](commands/arduino-cli_compile.md#options) of `arduino-cli compile` (in decreasing order of priority when multiple custom paths are defined) diff --git a/internal/integrationtest/compile_3/lib_selection_test.go b/internal/integrationtest/compile_3/lib_selection_test.go new file mode 100644 index 00000000000..a999384d583 --- /dev/null +++ b/internal/integrationtest/compile_3/lib_selection_test.go @@ -0,0 +1,68 @@ +// This file is part of arduino-cli. +// +// Copyright 2022 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-cli. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package compile_test + +import ( + "testing" + + "github.com/arduino/arduino-cli/internal/integrationtest" + "github.com/arduino/go-paths-helper" + "github.com/stretchr/testify/require" + "go.bug.st/testifyjson/requirejson" +) + +func TestCompileLibrarySelection(t *testing.T) { + // See: https://github.com/arduino/arduino-cli/issues/2106 + + env, cli := integrationtest.CreateArduinoCLIWithEnvironment(t) + defer env.CleanUp() + + // Run update-index with our test index + _, _, err := cli.Run("core", "install", "arduino:avr@1.8.5") + require.NoError(t, err) + + // Prepare sketchbook and sketch + sketchBook, err := paths.New("testdata", "sketchbook_for_testing_lib_priorities").Abs() + require.NoError(t, err) + vars := cli.GetDefaultEnv() + vars["ARDUINO_DIRECTORIES_USER"] = sketchBook.String() + + sketch := sketchBook.Join("SketchUsingLibraryA") + anotherLib := sketchBook.Join("libraries", "AnotherLibrary") + + // Perform two compile: + // - the first should use LibraryA + stdout, _, err := cli.RunWithCustomEnv(vars, "compile", "-b", "arduino:avr:mega", "--format", "json", sketch.String()) + require.NoError(t, err) + requirejson.Contains(t, stdout, `{ + "builder_result" : { + "used_libraries" : [ + { "name": "LibraryA" } + ] + } + }`) + + // - the second should use AnotherLibrary (because it was forced by --library) + stdout, _, err = cli.RunWithCustomEnv(vars, "compile", "-b", "arduino:avr:mega", "--library", anotherLib.String(), "--format", "json", sketch.String()) + require.NoError(t, err) + requirejson.Contains(t, stdout, `{ + "builder_result" : { + "used_libraries" : [ + { "name": "AnotherLibrary" } + ] + } + }`) +} diff --git a/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/SketchUsingLibraryA/SketchUsingLibraryA.ino b/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/SketchUsingLibraryA/SketchUsingLibraryA.ino new file mode 100644 index 00000000000..1b9965c7c15 --- /dev/null +++ b/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/SketchUsingLibraryA/SketchUsingLibraryA.ino @@ -0,0 +1,3 @@ +#include +void setup() {} +void loop() {} \ No newline at end of file diff --git a/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/libraries/AnotherLibrary/LibraryA.h b/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/libraries/AnotherLibrary/LibraryA.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/libraries/LibraryA/LibraryA.h b/internal/integrationtest/compile_3/testdata/sketchbook_for_testing_lib_priorities/libraries/LibraryA/LibraryA.h new file mode 100644 index 00000000000..e69de29bb2d