diff --git a/arduino/globals/globals.go b/arduino/globals/globals.go index 97e0b75e958..b00f82c227a 100644 --- a/arduino/globals/globals.go +++ b/arduino/globals/globals.go @@ -35,6 +35,8 @@ var ( ".hpp": empty, ".hh": empty, ".cpp": empty, + ".cxx": empty, + ".cc": empty, ".S": empty, ".adoc": empty, ".md": empty, @@ -43,11 +45,15 @@ var ( ".ipp": empty, } - // SourceFilesValidExtensions lists valid extensions for source files (no headers) - SourceFilesValidExtensions = map[string]struct{}{ - ".c": empty, - ".cpp": empty, - ".S": empty, + // SourceFilesValidExtensions lists valid extensions for source files (no headers). + // If a platform do not provide a compile recipe for a specific file extension, this + // map provides the equivalent extension to use as a fallback. + SourceFilesValidExtensions = map[string]string{ + ".c": "", + ".cpp": "", + ".cxx": ".cpp", + ".cc": ".cpp", + ".S": "", } // HeaderFilesValidExtensions lists valid extensions for header files diff --git a/docs/platform-specification.md b/docs/platform-specification.md index 5f26ac779b9..59031916c84 100644 --- a/docs/platform-specification.md +++ b/docs/platform-specification.md @@ -172,12 +172,15 @@ These properties can be overwritten respectively with `--keys-keychain`, `--sign #### Recipes to compile source code We said that the Arduino development software determines a list of files to compile. Each file can be source code -written in C (.c files), C++ (.cpp files) or Assembly (.S files). Every language is compiled using its respective -**recipe**: +written in C (.c files), C++ (.cpp/.cxx/.cc files) or Assembly (.S files). Every language is compiled using its +respective **recipe**: -- `recipe.c.o.pattern`: for C files -- `recipe.cpp.o.pattern`: for CPP files -- `recipe.S.o.pattern`: for Assembly files +- `recipe.c.o.pattern`: for C files (.c) +- `recipe.cpp.o.pattern`: for CPP files (.cpp/.cxx/.cc) +- `recipe.S.o.pattern`: for Assembly files (.S) + +(an optional `recipe.cxx.o.pattern` and `recipe.cc.o.pattern` may be provided, if `.cxx` or `.cc` needs special +handling, but it's not required and we do not recommend it) The recipes can be built concatenating the following automatically generated properties (for each file compiled): diff --git a/internal/integrationtest/compile_3/compile_cxx_cc_test.go b/internal/integrationtest/compile_3/compile_cxx_cc_test.go new file mode 100644 index 00000000000..0dc90dcf9ad --- /dev/null +++ b/internal/integrationtest/compile_3/compile_cxx_cc_test.go @@ -0,0 +1,42 @@ +// 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" +) + +func TestCompileSketchWithCxxOrCc(t *testing.T) { + // See: https://github.com/arduino/arduino-cli/issues/1149 + + 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 + sketch, err := paths.New("testdata", "sketch_with_cxx_cc").Abs() + require.NoError(t, err) + + _, _, err = cli.Run("compile", "-v", "-b", "arduino:avr:uno", sketch.String()) + require.NoError(t, err) +} diff --git a/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/sketch_with_cxx_cc.ino b/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/sketch_with_cxx_cc.ino new file mode 100644 index 00000000000..84301becc0c --- /dev/null +++ b/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/sketch_with_cxx_cc.ino @@ -0,0 +1,11 @@ +void func_in_cc(); +void func_in_cxx(); + +void setup() { + func_in_cc(); + func_in_cxx(); +} + +void loop() { + +} \ No newline at end of file diff --git a/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/test.cc b/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/test.cc new file mode 100644 index 00000000000..0065ea50fc1 --- /dev/null +++ b/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/test.cc @@ -0,0 +1,3 @@ +void func_in_cc() { + +} \ No newline at end of file diff --git a/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/test.cxx b/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/test.cxx new file mode 100644 index 00000000000..916dbe31ef9 --- /dev/null +++ b/internal/integrationtest/compile_3/testdata/sketch_with_cxx_cc/test.cxx @@ -0,0 +1,3 @@ +void func_in_cxx() { + +} \ No newline at end of file diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 5c25d2c86c0..e7b0d56fe41 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -109,6 +109,9 @@ func compileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buil queue := make(chan *paths.Path) job := func(source *paths.Path) { recipe := fmt.Sprintf("recipe%s.o.pattern", source.Ext()) + if !buildProperties.ContainsKey(recipe) { + recipe = fmt.Sprintf("recipe%s.o.pattern", globals.SourceFilesValidExtensions[source.Ext()]) + } objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe) if err != nil { errorsMux.Lock()