2018-07-30 18:23:41 +03:00
|
|
|
# Copyright 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.
|
|
|
|
|
|
2019-10-18 18:19:53 +03:00
|
|
|
import shutil
|
2019-10-21 17:06:00 +03:00
|
|
|
from os import SEEK_CUR, SEEK_END
|
2025-09-17 00:09:47 +02:00
|
|
|
from os.path import basename, isfile
|
|
|
|
|
from pathlib import Path
|
2018-07-09 22:47:38 +03:00
|
|
|
|
|
|
|
|
from SCons.Script import Builder
|
|
|
|
|
|
|
|
|
|
Import("env")
|
|
|
|
|
|
2019-10-28 15:28:29 +02:00
|
|
|
board = env.BoardConfig()
|
2025-09-17 00:09:47 +02:00
|
|
|
mcu = board.get("build.mcu", "esp32")
|
|
|
|
|
is_xtensa = mcu in ("esp32", "esp32s2", "esp32s3")
|
|
|
|
|
|
|
|
|
|
cmake_dir = str(env.PioPlatform().get_package_dir("tool-cmake"))
|
|
|
|
|
cmake_cmd = f'"{Path(cmake_dir) / "bin" / "cmake"}"'
|
|
|
|
|
|
|
|
|
|
idf_dir = str(env.PioPlatform().get_package_dir("framework-espidf"))
|
|
|
|
|
data_embed_script = (
|
|
|
|
|
f'"{Path(idf_dir) / "tools" / "cmake" / "scripts" / "data_file_embed_asm.cmake"}"'
|
|
|
|
|
)
|
2019-10-21 17:06:00 +03:00
|
|
|
|
2018-07-09 22:47:38 +03:00
|
|
|
#
|
2019-10-18 18:19:53 +03:00
|
|
|
# Embedded files helpers
|
2018-07-09 22:47:38 +03:00
|
|
|
#
|
|
|
|
|
|
2020-03-05 11:18:07 +02:00
|
|
|
|
2019-10-18 18:19:53 +03:00
|
|
|
def extract_files(cppdefines, files_type):
|
2021-08-16 16:31:41 +03:00
|
|
|
result = []
|
|
|
|
|
files = env.GetProjectOption("board_build.%s" % files_type, "").splitlines()
|
|
|
|
|
if files:
|
2025-09-17 00:09:47 +02:00
|
|
|
result.extend([str(Path("$PROJECT_DIR") / f.strip()) for f in files if f.strip()])
|
2019-10-28 15:28:29 +02:00
|
|
|
else:
|
|
|
|
|
files_define = "COMPONENT_" + files_type.upper()
|
|
|
|
|
for define in cppdefines:
|
|
|
|
|
if files_define not in define:
|
|
|
|
|
continue
|
2018-07-09 22:47:38 +03:00
|
|
|
|
|
|
|
|
value = define[1]
|
2019-10-28 15:28:29 +02:00
|
|
|
if not isinstance(define, tuple):
|
|
|
|
|
print("Warning! %s macro cannot be empty!" % files_define)
|
|
|
|
|
return []
|
|
|
|
|
|
2018-07-09 22:47:38 +03:00
|
|
|
if not isinstance(value, str):
|
2020-03-05 11:18:07 +02:00
|
|
|
print(
|
|
|
|
|
"Warning! %s macro must contain "
|
|
|
|
|
"a list of files separated by ':'" % files_define
|
|
|
|
|
)
|
2018-07-09 22:47:38 +03:00
|
|
|
return []
|
|
|
|
|
|
2020-03-05 11:18:07 +02:00
|
|
|
for f in value.split(":"):
|
2025-09-17 00:09:47 +02:00
|
|
|
f = f.strip()
|
2019-10-28 15:28:29 +02:00
|
|
|
if not f:
|
2018-07-09 22:47:38 +03:00
|
|
|
continue
|
2025-09-17 00:09:47 +02:00
|
|
|
result.append(str(Path("$PROJECT_DIR") / f))
|
2018-07-09 22:47:38 +03:00
|
|
|
|
2021-08-16 16:31:41 +03:00
|
|
|
for f in result:
|
2019-10-28 15:28:29 +02:00
|
|
|
if not isfile(env.subst(f)):
|
2020-03-05 11:18:07 +02:00
|
|
|
print('Warning! Could not find file "%s"' % basename(f))
|
2019-10-28 15:28:29 +02:00
|
|
|
|
2021-08-16 16:31:41 +03:00
|
|
|
return result
|
2018-07-09 22:47:38 +03:00
|
|
|
|
|
|
|
|
|
2019-10-18 18:19:53 +03:00
|
|
|
def remove_config_define(cppdefines, files_type):
|
2018-07-09 22:47:38 +03:00
|
|
|
for define in cppdefines:
|
2019-10-18 18:19:53 +03:00
|
|
|
if files_type in define:
|
2018-07-09 22:47:38 +03:00
|
|
|
env.ProcessUnFlags("-D%s" % "=".join(str(d) for d in define))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
|
2019-10-21 17:06:00 +03:00
|
|
|
def prepare_file(source, target, env):
|
|
|
|
|
filepath = source[0].get_abspath()
|
|
|
|
|
shutil.copy(filepath, filepath + ".piobkp")
|
|
|
|
|
|
|
|
|
|
with open(filepath, "rb+") as fp:
|
2025-09-17 00:09:47 +02:00
|
|
|
fp.seek(0, SEEK_END)
|
|
|
|
|
size = fp.tell()
|
|
|
|
|
if size == 0:
|
2020-03-05 11:18:07 +02:00
|
|
|
fp.write(b"\0")
|
2025-09-17 00:09:47 +02:00
|
|
|
else:
|
|
|
|
|
fp.seek(-1, SEEK_END)
|
|
|
|
|
if fp.read(1) != b"\0":
|
|
|
|
|
fp.write(b"\0")
|
2019-10-21 17:06:00 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def revert_original_file(source, target, env):
|
|
|
|
|
filepath = source[0].get_abspath()
|
|
|
|
|
if isfile(filepath + ".piobkp"):
|
|
|
|
|
shutil.move(filepath + ".piobkp", filepath)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def embed_files(files, files_type):
|
2018-07-09 22:47:38 +03:00
|
|
|
for f in files:
|
|
|
|
|
filename = basename(f) + ".txt.o"
|
2025-09-17 00:09:47 +02:00
|
|
|
file_target = env.TxtToBin(str(Path("$BUILD_DIR") / filename), f)
|
2018-07-09 22:47:38 +03:00
|
|
|
env.Depends("$PIOMAINPROG", file_target)
|
2019-10-28 15:28:29 +02:00
|
|
|
if files_type == "embed_txtfiles":
|
2019-10-21 17:06:00 +03:00
|
|
|
env.AddPreAction(file_target, prepare_file)
|
|
|
|
|
env.AddPostAction(file_target, revert_original_file)
|
2025-09-17 00:09:47 +02:00
|
|
|
env.AppendUnique(PIOBUILDFILES=[env.File(str(Path("$BUILD_DIR") / filename))])
|
2018-07-09 22:47:38 +03:00
|
|
|
|
|
|
|
|
|
2020-03-05 11:18:07 +02:00
|
|
|
def transform_to_asm(target, source, env):
|
2025-09-17 00:09:47 +02:00
|
|
|
asm_targets = [str(Path("$BUILD_DIR") / (s.name + ".S")) for s in source]
|
|
|
|
|
return asm_targets, source
|
2021-01-21 13:42:23 +02:00
|
|
|
|
2025-09-17 00:09:47 +02:00
|
|
|
|
2018-07-09 22:47:38 +03:00
|
|
|
env.Append(
|
|
|
|
|
BUILDERS=dict(
|
|
|
|
|
TxtToBin=Builder(
|
2020-03-05 11:18:07 +02:00
|
|
|
action=env.VerboseAction(
|
|
|
|
|
" ".join(
|
|
|
|
|
[
|
2022-04-18 16:27:17 +02:00
|
|
|
"riscv32-esp-elf-objcopy"
|
2025-09-17 00:09:47 +02:00
|
|
|
if not is_xtensa
|
|
|
|
|
else f"xtensa-{mcu}-elf-objcopy",
|
2020-03-05 11:18:07 +02:00
|
|
|
"--input-target",
|
|
|
|
|
"binary",
|
|
|
|
|
"--output-target",
|
2025-09-17 00:09:47 +02:00
|
|
|
"elf32-littleriscv" if not is_xtensa else "elf32-xtensa-le",
|
2020-03-05 11:18:07 +02:00
|
|
|
"--binary-architecture",
|
2025-09-17 00:09:47 +02:00
|
|
|
"riscv" if not is_xtensa else "xtensa",
|
2020-03-05 11:18:07 +02:00
|
|
|
"--rename-section",
|
|
|
|
|
".data=.rodata.embedded",
|
|
|
|
|
"$SOURCE",
|
|
|
|
|
"$TARGET",
|
|
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
"Converting $TARGET",
|
|
|
|
|
),
|
|
|
|
|
suffix=".txt.o",
|
|
|
|
|
),
|
2021-11-05 16:13:39 +02:00
|
|
|
FileToAsm=Builder(
|
2020-03-05 11:18:07 +02:00
|
|
|
action=env.VerboseAction(
|
|
|
|
|
" ".join(
|
|
|
|
|
[
|
2025-09-17 00:09:47 +02:00
|
|
|
cmake_cmd,
|
2020-03-05 11:18:07 +02:00
|
|
|
"-DDATA_FILE=$SOURCE",
|
|
|
|
|
"-DSOURCE_FILE=$TARGET",
|
2021-11-05 16:13:39 +02:00
|
|
|
"-DFILE_TYPE=$FILE_TYPE",
|
2020-03-05 11:18:07 +02:00
|
|
|
"-P",
|
2025-09-17 00:09:47 +02:00
|
|
|
data_embed_script,
|
2020-03-05 11:18:07 +02:00
|
|
|
]
|
|
|
|
|
),
|
|
|
|
|
"Generating assembly for $TARGET",
|
|
|
|
|
),
|
|
|
|
|
emitter=transform_to_asm,
|
2021-01-21 13:42:23 +02:00
|
|
|
single_source=True,
|
2020-03-05 11:18:07 +02:00
|
|
|
),
|
|
|
|
|
)
|
2018-07-09 22:47:38 +03:00
|
|
|
)
|
|
|
|
|
|
2020-03-05 11:18:07 +02:00
|
|
|
|
2018-07-09 22:47:38 +03:00
|
|
|
flags = env.get("CPPDEFINES")
|
2019-10-28 15:28:29 +02:00
|
|
|
for files_type in ("embed_txtfiles", "embed_files"):
|
2020-03-05 11:18:07 +02:00
|
|
|
if (
|
|
|
|
|
"COMPONENT_" + files_type.upper() not in env.Flatten(flags)
|
|
|
|
|
and "build." + files_type not in board
|
|
|
|
|
):
|
2019-10-18 18:19:53 +03:00
|
|
|
continue
|
2019-10-28 15:28:29 +02:00
|
|
|
|
2019-10-21 17:06:00 +03:00
|
|
|
files = extract_files(flags, files_type)
|
2020-03-05 11:18:07 +02:00
|
|
|
if "espidf" in env.subst("$PIOFRAMEWORK"):
|
2021-11-05 16:13:39 +02:00
|
|
|
env.Requires(
|
2025-09-17 00:09:47 +02:00
|
|
|
str(Path("$BUILD_DIR") / "${PROGNAME}.elf"),
|
2021-11-05 16:13:39 +02:00
|
|
|
env.FileToAsm(
|
|
|
|
|
files,
|
|
|
|
|
FILE_TYPE="TEXT" if files_type == "embed_txtfiles" else "BINARY",
|
|
|
|
|
),
|
|
|
|
|
)
|
2020-03-05 11:18:07 +02:00
|
|
|
else:
|
|
|
|
|
embed_files(files, files_type)
|
|
|
|
|
remove_config_define(flags, files_type)
|