Skip to content
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

Build fail on Docker without GCC #18779

Merged
merged 11 commits into from
Jul 26, 2020
31 changes: 24 additions & 7 deletions buildroot/share/PlatformIO/scripts/common-features-dependencies.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,11 @@
* Used by common-features-dependencies.py
*/

#ifndef __MARLIN_FIRMWARE__
#define __MARLIN_FIRMWARE__
#endif

//
// Prefix header to acquire configurations
//
#include <stdint.h>

// Include platform headers
//#include "../../../../Marlin/src/HAL/platforms.h"

#include "../../../../Marlin/src/core/boards.h"
#include "../../../../Marlin/src/core/macros.h"
#include "../../../../Marlin/Configuration.h"
Expand All @@ -44,7 +40,28 @@

#include "../../../../Marlin/src/inc/Conditionals_LCD.h"

#ifdef HAL_PATH
#include HAL_PATH(../../../../Marlin/src/HAL, inc/Conditionals_LCD.h)
#endif

#include "../../../../Marlin/src/core/drivers.h"
#include "../../../../Marlin/Configuration_adv.h"

#include "../../../../Marlin/src/inc/Conditionals_adv.h"

#ifdef HAL_PATH
#include HAL_PATH(../../../../Marlin/src/HAL, inc/Conditionals_adv.h)
#endif

//#include "../../../../Marlin/src/pins/pins.h"

#ifdef HAL_PATH
#include HAL_PATH(../../../../Marlin/src/HAL, timers.h)
#include HAL_PATH(../../../../Marlin/src/HAL, spi_pins.h)
#endif

#include "../../../../Marlin/src/inc/Conditionals_post.h"

#ifdef HAL_PATH
#include HAL_PATH(../../../../Marlin/src/HAL, inc/Conditionals_post.h)
#endif
99 changes: 64 additions & 35 deletions buildroot/share/PlatformIO/scripts/common-features-dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,8 @@ def load_config():
parts = dep.split('=')
name = parts.pop(0)
rest = '='.join(parts)
if name == 'extra_scripts':
FEATURE_DEPENDENCIES[ukey]['extra_scripts'] = rest
elif name == 'src_filter':
FEATURE_DEPENDENCIES[ukey]['src_filter'] = rest
elif name == 'lib_ignore':
FEATURE_DEPENDENCIES[ukey]['lib_ignore'] = rest
if name in ['extra_scripts', 'src_filter', 'lib_ignore']:
FEATURE_DEPENDENCIES[ukey][name] = rest
else:
FEATURE_DEPENDENCIES[ukey]['lib_deps'] += [dep]

Expand All @@ -57,15 +53,14 @@ def get_all_env_libs():
env_libs.append(name)
return env_libs

# We need to ignore all non-used libs,
# so if a lib folder lay forgotten in .pio/lib_deps, it
# will not break compiling
# All unused libs should be ignored so that if a library
# exists in .pio/lib_deps it will not break compilation.
def force_ignore_unused_libs():
env_libs = get_all_env_libs()
known_libs = get_all_known_libs()
diff = (list(set(known_libs) - set(env_libs)))
lib_ignore = env.GetProjectOption("lib_ignore") + diff
print("Ignoring libs: ", lib_ignore)
print("Ignoring libs:", lib_ignore)
proj = env.GetProjectConfig()
proj.set("env:" + env["PIOENV"], "lib_ignore", lib_ignore)

Expand All @@ -84,23 +79,23 @@ def install_features_dependencies():
name, _, _ = PackageManager.parse_pkg_uri(dep)
deps_to_add[name] = dep

# first check if the env already have the dep
# Does the env already have the dependency?
deps = env.GetProjectOption("lib_deps")
for dep in deps:
name, _, _ = PackageManager.parse_pkg_uri(dep)
if name in deps_to_add:
del deps_to_add[name]

# check if we need ignore any lib
# Are there any libraries that should be ignored?
lib_ignore = env.GetProjectOption("lib_ignore")
for dep in deps:
name, _, _ = PackageManager.parse_pkg_uri(dep)
if name in deps_to_add:
del deps_to_add[name]

# any left?
# Is there anything left?
if len(deps_to_add) > 0:
# add only the missing deps
# Only add the missing dependencies
proj = env.GetProjectConfig()
proj.set("env:" + env["PIOENV"], "lib_deps", deps + list(deps_to_add.values()))

Expand Down Expand Up @@ -129,45 +124,72 @@ def install_features_dependencies():
proj = env.GetProjectConfig()
proj.set("env:" + env["PIOENV"], "lib_ignore", lib_ignore)

# search the current compiler, considering the OS
#
# Find a compiler, considering the OS
#
ENV_BUILD_PATH = os.path.join(env.Dictionary("PROJECT_BUILD_DIR"), env["PIOENV"])
GCC_PATH_CACHE = os.path.join(ENV_BUILD_PATH, ".gcc_path")
def search_compiler():
if os.path.exists(GCC_PATH_CACHE):
print('Getting g++ path from cache')
with open(GCC_PATH_CACHE, 'r') as f:
return f.read()

# PlatformIO inserts the toolchain bin folder on the front of the $PATH
# Find the current platform compiler by searching the $PATH
if env['PLATFORM'] == 'win32':
# the first path have the compiler
for path in env['ENV']['PATH'].split(';'):
if not re.search(r'platformio\\packages.*\\bin', path):
continue
#print(path)
for file in os.listdir(path):
if file.endswith("g++.exe"):
return file
print("Could not find the g++")
return None
path_separator = ';'
path_regex = r'platformio\\packages.*\\bin'
gcc = "g++.exe"
else:
return env.get('CXX')
path_separator = ':'
path_regex = r'platformio/packages.*/bin'
gcc = "g++"

# Search for the compiler
for path in env['ENV']['PATH'].split(path_separator):
if not re.search(path_regex, path):
continue
for file in os.listdir(path):
if not file.endswith(gcc):
continue

# Cache the g++ path to no search always
if os.path.exists(ENV_BUILD_PATH):
print('Caching g++ for current env')
with open(GCC_PATH_CACHE, 'w+') as f:
f.write(file)

return file

file = env.get('CXX')
print("Couldn't find a compiler! Fallback to", file)
return file

# load marlin features
#
# Use the compiler to get a list of all enabled features
#
def load_marlin_features():
if "MARLIN_FEATURES" in env:
return

# procces defines
# print(env.Dump())
# Process defines
#print(env.Dump())
build_flags = env.get('BUILD_FLAGS')
build_flags = env.ParseFlagsExtended(build_flags)

cxx = search_compiler()
cmd = [cxx]

# build flags from board.json
# if 'BOARD' in env:
# cmd += [env.BoardConfig().get("build.extra_flags")]
# Build flags from board.json
#if 'BOARD' in env:
# cmd += [env.BoardConfig().get("build.extra_flags")]
for s in build_flags['CPPDEFINES']:
if isinstance(s, tuple):
cmd += ['-D' + s[0] + '=' + str(s[1])]
else:
cmd += ['-D' + s]
# cmd += ['-w -dM -E -x c++ Marlin/src/inc/MarlinConfigPre.h']

cmd += ['-w -dM -E -x c++ buildroot/share/PlatformIO/scripts/common-features-dependencies.h']
cmd = ' '.join(cmd)
print(cmd)
Expand All @@ -179,15 +201,22 @@ def load_marlin_features():
marlin_features[feature] = definition
env["MARLIN_FEATURES"] = marlin_features

#
# Return True if a matching feature is enabled
#
def MarlinFeatureIsEnabled(env, feature):
load_marlin_features()
r = re.compile(feature)
matches = list(filter(r.match, env["MARLIN_FEATURES"]))
return len(matches) > 0

# add a method for others scripts to check if a feature is enabled
#
# Add a method for other PIO scripts to query enabled features
#
env.AddMethod(MarlinFeatureIsEnabled)

# install all dependencies for features enabled in Configuration.h
#
# Add dependencies for enabled Marlin features
#
install_features_dependencies()
force_ignore_unused_libs()