Skip to content

Commit 405a24a

Browse files
Limit recursive sketch compilation to the src directory
Since c7a18f8 (Sketch sources files were recursively copied BUT not compiled), sketches were compiled recursively. However, this turned out to have some side effects, such as including files that were not intended to be compiled (included as documentation or otherwise not part uof the sketch itself) and breaking the build if the build directory is inside the sketch directory (arduino#89). To prevent these side effects, but still allow users to apply more structure to their sketches, recursive compilation is now limited to the `src` directory inside the sketch folder. All .ino files must still reside in the root folder, but any .c and .cpp files inside (subdirectories of) the `src` directory are included in the build. Using a `src` directory in this way is similar to how libraries are compiled (except for libraries *all* source files live in the `src` directory if it is present, while for sketches files can *also* live in the root directory). Sketches written to use this new `src` directory should also be backward compatible, in the sense that arduino-builder 1.0.7 (Arduino IDE 1.6.7) and later can succesfully compile it, not just the versions after this commit. The reverse is not true: sketches that need recursive compilation outside of the `src` directory, as supported by arduino-builder 1.0.7 above, will not compile after this commit, but it is trivial to convert them to do so (without breaking compilation before this commit). This also changes some testcases that used subfolders, to move these inside the `src` directory instead of directly in the sketch root directory. This fixes arduino#89. Signed-off-by: Matthijs Kooijman <[email protected]>
1 parent 2f4824e commit 405a24a

16 files changed

+67
-10
lines changed

src/arduino.cc/builder/constants/constants.go

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ const RECIPE_S_PATTERN = "recipe.S.o.pattern"
204204
const REWRITING_DISABLED = "disabled"
205205
const REWRITING = "rewriting"
206206
const SPACE = " "
207+
const SKETCH_FOLDER_SRC = "src"
207208
const TOOL_NAME = "name"
208209
const TOOL_URL = "url"
209210
const TOOL_VERSION = "version"

src/arduino.cc/builder/phases/sketch_builder.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ import (
3434
"arduino.cc/builder/i18n"
3535
"arduino.cc/builder/types"
3636
"arduino.cc/builder/utils"
37+
"arduino.cc/builder/constants"
38+
"path/filepath"
39+
"os"
3740
)
3841

3942
type SketchBuilder struct{}
@@ -53,11 +56,20 @@ func (s *SketchBuilder) Run(ctx *types.Context) error {
5356
}
5457

5558
var objectFiles []string
56-
objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, true, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
59+
objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
5760
if err != nil {
5861
return i18n.WrapError(err)
5962
}
6063

64+
// The "src/" subdirectory of a sketch is compiled recursively
65+
sketchSrcPath := filepath.Join(sketchBuildPath, constants.SKETCH_FOLDER_SRC)
66+
if info, err := os.Stat(sketchSrcPath); err == nil && info.IsDir() {
67+
objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchSrcPath, true, sketchSrcPath, buildProperties, includes, verbose, warningsLevel, logger)
68+
if err != nil {
69+
return i18n.WrapError(err)
70+
}
71+
}
72+
6173
ctx.SketchObjectFiles = objectFiles
6274

6375
return nil

src/arduino.cc/builder/sketch_loader.go

+15-2
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,21 @@ func (s *SketchLoader) Run(ctx *types.Context) error {
8888

8989
func collectAllSketchFiles(from string) ([]string, error) {
9090
filePaths := []string{}
91-
extensions := func(ext string) bool { return MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext] }
92-
err := utils.FindFilesInFolder(&filePaths, from, extensions, /* recurse */ true)
91+
// Source files in the root are compiled, non-recursively. This
92+
// is the only place where .ino files can be present.
93+
rootExtensions := func(ext string) bool { return MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext] }
94+
err := utils.FindFilesInFolder(&filePaths, from, rootExtensions, /* recurse */ false)
95+
if err != nil {
96+
return nil, i18n.WrapError(err)
97+
}
98+
99+
// The "src/" subdirectory of a sketch is compiled recursively
100+
// (but .ino files are *not* compiled)
101+
srcPath := filepath.Join(from, constants.SKETCH_FOLDER_SRC)
102+
if info, err := os.Stat(srcPath); err == nil && info.IsDir() {
103+
srcExtensions := func(ext string) bool { return ADDITIONAL_FILE_VALID_EXTENSIONS[ext] }
104+
err = utils.FindFilesInFolder(&filePaths, srcPath, srcExtensions, /* recurse */ true)
105+
}
93106
return filePaths, i18n.WrapError(err)
94107
}
95108

src/arduino.cc/builder/test/additional_sketch_files_copier_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ func TestCopyOtherFiles(t *testing.T) {
8383
sort.Sort(ByFileInfoName(files))
8484
require.Equal(t, "header.h", files[0].Name())
8585
require.Equal(t, "s_file.S", files[1].Name())
86-
require.Equal(t, "subfolder", files[2].Name())
86+
require.Equal(t, "src", files[2].Name())
8787

88-
files, err1 = gohasissues.ReadDir(filepath.Join(buildPath, constants.FOLDER_SKETCH, "subfolder"))
88+
files, err1 = gohasissues.ReadDir(filepath.Join(buildPath, constants.FOLDER_SKETCH, "src"))
8989
NoError(t, err1)
9090
require.Equal(t, 1, len(files))
9191
require.Equal(t, "helper.h", files[0].Name())

src/arduino.cc/builder/test/builder_test.go

+29
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,32 @@ func TestBuilderSketchBuildPathContainsUnusedPreviouslyCompiledLibrary(t *testin
373373
_, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_LIBRARIES, "Bridge"))
374374
NoError(t, err)
375375
}
376+
377+
func TestBuilderWithBuildPathInSketchDir(t *testing.T) {
378+
DownloadCoresAndToolsAndLibraries(t)
379+
380+
ctx := &types.Context{
381+
HardwareFolders: []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"},
382+
ToolsFolders: []string{"downloaded_tools"},
383+
BuiltInLibrariesFolders: []string{"downloaded_libraries"},
384+
OtherLibrariesFolders: []string{"libraries"},
385+
SketchLocation: filepath.Join("sketch1", "sketch.ino"),
386+
FQBN: "arduino:avr:uno",
387+
ArduinoAPIVersion: "10600",
388+
Verbose: true,
389+
}
390+
391+
var err error
392+
ctx.BuildPath, err = filepath.Abs(filepath.Join("sketch1", "build"))
393+
NoError(t, err)
394+
defer os.RemoveAll(ctx.BuildPath)
395+
396+
command := builder.Builder{}
397+
err = command.Run(ctx)
398+
NoError(t, err)
399+
400+
// Run build twice, to verify the build still works when the
401+
// build directory is present at the start
402+
err = command.Run(ctx)
403+
NoError(t, err)
404+
}

src/arduino.cc/builder/test/collect_all_source_files_from_folders_with_sources_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestCollectAllSourceFilesFromFoldersWithSources(t *testing.T) {
6060
require.Equal(t, 0, len(*foldersWithSources))
6161
sort.Strings(*sourceFiles)
6262

63-
require.Equal(t, Abs(t, filepath.Join("sketch_with_config", "includes", "de bug.cpp")), sourceFiles.Pop())
63+
require.Equal(t, Abs(t, filepath.Join("sketch_with_config", "src", "includes", "de bug.cpp")), sourceFiles.Pop())
6464
require.Equal(t, 0, len(*sourceFiles))
6565
}
6666

src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "config.h"
22

33
#ifdef DEBUG
4-
#include "includes/de bug.h"
4+
#include "src/includes/de bug.h"
55
#endif
66

77
#ifdef UNDEF

src/arduino.cc/builder/test/sketch_with_config/sketch_with_config.preprocessed.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "config.h"
55

66
#ifdef DEBUG
7-
#include "includes/de bug.h"
7+
#include "src/includes/de bug.h"
88
#endif
99

1010
#ifdef UNDEF
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "subfolder/other.h"
1+
#include "src/subfolder/other.h"
22

33
MyClass myClass;
44

@@ -7,4 +7,4 @@ void setup() {
77
}
88

99
void loop() {
10-
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#error "Whattya looking at?"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#error "Whattya looking at?"

0 commit comments

Comments
 (0)