Files
platformio-core/platformio/builder/tools/piointegration.py
T

195 lines
6.2 KiB
Python
Raw Normal View History

# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
#
# 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.
2021-03-17 21:08:06 +02:00
import glob
2019-11-15 16:02:15 +02:00
import os
import SCons.Defaults # pylint: disable=import-error
import SCons.Subst # pylint: disable=import-error
2022-05-26 22:29:51 +03:00
from SCons.Script import COMMAND_LINE_TARGETS # pylint: disable=import-error
2019-05-27 22:25:22 +03:00
from platformio.proc import exec_command, where_is_program
2022-05-26 22:29:51 +03:00
def IsIntegrationDump(_):
return set(["__idedata", "idedata"]) & set(COMMAND_LINE_TARGETS)
2022-05-26 22:29:51 +03:00
def DumpIntegrationIncludes(env):
result = dict(build=[], compatlib=[], toolchain=[])
result["build"].extend(
[
env.subst("$PROJECT_INCLUDE_DIR"),
env.subst("$PROJECT_SRC_DIR"),
]
)
result["build"].extend(
[os.path.abspath(env.subst(item)) for item in env.get("CPPPATH", [])]
)
# installed libs
for lb in env.GetLibBuilders():
result["compatlib"].extend(
[os.path.abspath(inc) for inc in lb.get_include_dirs()]
)
# includes from toolchains
p = env.PioPlatform()
2022-03-23 17:56:15 +02:00
for pkg in p.get_installed_packages(with_optional=False):
2020-08-15 23:11:01 +03:00
if p.get_package_type(pkg.metadata.name) != "toolchain":
continue
2021-03-17 21:08:06 +02:00
toolchain_dir = glob.escape(pkg.path)
toolchain_incglobs = [
2019-11-15 16:02:15 +02:00
os.path.join(toolchain_dir, "*", "include", "c++", "*"),
os.path.join(toolchain_dir, "*", "include", "c++", "*", "*-*-*"),
os.path.join(toolchain_dir, "lib", "gcc", "*", "*", "include*"),
2020-04-26 00:10:41 +03:00
os.path.join(toolchain_dir, "*", "include*"),
]
for g in toolchain_incglobs:
result["toolchain"].extend([os.path.abspath(inc) for inc in glob.glob(g)])
return result
2022-05-26 22:29:51 +03:00
def get_gcc_defines(env):
2017-12-13 00:59:51 +02:00
items = []
try:
2019-11-15 16:02:15 +02:00
sysenv = os.environ.copy()
2019-09-23 23:13:48 +03:00
sysenv["PATH"] = str(env["ENV"]["PATH"])
result = exec_command(
"echo | %s -dM -E -" % env.subst("$CC"), env=sysenv, shell=True
)
2017-12-13 00:59:51 +02:00
except OSError:
return items
2019-09-23 23:13:48 +03:00
if result["returncode"] != 0:
2017-12-13 00:59:51 +02:00
return items
2019-09-23 23:13:48 +03:00
for line in result["out"].split("\n"):
2017-12-13 00:59:51 +02:00
tokens = line.strip().split(" ", 2)
if not tokens or tokens[0] != "#define":
continue
if len(tokens) > 2:
items.append("%s=%s" % (tokens[1], tokens[2]))
else:
items.append(tokens[1])
return items
2022-05-26 22:29:51 +03:00
def dump_defines(env):
defines = []
# global symbols
for item in SCons.Defaults.processDefines(env.get("CPPDEFINES", [])):
item = item.strip()
if item:
defines.append(env.subst(item).replace('\\"', '"'))
# special symbol for Atmel AVR MCU
2019-09-23 23:13:48 +03:00
if env["PIOPLATFORM"] == "atmelavr":
board_mcu = env.get("BOARD_MCU")
if not board_mcu and "BOARD" in env:
board_mcu = env.BoardConfig().get("build.mcu")
if board_mcu:
defines.append(
2019-09-23 23:13:48 +03:00
str(
"__AVR_%s__"
% board_mcu.upper()
.replace("ATMEGA", "ATmega")
.replace("ATTINY", "ATtiny")
)
)
2017-12-13 00:59:51 +02:00
# built-in GCC marcos
2018-04-20 13:56:04 +03:00
# if env.GetCompilerType() == "gcc":
2022-05-26 22:29:51 +03:00
# defines.extend(get_gcc_defines(env))
2017-12-13 00:59:51 +02:00
return defines
2022-05-26 22:29:51 +03:00
def dump_svd_path(env):
svd_path = env.GetProjectOption("debug_svd_path")
2018-05-02 12:37:51 +03:00
if svd_path:
return os.path.abspath(svd_path)
2018-04-27 20:37:41 +03:00
if "BOARD" not in env:
return None
try:
svd_path = env.BoardConfig().get("debug.svd_path")
2018-04-30 12:33:19 +03:00
assert svd_path
except (AssertionError, KeyError):
2018-04-27 20:37:41 +03:00
return None
2018-04-30 12:33:19 +03:00
# custom path to SVD file
2019-11-15 16:02:15 +02:00
if os.path.isfile(svd_path):
2018-04-30 12:33:19 +03:00
return svd_path
# default file from ./platform/misc/svd folder
p = env.PioPlatform()
2019-11-15 16:02:15 +02:00
if os.path.isfile(os.path.join(p.get_dir(), "misc", "svd", svd_path)):
return os.path.abspath(os.path.join(p.get_dir(), "misc", "svd", svd_path))
2018-04-30 12:33:19 +03:00
return None
2018-04-27 20:37:41 +03:00
def _subst_cmd(env, cmd):
args = env.subst_list(cmd, SCons.Subst.SUBST_CMD)[0]
return " ".join([SCons.Subst.quote_spaces(arg) for arg in args])
def DumpIntegrationData(*args):
projenv, globalenv = args[0:2] # pylint: disable=unbalanced-tuple-unpacking
data = {
"build_type": globalenv.GetBuildType(),
"env_name": globalenv["PIOENV"],
"libsource_dirs": [
globalenv.subst(item) for item in globalenv.GetLibSourceDirs()
],
"defines": dump_defines(projenv),
"includes": projenv.DumpIntegrationIncludes(),
"cc_flags": _subst_cmd(projenv, "$CFLAGS $CCFLAGS $CPPFLAGS"),
"cxx_flags": _subst_cmd(projenv, "$CXXFLAGS $CCFLAGS $CPPFLAGS"),
"cc_path": where_is_program(
globalenv.subst("$CC"), globalenv.subst("${ENV['PATH']}")
),
"cxx_path": where_is_program(
globalenv.subst("$CXX"), globalenv.subst("${ENV['PATH']}")
),
"gdb_path": where_is_program(
globalenv.subst("$GDB"), globalenv.subst("${ENV['PATH']}")
),
2022-07-30 12:16:32 +03:00
"prog_path": globalenv.subst("$PROGPATH"),
"svd_path": dump_svd_path(globalenv),
"compiler_type": globalenv.GetCompilerType(),
2020-06-09 18:43:50 +03:00
"targets": globalenv.DumpTargets(),
2020-10-26 18:23:28 +02:00
"extra": dict(
flash_images=[
{"offset": item[0], "path": globalenv.subst(item[1])}
for item in globalenv.get("FLASH_EXTRA_IMAGES", [])
2020-10-26 18:23:28 +02:00
]
),
}
for key in ("IDE_EXTRA_DATA", "INTEGRATION_EXTRA_DATA"):
data["extra"].update(globalenv.get(key, {}))
return data
def exists(_):
return True
def generate(env):
env["IDE_EXTRA_DATA"] = {} # legacy support
env["INTEGRATION_EXTRA_DATA"] = {}
2022-05-26 22:29:51 +03:00
env.AddMethod(IsIntegrationDump)
env.AddMethod(DumpIntegrationIncludes)
env.AddMethod(DumpIntegrationData)
return env