# Copyright (c) 2014-present PlatformIO # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import sys from platformio import fs, util from platformio.proc import exec_command @util.memoized() def GetCompilerType(env): if env.subst("$CC").endswith("-gcc"): return "gcc" try: sysenv = os.environ.copy() sysenv["PATH"] = str(env["ENV"]["PATH"]) result = exec_command([env.subst("$CC"), "-v"], env=sysenv) except OSError: return None if result["returncode"] != 0: return None output = "".join([result["out"], result["err"]]).lower() if "clang" in output and "LLVM" in output: return "clang" if "gcc" in output: return "gcc" return None def GetActualLDScript(env): def _lookup_in_ldpath(script): for d in env.get("LIBPATH", []): path = os.path.join(env.subst(d), script) if os.path.isfile(path): return path return None script = None script_in_next = False for f in env.get("LINKFLAGS", []): raw_script = None if f == "-T": script_in_next = True continue if script_in_next: script_in_next = False raw_script = f elif f.startswith("-Wl,-T"): raw_script = f[6:] else: continue script = env.subst(raw_script.replace('"', "").strip()) if os.path.isfile(script): return script path = _lookup_in_ldpath(script) if path: return path if script: sys.stderr.write( "Error: Could not find '%s' LD script in LDPATH '%s'\n" % (script, env.subst("$LIBPATH")) ) env.Exit(1) if not script and "LDSCRIPT_PATH" in env: path = _lookup_in_ldpath(env["LDSCRIPT_PATH"]) if path: return path sys.stderr.write("Error: Could not find LD script\n") env.Exit(1) def ConfigureDebugTarget(env): def _cleanup_debug_flags(scope): if scope not in env: return unflags = ["-Os", "-g"] for level in [0, 1, 2, 3]: for flag in ("O", "g", "ggdb"): unflags.append("-%s%d" % (flag, level)) env[scope] = [f for f in env.get(scope, []) if f not in unflags] env.Append(CPPDEFINES=["__PLATFORMIO_BUILD_DEBUG__"]) for scope in ("ASFLAGS", "CCFLAGS", "LINKFLAGS"): _cleanup_debug_flags(scope) debug_flags = env.ParseFlags( env.get("PIODEBUGFLAGS") if env.get("PIODEBUGFLAGS") and not env.GetProjectOptions(as_dict=True).get("debug_build_flags") else env.GetProjectOption("debug_build_flags") ) env.MergeFlags(debug_flags) optimization_flags = [ f for f in debug_flags.get("CCFLAGS", []) if f.startswith(("-O", "-g")) ] if optimization_flags: env.AppendUnique( ASFLAGS=[ # skip -O flags for assembler f for f in optimization_flags if f.startswith("-g") ], LINKFLAGS=optimization_flags, ) def GetExtraScripts(env, scope): items = [] for item in env.GetProjectOption("extra_scripts", []): if scope == "post" and ":" not in item: items.append(item) elif item.startswith("%s:" % scope): items.append(item[len(scope) + 1 :]) if not items: return items with fs.cd(env.subst("$PROJECT_DIR")): return [os.path.abspath(env.subst(item)) for item in items] def generate(env): env.AddMethod(GetCompilerType) env.AddMethod(GetActualLDScript) env.AddMethod(ConfigureDebugTarget) env.AddMethod(GetExtraScripts) # bakward-compatibility with Zephyr build script env.AddMethod(ConfigureDebugTarget, "ConfigureDebugFlags") def exists(_): return True