Skip to content

Commit 6b17183

Browse files
committed
Merge branch 'hotfix/v3.6.6'
2 parents e37d34b + 8cd35fb commit 6b17183

File tree

9 files changed

+187
-15
lines changed

9 files changed

+187
-15
lines changed

HISTORY.rst

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ Release Notes
44
PlatformIO 3.0
55
--------------
66

7+
3.6.6 (2019-03-29)
8+
~~~~~~~~~~~~~~~~~~
9+
10+
* Project Generator: fixed a warning "Property !!! WARNING !!! is not allowed" for VSCode
11+
(`issue #2243 <https://github.com/platformio/platformio-core/issues/2243>`_)
12+
* Fixed an issue when PlatformIO Build System does not pick up "mbed_lib.json" files from libraries
13+
(`issue #2164 <https://github.com/platformio/platformio-core/issues/2164>`_)
14+
* Fixed an error with conflicting declaration of a prototype (Arduino sketch preprocessor)
15+
* Fixed "FileExistsError" when `platformio ci <https://docs.platformio.org/en/latest/userguide/cmd_ci.html>`__ command is used in pair with ``--keep-build-dir`` option
16+
* Fixed an issue with incorrect order of project "include" and "src" paths in ``CPPPATH``
17+
(`issue #1914 <https://github.com/platformio/platformio-core/issues/1914>`_)
18+
719
3.6.5 (2019-03-07)
820
~~~~~~~~~~~~~~~~~~
921

platformio/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import sys
1616

17-
VERSION = (3, 6, 5)
17+
VERSION = (3, 6, 6)
1818
__version__ = ".".join([str(s) for s in VERSION])
1919

2020
__title__ = "platformio"

platformio/builder/tools/piolib.py

+115-5
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
@@ -70,6 +70,8 @@ def get_used_frameworks(env, path):
7070

7171
# check source files
7272
for root, _, files in os.walk(path, followlinks=True):
73+
if "mbed_lib.json" in files:
74+
return ["mbed"]
7375
for fname in files:
7476
if not env.IsFileWithExt(
7577
fname, piotool.SRC_BUILD_EXT + piotool.SRC_HEADER_EXT):
@@ -175,10 +177,11 @@ def src_dir(self):
175177
if isdir(join(self.path, "src")) else self.path)
176178

177179
def get_include_dirs(self):
178-
items = [self.src_dir]
180+
items = []
179181
include_dir = self.include_dir
180182
if include_dir and include_dir not in items:
181183
items.append(include_dir)
184+
items.append(self.src_dir)
182185
return items
183186

184187
@property
@@ -260,7 +263,6 @@ def load_manifest(self):
260263

261264
def process_extra_options(self):
262265
with util.cd(self.path):
263-
self.env.ProcessUnFlags(self.build_unflags)
264266
self.env.ProcessFlags(self.build_flags)
265267
if self.extra_script:
266268
self.env.SConscriptChdir(1)
@@ -270,6 +272,7 @@ def process_extra_options(self):
270272
"env": self.env,
271273
"pio_lib_builder": self
272274
})
275+
self.env.ProcessUnFlags(self.build_unflags)
273276

274277
def process_dependencies(self):
275278
if not self.dependencies:
@@ -588,6 +591,111 @@ def get_include_dirs(self):
588591
def is_frameworks_compatible(self, frameworks):
589592
return util.items_in_list(frameworks, ["mbed"])
590593

594+
def process_extra_options(self):
595+
self._process_mbed_lib_confs()
596+
return super(MbedLibBuilder, self).process_extra_options()
597+
598+
def _process_mbed_lib_confs(self):
599+
mbed_lib_paths = [
600+
join(root, "mbed_lib.json")
601+
for root, _, files in os.walk(self.path)
602+
if "mbed_lib.json" in files
603+
]
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:
615+
return None
616+
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 = {}
634+
cppdefines = str(self.env.Flatten(self.env.subst("$CPPDEFINES")))
635+
manifest = util.load_json(mbed_lib_path)
636+
637+
# default macros
638+
for macro in manifest.get("macros", []):
639+
macro = self._mbed_normalize_macro(macro)
640+
macros[macro['name']] = macro
641+
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)
691+
continue
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))
698+
591699

592700
class PlatformIOLibBuilder(LibBuilderBase):
593701

@@ -701,10 +809,11 @@ def src_dir(self):
701809
return self.env.subst("$PROJECTSRC_DIR")
702810

703811
def get_include_dirs(self):
704-
include_dirs = LibBuilderBase.get_include_dirs(self)
812+
include_dirs = []
705813
project_include_dir = self.env.subst("$PROJECTINCLUDE_DIR")
706814
if isdir(project_include_dir):
707815
include_dirs.append(project_include_dir)
816+
include_dirs.extend(LibBuilderBase.get_include_dirs(self))
708817
return include_dirs
709818

710819
def get_search_files(self):
@@ -772,8 +881,9 @@ def process_dependencies(self): # pylint: disable=too-many-branches
772881

773882
def build(self):
774883
self._is_built = True # do not build Project now
884+
result = LibBuilderBase.build(self)
775885
self.env.PrependUnique(CPPPATH=self.get_include_dirs())
776-
return LibBuilderBase.build(self)
886+
return result
777887

778888

779889
def GetLibBuilders(env): # pylint: disable=too-many-branches

platformio/builder/tools/piomisc.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ class InoToCPPConverter(object):
3333
PROTOTYPE_RE = re.compile(
3434
r"""^(
3535
(?:template\<.*\>\s*)? # template
36-
([a-z_\d\&]+\*?\s+){1,2} # return type
36+
([a-z_\d\&]+\*?\s+){1,2} # return type
3737
([a-z_\d]+\s*) # name of prototype
3838
\([a-z_,\.\*\&\[\]\s\d]*\) # arguments
39-
)\s*\{ # must end with {
39+
)\s*(\{|;) # must end with `{` or `;`
4040
""", re.X | re.M | re.I)
4141
DETECTMAIN_RE = re.compile(r"void\s+(setup|loop)\s*\(", re.M | re.I)
4242
PROTOPTRS_TPLRE = r"\([^&\(]*&(%s)[^\)]*\)"
@@ -162,7 +162,14 @@ def append_prototypes(self, contents):
162162
if not prototypes:
163163
return contents
164164

165-
prototype_names = set([m.group(3).strip() for m in prototypes])
165+
# skip already declared prototypes
166+
declared = set(
167+
m.group(1).strip() for m in prototypes if m.group(4) == ";")
168+
prototypes = [
169+
m for m in prototypes if m.group(1).strip() not in declared
170+
]
171+
172+
prototype_names = set(m.group(3).strip() for m in prototypes)
166173
split_pos = prototypes[0].start()
167174
match_ptrs = re.search(
168175
self.PROTOPTRS_TPLRE % ("|".join(prototype_names)),

platformio/commands/ci.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ def validate_path(ctx, param, value): # pylint: disable=unused-argument
5555
"--build-dir",
5656
default=mkdtemp,
5757
type=click.Path(
58-
exists=True,
5958
file_okay=False,
6059
dir_okay=True,
6160
writable=True,
@@ -134,7 +133,8 @@ def _copy_contents(dst_dir, contents):
134133
if dst_dir_name == "src" and len(items['dirs']) == 1:
135134
copytree(list(items['dirs']).pop(), dst_dir, symlinks=True)
136135
else:
137-
makedirs(dst_dir)
136+
if not isdir(dst_dir):
137+
makedirs(dst_dir)
138138
for d in items['dirs']:
139139
copytree(d, join(dst_dir, basename(d)), symlinks=True)
140140

@@ -145,7 +145,10 @@ def _copy_contents(dst_dir, contents):
145145
dst_dir = join(dst_dir, mkdtemp(dir=dst_dir))
146146

147147
for f in items['files']:
148-
copyfile(f, join(dst_dir, basename(f)))
148+
dst_file = join(dst_dir, basename(f))
149+
if f == dst_file:
150+
continue
151+
copyfile(f, dst_file)
149152

150153

151154
def _exclude_contents(dst_dir, patterns):

platformio/ide/tpls/vscode/.vscode/c_cpp_properties.json.tpl

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
{
2-
"!!! WARNING !!!": "PLEASE DO NOT MODIFY THIS FILE! USE https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags",
32
"configurations": [
43
{
4+
"name": "!!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags"
5+
},
6+
{
57
% import platform
68
% from os.path import commonprefix, dirname
79
%

tests/commands/test_ci.py

+31-1
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-
from os.path import join
15+
from os.path import isfile, join
1616

1717
from platformio.commands.ci import cli as cmd_ci
1818
from platformio.commands.lib import cli as cmd_lib
@@ -32,6 +32,36 @@ def test_ci_boards(clirunner, validate_cliresult):
3232
validate_cliresult(result)
3333

3434

35+
def test_ci_build_dir(clirunner, tmpdir_factory, validate_cliresult):
36+
build_dir = str(tmpdir_factory.mktemp("ci_build_dir"))
37+
result = clirunner.invoke(cmd_ci, [
38+
join("examples", "wiring-blink", "src", "main.cpp"), "-b", "uno",
39+
"--build-dir", build_dir
40+
])
41+
validate_cliresult(result)
42+
assert not isfile(join(build_dir, "platformio.ini"))
43+
44+
45+
def test_ci_keep_build_dir(clirunner, tmpdir_factory, validate_cliresult):
46+
build_dir = str(tmpdir_factory.mktemp("ci_build_dir"))
47+
result = clirunner.invoke(cmd_ci, [
48+
join("examples", "wiring-blink", "src", "main.cpp"), "-b", "uno",
49+
"--build-dir", build_dir, "--keep-build-dir"
50+
])
51+
validate_cliresult(result)
52+
assert isfile(join(build_dir, "platformio.ini"))
53+
54+
# 2nd attempt
55+
result = clirunner.invoke(cmd_ci, [
56+
join("examples", "wiring-blink", "src", "main.cpp"), "-b", "metro",
57+
"--build-dir", build_dir, "--keep-build-dir"
58+
])
59+
validate_cliresult(result)
60+
61+
assert "board: uno" in result.output
62+
assert "board: metro" in result.output
63+
64+
3565
def test_ci_project_conf(clirunner, validate_cliresult):
3666
project_dir = join("examples", "wiring-blink")
3767
result = clirunner.invoke(cmd_ci, [

tests/ino2cpp/basic/basic.ino

+8
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,12 @@ void fooCallback(){
4949

5050
}
5151

52+
extern "C" {
53+
void some_extern(const char *fmt, ...);
54+
};
55+
56+
void some_extern(const char *fmt, ...) {
57+
58+
}
59+
5260
// юнікод

0 commit comments

Comments
 (0)