Repository: ARMmbed/mbed-tools

Issue:
Does not compile with --mbed-os-path option
**Describe the bug**
As in title.

**To Reproduce**
Steps to reproduce the behavior:
1. Import an example project.
1. mbed-tools compile -m K64F -t GCC_ARM --mbed-os-path mbed-os

Error:
`ValueError: Setting storage_filesystem.rbp_internal_size already defined. You cannot duplicate config settings!`

The setting name changes every time the command is executed.

**Expected behavior**
Should work.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
 - OS: Windows
 - Version: 10

**Mbed (please complete the following information):**
 - Device: any
 - Mbed OS Version: 6.9.0
 - Mbed CLI 2 Version: 7.8.0

**Additional context**
I assume this has something to do with the dependencies. Here is my pipdeptree output:

```
mbed-tools==7.8.0
  - Click [required: >=7.1,<8, installed: 7.1]
  - GitPython [required: Any, installed: 3.1.14]
    - gitdb [required: >=4.0.1,<5, installed: 4.0.5]
      - smmap [required: >=3.0.1,<4, installed: 3.0.5]
  - Jinja2 [required: Any, installed: 2.11.3]
    - MarkupSafe [required: >=0.23, installed: 1.1.1]
  - pdoc3 [required: Any, installed: 0.9.2]
    - mako [required: Any, installed: 1.1.4]
      - MarkupSafe [required: >=0.9.2, installed: 1.1.1]
    - markdown [required: >=3.0, installed: 3.3.4]
  - pyserial [required: Any, installed: 3.5]
  - python-dotenv [required: Any, installed: 0.15.0]
  - pywin32 [required: Any, installed: 300]
  - requests [required: >=2.20, installed: 2.25.1]
    - certifi [required: >=2017.4.17, installed: 2020.12.5]
    - chardet [required: >=3.0.2,<5, installed: 4.0.0]
    - idna [required: >=2.5,<3, installed: 2.10]
    - urllib3 [required: >=1.21.1,<1.27, installed: 1.26.4]
  - tabulate [required: Any, installed: 0.8.9]
  - tqdm [required: Any, installed: 4.59.0]
  - typing-extensions [required: Any, installed: 3.7.4.3]
```

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed) Report
> Merging [#285](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed) (0fa678f) into [master](https://codecov.io/gh/ARMmbed/mbed-tools/commit/71e9707b908c393691a4e509ced90ce608e68b81?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed) (71e9707) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285/graphs/tree.svg?width=650&height=150&src=pr&token=QFRIdRv91G&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed)](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed)

```diff
@@           Coverage Diff           @@
##           master     #285   +/-   ##
=======================================
  Coverage   97.12%   97.12%           
=======================================
  Files          92       92           
  Lines        2813     2815    +2     
=======================================
+ Hits         2732     2734    +2     
  Misses         81       81           
```


| [Impacted Files](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed) | Coverage Δ | |
|---|---|---|
| [...ls/build/\_internal/config/assemble\_build\_config.py](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed#diff-c3JjL21iZWRfdG9vbHMvYnVpbGQvX2ludGVybmFsL2NvbmZpZy9hc3NlbWJsZV9idWlsZF9jb25maWcucHk=) | `100.00% <ø> (ø)` | |
| [src/mbed\_tools/build/\_internal/find\_files.py](https://codecov.io/gh/ARMmbed/mbed-tools/pull/285/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=ARMmbed#diff-c3JjL21iZWRfdG9vbHMvYnVpbGQvX2ludGVybmFsL2ZpbmRfZmlsZXMucHk=) | `100.00% <100.00%> (ø)` | |


Patch:
diff --git a/news/20210524175020.bugfix b/news/20210524175020.bugfix
new file mode 100644
index 0000000..e9b7b63
--- /dev/null
+++ b/news/20210524175020.bugfix
@@ -0,0 +1,1 @@
+Avoid searching config file paths twice when mbed-os-path is used and it is a subdirectory of the project path.
diff --git a/src/mbed_tools/build/_internal/config/assemble_build_config.py b/src/mbed_tools/build/_internal/config/assemble_build_config.py
index 676bc4a..e61cd9c 100644
--- a/src/mbed_tools/build/_internal/config/assemble_build_config.py
+++ b/src/mbed_tools/build/_internal/config/assemble_build_config.py
@@ -33,7 +33,11 @@ def assemble_config(target_attributes: dict, search_paths: Iterable[Path], mbed_
         mbed_app_file: The path to mbed_app.json. This can be None.
     """
     mbed_lib_files = list(
-        set(itertools.chain.from_iterable(find_files("mbed_lib.json", path) for path in search_paths))
+        set(
+            itertools.chain.from_iterable(
+                find_files("mbed_lib.json", path.absolute().resolve()) for path in search_paths
+            )
+        )
     )
     return _assemble_config_from_sources(target_attributes, mbed_lib_files, mbed_app_file)
 
diff --git a/src/mbed_tools/build/_internal/find_files.py b/src/mbed_tools/build/_internal/find_files.py
index 9f663bb..1dba384 100644
--- a/src/mbed_tools/build/_internal/find_files.py
+++ b/src/mbed_tools/build/_internal/find_files.py
@@ -52,6 +52,9 @@ def _find_files(filename: str, directory: Path, filters: Optional[List[Callable]
     filtered_children = filter_files(children, filters)
 
     for child in filtered_children:
+        if child.is_symlink():
+            child = child.absolute().resolve()
+
         if child.is_dir():
             # If processed child is a directory, recurse with current set of filters
             result += _find_files(filename, child, filters)


Test patch:
diff --git a/tests/build/_internal/config/test_assemble_build_config.py b/tests/build/_internal/config/test_assemble_build_config.py
index 79acb8d..47fcc5f 100644
--- a/tests/build/_internal/config/test_assemble_build_config.py
+++ b/tests/build/_internal/config/test_assemble_build_config.py
@@ -6,7 +6,7 @@ import json
 from pathlib import Path
 from tempfile import TemporaryDirectory
 
-from mbed_tools.build._internal.config.assemble_build_config import _assemble_config_from_sources
+from mbed_tools.build._internal.config.assemble_build_config import _assemble_config_from_sources, assemble_config
 from mbed_tools.build._internal.config.config import Config
 from mbed_tools.build._internal.find_files import find_files
 from mbed_tools.build._internal.config.source import prepare
@@ -157,3 +157,47 @@ class TestAssembleConfigFromSourcesAndLibFiles:
             assert config["extra_labels"] == {"EXTRA_HOT"}
             assert config["labels"] == {"A", "PICKLE"}
             assert config["macros"] == {"TICKER", "RED_MACRO"}
+
+    def test_ignores_duplicate_paths_to_lib_files(self, tmp_path, monkeypatch):
+        target = {
+            "labels": {"A"},
+        }
+        mbed_lib_files = [
+            {
+                "path": Path("mbed-os", "TARGET_A", "mbed_lib.json"),
+                "json_contents": {"name": "a", "config": {"a": {"value": 4}}},
+            },
+        ]
+        _ = create_files(tmp_path, mbed_lib_files)
+        monkeypatch.chdir(tmp_path)
+
+        config = assemble_config(target, [tmp_path, Path("mbed-os")], None)
+
+        assert config["config"][0].name == "a"
+        assert config["config"][0].value == 4
+
+    def test_does_not_search_symlinks_in_proj_dir_twice(self, tmp_path, monkeypatch):
+        target = {
+            "labels": {"A"},
+        }
+        mbed_lib_files = [
+            {
+                "path": Path("mbed-os", "TARGET_A", "mbed_lib.json"),
+                "json_contents": {"name": "a", "config": {"a": {"value": 4}}},
+            },
+        ]
+        project_dir = tmp_path / "project"
+        project_dir.mkdir()
+
+        mbed_os_dir = tmp_path / "other" / "mbed-os"
+        mbed_os_dir.mkdir(parents=True)
+        _ = create_files(mbed_os_dir, mbed_lib_files)
+
+        monkeypatch.chdir(project_dir)
+        mbed_symlink = Path("mbed-os")
+        mbed_symlink.symlink_to(mbed_os_dir, target_is_directory=True)
+
+        config = assemble_config(target, [project_dir, mbed_symlink], None)
+
+        assert config["config"][0].name == "a"
+        assert config["config"][0].value == 4