Skip to content

Limit recursive sketch compilation to the src directory #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,22 @@
package builder

import (
"arduino.cc/builder/gohasissues"
"arduino.cc/builder/i18n"
"arduino.cc/builder/types"
"arduino.cc/builder/utils"
"io/ioutil"
"os"
"path/filepath"
"strings"
)

type CollectAllSourceFilesFromFoldersWithSources struct{}

func (s *CollectAllSourceFilesFromFoldersWithSources) Run(ctx *types.Context) error {
foldersWithSources := ctx.FoldersWithSourceFiles
sourceFiles := ctx.CollectedSourceFiles
extensions := func(ext string) bool { return ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext] }

filePaths := []string{}
for !foldersWithSources.Empty() {
sourceFolder := foldersWithSources.Pop().(types.SourceFolder)
var err error
if sourceFolder.Recurse {
err = collectByWalk(&filePaths, sourceFolder.Folder)
} else {
err = collectByReadDir(&filePaths, sourceFolder.Folder)
}
err := utils.FindFilesInFolder(&filePaths, sourceFolder.Folder, extensions, sourceFolder.Recurse)
if err != nil {
return i18n.WrapError(err)
}
Expand All @@ -66,32 +57,3 @@ func (s *CollectAllSourceFilesFromFoldersWithSources) Run(ctx *types.Context) er

return nil
}

func collectByWalk(filePaths *[]string, folder string) error {
checkExtensionFunc := func(filePath string) bool {
name := filepath.Base(filePath)
ext := strings.ToLower(filepath.Ext(filePath))
return !strings.HasPrefix(name, ".") && ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext]
}
walkFunc := utils.CollectAllReadableFiles(filePaths, checkExtensionFunc)
err := gohasissues.Walk(folder, walkFunc)
return i18n.WrapError(err)
}

func collectByReadDir(filePaths *[]string, folder string) error {
if _, err := os.Stat(folder); err != nil && os.IsNotExist(err) {
return nil
}

files, err := ioutil.ReadDir(folder)
if err != nil {
return i18n.WrapError(err)
}
for _, file := range files {
ext := strings.ToLower(filepath.Ext(file.Name()))
if ADDITIONAL_FILE_VALID_EXTENSIONS_NO_HEADERS[ext] {
*filePaths = append(*filePaths, filepath.Join(folder, file.Name()))
}
}
return nil
}
1 change: 1 addition & 0 deletions src/arduino.cc/builder/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ const RECIPE_S_PATTERN = "recipe.S.o.pattern"
const REWRITING_DISABLED = "disabled"
const REWRITING = "rewriting"
const SPACE = " "
const SKETCH_FOLDER_SRC = "src"
const TOOL_NAME = "name"
const TOOL_URL = "url"
const TOOL_VERSION = "version"
14 changes: 13 additions & 1 deletion src/arduino.cc/builder/phases/sketch_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ import (
"arduino.cc/builder/i18n"
"arduino.cc/builder/types"
"arduino.cc/builder/utils"
"arduino.cc/builder/constants"
"path/filepath"
"os"
)

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

var objectFiles []string
objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, true, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, verbose, warningsLevel, logger)
if err != nil {
return i18n.WrapError(err)
}

// The "src/" subdirectory of a sketch is compiled recursively
sketchSrcPath := filepath.Join(sketchBuildPath, constants.SKETCH_FOLDER_SRC)
if info, err := os.Stat(sketchSrcPath); err == nil && info.IsDir() {
objectFiles, err = builder_utils.CompileFiles(objectFiles, sketchSrcPath, true, sketchSrcPath, buildProperties, includes, verbose, warningsLevel, logger)
if err != nil {
return i18n.WrapError(err)
}
}

ctx.SketchObjectFiles = objectFiles

return nil
Expand Down
21 changes: 14 additions & 7 deletions src/arduino.cc/builder/sketch_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ package builder

import (
"arduino.cc/builder/constants"
"arduino.cc/builder/gohasissues"
"arduino.cc/builder/i18n"
"arduino.cc/builder/types"
"arduino.cc/builder/utils"
Expand Down Expand Up @@ -89,13 +88,21 @@ func (s *SketchLoader) Run(ctx *types.Context) error {

func collectAllSketchFiles(from string) ([]string, error) {
filePaths := []string{}
checkExtensionFunc := func(filePath string) bool {
name := filepath.Base(filePath)
ext := strings.ToLower(filepath.Ext(filePath))
return !strings.HasPrefix(name, ".") && MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext]
// Source files in the root are compiled, non-recursively. This
// is the only place where .ino files can be present.
rootExtensions := func(ext string) bool { return MAIN_FILE_VALID_EXTENSIONS[ext] || ADDITIONAL_FILE_VALID_EXTENSIONS[ext] }
err := utils.FindFilesInFolder(&filePaths, from, rootExtensions, /* recurse */ false)
if err != nil {
return nil, i18n.WrapError(err)
}

// The "src/" subdirectory of a sketch is compiled recursively
// (but .ino files are *not* compiled)
srcPath := filepath.Join(from, constants.SKETCH_FOLDER_SRC)
if info, err := os.Stat(srcPath); err == nil && info.IsDir() {
srcExtensions := func(ext string) bool { return ADDITIONAL_FILE_VALID_EXTENSIONS[ext] }
err = utils.FindFilesInFolder(&filePaths, srcPath, srcExtensions, /* recurse */ true)
}
walkFunc := utils.CollectAllReadableFiles(&filePaths, checkExtensionFunc)
err := gohasissues.Walk(from, walkFunc)
return filePaths, i18n.WrapError(err)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ func TestCopyOtherFiles(t *testing.T) {
sort.Sort(ByFileInfoName(files))
require.Equal(t, "header.h", files[0].Name())
require.Equal(t, "s_file.S", files[1].Name())
require.Equal(t, "subfolder", files[2].Name())
require.Equal(t, "src", files[2].Name())

files, err1 = gohasissues.ReadDir(filepath.Join(buildPath, constants.FOLDER_SKETCH, "subfolder"))
files, err1 = gohasissues.ReadDir(filepath.Join(buildPath, constants.FOLDER_SKETCH, "src"))
NoError(t, err1)
require.Equal(t, 1, len(files))
require.Equal(t, "helper.h", files[0].Name())
Expand Down
29 changes: 29 additions & 0 deletions src/arduino.cc/builder/test/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,32 @@ func TestBuilderSketchBuildPathContainsUnusedPreviouslyCompiledLibrary(t *testin
_, err = os.Stat(filepath.Join(buildPath, constants.FOLDER_LIBRARIES, "Bridge"))
NoError(t, err)
}

func TestBuilderWithBuildPathInSketchDir(t *testing.T) {
DownloadCoresAndToolsAndLibraries(t)

ctx := &types.Context{
HardwareFolders: []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"},
ToolsFolders: []string{"downloaded_tools"},
BuiltInLibrariesFolders: []string{"downloaded_libraries"},
OtherLibrariesFolders: []string{"libraries"},
SketchLocation: filepath.Join("sketch1", "sketch.ino"),
FQBN: "arduino:avr:uno",
ArduinoAPIVersion: "10600",
Verbose: true,
}

var err error
ctx.BuildPath, err = filepath.Abs(filepath.Join("sketch1", "build"))
NoError(t, err)
defer os.RemoveAll(ctx.BuildPath)

command := builder.Builder{}
err = command.Run(ctx)
NoError(t, err)

// Run build twice, to verify the build still works when the
// build directory is present at the start
err = command.Run(ctx)
NoError(t, err)
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func TestCollectAllSourceFilesFromFoldersWithSources(t *testing.T) {
require.Equal(t, 0, len(*foldersWithSources))
sort.Strings(*sourceFiles)

require.Equal(t, Abs(t, filepath.Join("sketch_with_config", "includes", "de bug.cpp")), sourceFiles.Pop())
require.Equal(t, Abs(t, filepath.Join("sketch_with_config", "src", "includes", "de bug.cpp")), sourceFiles.Pop())
require.Equal(t, 0, len(*sourceFiles))
}

Expand Down Expand Up @@ -106,7 +106,6 @@ func TestCollectAllSourceFilesFromFoldersWithSourcesOfOldLibrary(t *testing.T) {
foldersWithSources := &types.UniqueSourceFolderQueue{}
foldersWithSources.Push(types.SourceFolder{Folder: Abs(t, filepath.Join("libraries", "ShouldNotRecurseWithOldLibs")), Recurse: false})
foldersWithSources.Push(types.SourceFolder{Folder: Abs(t, filepath.Join("libraries", "ShouldNotRecurseWithOldLibs", "utility")), Recurse: false})
foldersWithSources.Push(types.SourceFolder{Folder: Abs(t, "non existent folder"), Recurse: false})
ctx.FoldersWithSourceFiles = foldersWithSources

commands := []types.Command{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "config.h"

#ifdef DEBUG
#include "includes/de bug.h"
#include "src/includes/de bug.h"
#endif

#ifdef UNDEF
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "config.h"

#ifdef DEBUG
#include "includes/de bug.h"
#include "src/includes/de bug.h"
#endif

#ifdef UNDEF
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "subfolder/other.h"
#include "src/subfolder/other.h"

MyClass myClass;

Expand All @@ -7,4 +7,4 @@ void setup() {
}

void loop() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#error "Whattya looking at?"
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#error "Whattya looking at?"
5 changes: 4 additions & 1 deletion src/arduino.cc/builder/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"arduino.cc/builder/props"
"path/filepath"
"strconv"
"os"
)

type SketchFile struct {
Expand Down Expand Up @@ -201,7 +202,9 @@ func LibraryToSourceFolder(library *Library) []SourceFolder {
sourceFolders = append(sourceFolders, SourceFolder{Folder: library.SrcFolder, Recurse: recurse})
if library.Layout == LIBRARY_FLAT {
utility := filepath.Join(library.SrcFolder, constants.LIBRARY_FOLDER_UTILITY)
sourceFolders = append(sourceFolders, SourceFolder{Folder: utility, Recurse: false})
if info, err := os.Stat(utility); err == nil && info.IsDir() {
sourceFolders = append(sourceFolders, SourceFolder{Folder: utility, Recurse: false})
}
}
return sourceFolders
}
Expand Down
34 changes: 26 additions & 8 deletions src/arduino.cc/builder/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,30 +304,48 @@ func FilterOutFoldersByNames(folders []os.FileInfo, names ...string) []os.FileIn
return filtered
}

type CheckFilePathFunc func(filePath string) bool
type CheckExtensionFunc func(ext string) bool

func CollectAllReadableFiles(collector *[]string, test CheckFilePathFunc) filepath.WalkFunc {
walkFunc := func(currentPath string, info os.FileInfo, err error) error {
func FindFilesInFolder(files *[]string, folder string, extensions CheckExtensionFunc, recurse bool) error {
walkFunc := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
// Skip source control and hidden files and directories
if IsSCCSOrHiddenFile(info) {
if info.IsDir() {
return filepath.SkipDir
}
return nil
}
if !test(currentPath) {

// Skip directories unless recurse is on, or this is the
// root directory
if info.IsDir() {
if recurse || path == folder {
return nil
} else {
return filepath.SkipDir
}
}

// Check (lowercased) extension against list of extensions
if extensions != nil && !extensions(strings.ToLower(filepath.Ext(path))) {
return nil
}
currentFile, err := os.Open(currentPath)

// See if the file is readable by opening it
currentFile, err := os.Open(path)
if err != nil {
return nil
}
currentFile.Close()

*collector = append(*collector, currentPath)
*files = append(*files, path)
return nil
}
return walkFunc
return gohasissues.Walk(folder, walkFunc)
}

func AppendIfNotPresent(target []string, elements ...string) []string {
Expand Down