diff --git a/legacy/builder/gcc_preproc_runner.go b/legacy/builder/gcc_preproc_runner.go
index a1ddab96cd2..6ac49149fed 100644
--- a/legacy/builder/gcc_preproc_runner.go
+++ b/legacy/builder/gcc_preproc_runner.go
@@ -61,7 +61,8 @@ func prepareGCCPreprocRecipeProperties(ctx *types.Context, sourceFilePath *paths
 	properties.SetPath(constants.BUILD_PROPERTIES_SOURCE_FILE, sourceFilePath)
 	properties.SetPath(constants.BUILD_PROPERTIES_PREPROCESSED_FILE_PATH, targetFilePath)
 
-	includesStrings := utils.Map(includes.AsStrings(), utils.WrapWithHyphenI)
+    ctx.SetGlobalIncludeOption()
+	includesStrings := append(utils.Map(includes.AsStrings(), utils.WrapWithHyphenI), ctx.GlobalIncludeOption)
 	properties.Set(constants.BUILD_PROPERTIES_INCLUDES, strings.Join(includesStrings, constants.SPACE))
 
 	if properties.Get(constants.RECIPE_PREPROC_MACROS) == "" {
diff --git a/legacy/builder/phases/libraries_builder.go b/legacy/builder/phases/libraries_builder.go
index a5253f76303..67705d07c91 100644
--- a/legacy/builder/phases/libraries_builder.go
+++ b/legacy/builder/phases/libraries_builder.go
@@ -37,7 +37,8 @@ type LibrariesBuilder struct{}
 func (s *LibrariesBuilder) Run(ctx *types.Context) error {
 	librariesBuildPath := ctx.LibrariesBuildPath
 	buildProperties := ctx.BuildProperties
-	includes := utils.Map(ctx.IncludeFolders.AsStrings(), utils.WrapWithHyphenI)
+	ctx.SetGlobalIncludeOption()
+    includes := append(utils.Map(ctx.IncludeFolders.AsStrings(), utils.WrapWithHyphenI), ctx.GlobalIncludeOption)
 	libs := ctx.ImportedLibraries
 
 	if err := librariesBuildPath.MkdirAll(); err != nil {
diff --git a/legacy/builder/phases/sketch_builder.go b/legacy/builder/phases/sketch_builder.go
index 8fea0f129c0..c982dec4be4 100644
--- a/legacy/builder/phases/sketch_builder.go
+++ b/legacy/builder/phases/sketch_builder.go
@@ -27,8 +27,8 @@ type SketchBuilder struct{}
 func (s *SketchBuilder) Run(ctx *types.Context) error {
 	sketchBuildPath := ctx.SketchBuildPath
 	buildProperties := ctx.BuildProperties
-	includes := utils.Map(ctx.IncludeFolders.AsStrings(), utils.WrapWithHyphenI)
-
+	ctx.SetGlobalIncludeOption()
+    includes := append(utils.Map(ctx.IncludeFolders.AsStrings(), utils.WrapWithHyphenI), ctx.GlobalIncludeOption)
 	if err := sketchBuildPath.MkdirAll(); err != nil {
 		return errors.WithStack(err)
 	}
diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go
index a3f8ee98626..d1ff306e2d7 100644
--- a/legacy/builder/types/context.go
+++ b/legacy/builder/types/context.go
@@ -16,6 +16,7 @@
 package types
 
 import (
+    "os"
 	"io"
 	"strings"
 
@@ -27,6 +28,7 @@ import (
 	"github.com/arduino/arduino-cli/arduino/libraries/librariesresolver"
 	"github.com/arduino/arduino-cli/arduino/sketch"
 	"github.com/arduino/arduino-cli/legacy/builder/i18n"
+    "github.com/arduino/arduino-cli/legacy/builder/constants"
 	rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
 	paths "github.com/arduino/go-paths-helper"
 	properties "github.com/arduino/go-properties-orderedmap"
@@ -177,6 +179,9 @@ type Context struct {
 	// The provided source data is used instead of reading it from disk.
 	// The keys of the map are paths relative to sketch folder.
 	SourceOverride map[string]string
+
+    // Compiler directive for transparent inclusion of global definition when present
+	GlobalIncludeOption string
 }
 
 // ExecutableSectionSize represents a section of the executable output file
@@ -254,3 +259,23 @@ func (ctx *Context) GetLogger() i18n.Logger {
 func (ctx *Context) SetLogger(l i18n.Logger) {
 	ctx.logger = l
 }
+
+func (ctx *Context) SetGlobalIncludeOption () {
+    if len(ctx.GlobalIncludeOption) == 0 {
+
+        // testing existence of path/to/sketch/sketch_globals.h
+
+        globalsHeaderName := ctx.BuildPath.Join("sketch").Join(ctx.Sketch.Name + "_globals.h").String()
+        _, err := os.Stat(globalsHeaderName);
+
+        if os.IsNotExist(err) {
+            ctx.GetLogger().Fprintln(os.Stdout, constants.LOG_LEVEL_INFO, tr("global definition file is not present") + " '" + globalsHeaderName + "'")
+        } else {
+            ctx.GlobalIncludeOption = "-include "
+            ctx.GlobalIncludeOption += globalsHeaderName
+            ctx.GetLogger().Fprintln(os.Stdout, constants.LOG_LEVEL_INFO, tr("Using global definition file") + " '" + globalsHeaderName + "'")
+        }
+
+        ctx.GlobalIncludeOption += " "
+    }
+}
diff --git a/test/testdata/sketch_with_multiple_custom_libraries/libraries2/Lib/lib2.h b/test/testdata/sketch_with_multiple_custom_libraries/libraries2/Lib/lib2.h
index e69de29bb2d..8ddc0f50ff1 100644
--- a/test/testdata/sketch_with_multiple_custom_libraries/libraries2/Lib/lib2.h
+++ b/test/testdata/sketch_with_multiple_custom_libraries/libraries2/Lib/lib2.h
@@ -0,0 +1,6 @@
+
+#ifndef LIB2_SOME_CONFIG
+#define LIB2_SOME_CONFIG 0
+#endif
+
+#define LIB2_SOME_SIZE ((LIB2_SOME_CONFIG) * 42)
diff --git a/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries.ino b/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries.ino
index fb99d2a57ee..191e7cc8a19 100644
--- a/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries.ino
+++ b/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries.ino
@@ -1,6 +1,10 @@
 #include "lib1.h"
 #include "lib2.h"
 
+#if LIB2_SOME_SIZE != 42
+#error should be 42 per global configuration
+#endif
+
 void setup() {
 }
 
diff --git a/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries_globals.h b/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries_globals.h
new file mode 100644
index 00000000000..fc2c6a553bc
--- /dev/null
+++ b/test/testdata/sketch_with_multiple_custom_libraries/sketch_with_multiple_custom_libraries_globals.h
@@ -0,0 +1,8 @@
+
+// When it exists under the name 'sketch_globals.h' (next to 'sketch.ino'),
+// this user file is always included first during libraries and sketch compilation.
+// It allows global library configuration per sketch.
+
+#pragma once
+
+#define LIB2_SOME_CONFIG 1