mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 10:07:14 +02:00
Fixed an issue with endless scanning of project dependencies // Resolve #4349
This commit is contained in:
@ -18,6 +18,7 @@ PlatformIO Core 6
|
|||||||
|
|
||||||
* Show "TimeoutError" only in the verbose mode when can not find a serial port
|
* Show "TimeoutError" only in the verbose mode when can not find a serial port
|
||||||
* Fixed an issue when a serial port was not automatically detected if the board has predefined HWIDs
|
* Fixed an issue when a serial port was not automatically detected if the board has predefined HWIDs
|
||||||
|
* Fixed an issue with endless scanning of project dependencies (`issue #4349 <https://github.com/platformio/platformio-core/issues/4349>`_)
|
||||||
|
|
||||||
6.1.0 (2022-07-06)
|
6.1.0 (2022-07-06)
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -331,7 +331,7 @@ class LibBuilderBase:
|
|||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
def _get_found_includes( # pylint: disable=too-many-branches
|
def get_implicit_includes( # pylint: disable=too-many-branches
|
||||||
self, search_files=None
|
self, search_files=None
|
||||||
):
|
):
|
||||||
# all include directories
|
# all include directories
|
||||||
@ -352,15 +352,17 @@ class LibBuilderBase:
|
|||||||
include_dirs.extend(LibBuilderBase._INCLUDE_DIRS_CACHE)
|
include_dirs.extend(LibBuilderBase._INCLUDE_DIRS_CACHE)
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
for path in search_files or []:
|
search_files = search_files or []
|
||||||
if path in self._processed_files:
|
while search_files:
|
||||||
|
node = self.env.File(search_files.pop(0))
|
||||||
|
if node.get_abspath() in self._processed_search_files:
|
||||||
continue
|
continue
|
||||||
self._processed_files.append(path)
|
self._processed_search_files.append(node.get_abspath())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
assert "+" in self.lib_ldf_mode
|
assert "+" in self.lib_ldf_mode
|
||||||
candidates = LibBuilderBase.CCONDITIONAL_SCANNER(
|
candidates = LibBuilderBase.CCONDITIONAL_SCANNER(
|
||||||
self.env.File(path),
|
node,
|
||||||
self.env,
|
self.env,
|
||||||
tuple(include_dirs),
|
tuple(include_dirs),
|
||||||
depth=self.CCONDITIONAL_SCANNER_DEPTH,
|
depth=self.CCONDITIONAL_SCANNER_DEPTH,
|
||||||
@ -370,39 +372,35 @@ class LibBuilderBase:
|
|||||||
if self.verbose and "+" in self.lib_ldf_mode:
|
if self.verbose and "+" in self.lib_ldf_mode:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
"Warning! Classic Pre Processor is used for `%s`, "
|
"Warning! Classic Pre Processor is used for `%s`, "
|
||||||
"advanced has failed with `%s`\n" % (path, exc)
|
"advanced has failed with `%s`\n" % (node.get_abspath(), exc)
|
||||||
)
|
)
|
||||||
candidates = self.env.File(path).get_implicit_deps(
|
candidates = LibBuilderBase.CLASSIC_SCANNER(
|
||||||
self.env,
|
node, self.env, tuple(include_dirs)
|
||||||
LibBuilderBase.CLASSIC_SCANNER,
|
|
||||||
lambda _: tuple(include_dirs),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# mark candidates already processed
|
# print(node.get_abspath(), [c.get_abspath() for c in candidates])
|
||||||
self._processed_files.extend(
|
|
||||||
[
|
|
||||||
c.get_abspath()
|
|
||||||
for c in candidates
|
|
||||||
if c.get_abspath() not in self._processed_files
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
# print(path, [c.get_abspath() for c in candidates])
|
|
||||||
for item in candidates:
|
for item in candidates:
|
||||||
|
item_path = item.get_abspath()
|
||||||
|
# process internal files recursively
|
||||||
|
if (
|
||||||
|
item_path not in self._processed_search_files
|
||||||
|
and item_path not in search_files
|
||||||
|
and item_path in self
|
||||||
|
):
|
||||||
|
search_files.append(item_path)
|
||||||
if item not in result:
|
if item not in result:
|
||||||
result.append(item)
|
result.append(item)
|
||||||
if not self.PARSE_SRC_BY_H_NAME:
|
if not self.PARSE_SRC_BY_H_NAME:
|
||||||
continue
|
continue
|
||||||
_h_path = item.get_abspath()
|
if not fs.path_endswith_ext(item_path, piotool.SRC_HEADER_EXT):
|
||||||
if not fs.path_endswith_ext(_h_path, piotool.SRC_HEADER_EXT):
|
|
||||||
continue
|
continue
|
||||||
_f_part = _h_path[: _h_path.rindex(".")]
|
item_fname = item_path[: item_path.rindex(".")]
|
||||||
for ext in piotool.SRC_C_EXT + piotool.SRC_CXX_EXT:
|
for ext in piotool.SRC_C_EXT + piotool.SRC_CXX_EXT:
|
||||||
if not os.path.isfile("%s.%s" % (_f_part, ext)):
|
if not os.path.isfile("%s.%s" % (item_fname, ext)):
|
||||||
continue
|
continue
|
||||||
_c_path = self.env.File("%s.%s" % (_f_part, ext))
|
item_c_node = self.env.File("%s.%s" % (item_fname, ext))
|
||||||
if _c_path not in result:
|
if item_c_node not in result:
|
||||||
result.append(_c_path)
|
result.append(item_c_node)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -417,7 +415,7 @@ class LibBuilderBase:
|
|||||||
search_files = self.get_search_files()
|
search_files = self.get_search_files()
|
||||||
|
|
||||||
lib_inc_map = {}
|
lib_inc_map = {}
|
||||||
for inc in self._get_found_includes(search_files):
|
for inc in self.get_implicit_includes(search_files):
|
||||||
inc_path = inc.get_abspath()
|
inc_path = inc.get_abspath()
|
||||||
for lb in self.env.GetLibBuilders():
|
for lb in self.env.GetLibBuilders():
|
||||||
if inc_path in lb:
|
if inc_path in lb:
|
||||||
|
@ -335,3 +335,73 @@ projenv.Append(CPPDEFINES=[
|
|||||||
assert 'MACRO_2=<Text is "Quoted">' in result.output
|
assert 'MACRO_2=<Text is "Quoted">' in result.output
|
||||||
assert 'MACRO_3=<Hello "World"! Isn\'t true?>' in result.output
|
assert 'MACRO_3=<Hello "World"! Isn\'t true?>' in result.output
|
||||||
assert "MACRO_4=<Special chars: ',(,),[,],:>" in result.output
|
assert "MACRO_4=<Special chars: ',(,),[,],:>" in result.output
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldf(clirunner, validate_cliresult, tmp_path: Path):
|
||||||
|
project_dir = tmp_path / "project"
|
||||||
|
|
||||||
|
# libs
|
||||||
|
lib_dir = project_dir / "lib"
|
||||||
|
a_lib_dir = lib_dir / "a"
|
||||||
|
a_lib_dir.mkdir(parents=True)
|
||||||
|
(a_lib_dir / "a.h").write_text(
|
||||||
|
"""
|
||||||
|
#include <some_from_b.h>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
# b
|
||||||
|
b_lib_dir = lib_dir / "b"
|
||||||
|
b_lib_dir.mkdir(parents=True)
|
||||||
|
(b_lib_dir / "some_from_b.h").write_text("")
|
||||||
|
# c
|
||||||
|
c_lib_dir = lib_dir / "c"
|
||||||
|
c_lib_dir.mkdir(parents=True)
|
||||||
|
(c_lib_dir / "parse_c_by_name.h").write_text(
|
||||||
|
"""
|
||||||
|
void some_func();
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
(c_lib_dir / "parse_c_by_name.c").write_text(
|
||||||
|
"""
|
||||||
|
#include <d.h>
|
||||||
|
#include <parse_c_by_name.h>
|
||||||
|
|
||||||
|
void some_func() {
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
(c_lib_dir / "some.c").write_text(
|
||||||
|
"""
|
||||||
|
#include <d.h>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
# d
|
||||||
|
d_lib_dir = lib_dir / "d"
|
||||||
|
d_lib_dir.mkdir(parents=True)
|
||||||
|
(d_lib_dir / "d.h").write_text("")
|
||||||
|
|
||||||
|
# project
|
||||||
|
src_dir = project_dir / "src"
|
||||||
|
src_dir.mkdir(parents=True)
|
||||||
|
(src_dir / "main.h").write_text(
|
||||||
|
"""
|
||||||
|
#include <a.h>
|
||||||
|
#include <parse_c_by_name.h>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
(src_dir / "main.c").write_text(
|
||||||
|
"""
|
||||||
|
#include <main.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
(project_dir / "platformio.ini").write_text(
|
||||||
|
"""
|
||||||
|
[env:native]
|
||||||
|
platform = native
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = clirunner.invoke(cmd_run, ["--project-dir", str(project_dir)])
|
||||||
|
validate_cliresult(result)
|
||||||
|
Reference in New Issue
Block a user