Skip to content

Commit 760499c

Browse files
committed
Append configuration settings from "mbed_lib.json" to "mbed_config.h" // Resolve #2164
1 parent 00b1626 commit 760499c

File tree

1 file changed

+94
-42
lines changed

1 file changed

+94
-42
lines changed

platformio/builder/tools/piolib.py

Lines changed: 94 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
# pylint: disable=no-member, no-self-use, unused-argument
15+
# pylint: disable=no-member, no-self-use, unused-argument, too-many-lines
1616
# pylint: disable=too-many-instance-attributes, too-many-public-methods
1717

1818
from __future__ import absolute_import
@@ -591,58 +591,110 @@ def get_include_dirs(self):
591591
def is_frameworks_compatible(self, frameworks):
592592
return util.items_in_list(frameworks, ["mbed"])
593593

594-
@property
595-
def build_flags(self):
596-
return self._mbed_lib_json_to_build_flags()
594+
def process_extra_options(self):
595+
self._process_mbed_lib_confs()
596+
return super(MbedLibBuilder, self).process_extra_options()
597597

598-
def _mbed_lib_json_to_build_flags(self): # pylint: disable=too-many-locals
599-
json_files = [
598+
def _process_mbed_lib_confs(self):
599+
mbed_lib_paths = [
600600
join(root, "mbed_lib.json")
601601
for root, _, files in os.walk(self.path)
602602
if "mbed_lib.json" in files
603603
]
604-
if not json_files:
604+
if not mbed_lib_paths:
605+
return None
606+
607+
mbed_config_path = None
608+
for p in self.env.get("CPPPATH"):
609+
mbed_config_path = join(self.env.subst(p), "mbed_config.h")
610+
if isfile(mbed_config_path):
611+
break
612+
else:
613+
mbed_config_path = None
614+
if not mbed_config_path:
605615
return None
606616

607-
build_flags = []
617+
macros = {}
618+
for mbed_lib_path in mbed_lib_paths:
619+
macros.update(self._mbed_lib_conf_parse_macros(mbed_lib_path))
620+
621+
self._mbed_conf_append_macros(mbed_config_path, macros)
622+
return True
623+
624+
@staticmethod
625+
def _mbed_normalize_macro(macro):
626+
name = macro
627+
value = None
628+
if "=" in macro:
629+
name, value = macro.split("=", 1)
630+
return dict(name=name, value=value)
631+
632+
def _mbed_lib_conf_parse_macros(self, mbed_lib_path):
633+
macros = {}
608634
cppdefines = str(self.env.Flatten(self.env.subst("$CPPDEFINES")))
609-
for p in json_files:
610-
manifest = util.load_json(p)
635+
manifest = util.load_json(mbed_lib_path)
611636

612-
# default macros
613-
build_flags.extend(["-D" + m for m in manifest.get("macros", [])])
637+
# default macros
638+
for macro in manifest.get("macros", []):
639+
macro = self._mbed_normalize_macro(macro)
640+
macros[macro['name']] = macro
614641

615-
macros = {}
616-
# configuration items
617-
for key, options in manifest.get("config", {}).items():
618-
if "value" not in options:
619-
continue
620-
macros[key] = dict(
621-
name=options.get("macro_name"), value=options.get("value"))
622-
# overrode items per target
623-
for target, options in manifest.get("target_overrides",
624-
{}).items():
625-
if target != "*" and "TARGET_" + target not in cppdefines:
642+
# configuration items
643+
for key, options in manifest.get("config", {}).items():
644+
if "value" not in options:
645+
continue
646+
macros[key] = dict(
647+
name=options.get("macro_name"), value=options.get("value"))
648+
649+
# overrode items per target
650+
for target, options in manifest.get("target_overrides", {}).items():
651+
if target != "*" and "TARGET_" + target not in cppdefines:
652+
continue
653+
for macro in options.get("target.macros_add", []):
654+
macro = self._mbed_normalize_macro(macro)
655+
macros[macro['name']] = macro
656+
for key, value in options.items():
657+
if not key.startswith("target.") and key in macros:
658+
macros[key]['value'] = value
659+
660+
# normalize macro names
661+
for key, macro in macros.items():
662+
if not macro['name']:
663+
macro['name'] = key
664+
if "." not in macro['name']:
665+
macro['name'] = "%s.%s" % (manifest.get("name"),
666+
macro['name'])
667+
macro['name'] = re.sub(
668+
r"[^a-z\d]+", "_", macro['name'], flags=re.I).upper()
669+
macro['name'] = "MBED_CONF_" + macro['name']
670+
if isinstance(macro['value'], bool):
671+
macro['value'] = 1 if macro['value'] else 0
672+
673+
return {macro["name"]: macro["value"] for macro in macros.values()}
674+
675+
def _mbed_conf_append_macros(self, mbed_config_path, macros):
676+
lines = []
677+
with open(mbed_config_path) as fp:
678+
for line in fp.readlines():
679+
line = line.strip()
680+
if line == "#endif":
681+
lines.append(
682+
"// PlatformIO Library Dependency Finder (LDF)")
683+
lines.extend([
684+
"#define %s %s" % (name,
685+
value if value is not None else "")
686+
for name, value in macros.items()
687+
])
688+
lines.append("")
689+
if not line.startswith("#define"):
690+
lines.append(line)
626691
continue
627-
build_flags.extend(
628-
["-D" + m for m in options.get("target.macros_add", [])])
629-
for key, value in options.items():
630-
if not key.startswith("target.") and key in macros:
631-
macros[key]['value'] = value
632-
for key, macro in macros.items():
633-
name = macro['name']
634-
value = macro['value']
635-
if not name:
636-
name = key
637-
if "." not in name:
638-
name = manifest.get("name") + "." + name
639-
name = re.sub(r"[^a-z\d]+", "_", name, flags=re.I).upper()
640-
name = "MBED_CONF_" + name
641-
if isinstance(value, bool):
642-
value = 1 if value else 0
643-
build_flags.append("-D%s=%s" % (name, value))
644-
645-
return build_flags
692+
tokens = line.split()
693+
if len(tokens) < 2 or tokens[1] not in macros:
694+
lines.append(line)
695+
lines.append("")
696+
with open(mbed_config_path, "w") as fp:
697+
fp.write("\n".join(lines))
646698

647699

648700
class PlatformIOLibBuilder(LibBuilderBase):

0 commit comments

Comments
 (0)