aboutsummaryrefslogtreecommitdiff
path: root/pw_build_mcuxpresso
diff options
context:
space:
mode:
Diffstat (limited to 'pw_build_mcuxpresso')
-rw-r--r--pw_build_mcuxpresso/docs.rst126
-rw-r--r--pw_build_mcuxpresso/py/BUILD.gn3
-rw-r--r--pw_build_mcuxpresso/py/pw_build_mcuxpresso/__main__.py42
-rw-r--r--pw_build_mcuxpresso/py/pw_build_mcuxpresso/bazel.py89
-rw-r--r--pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py126
-rw-r--r--pw_build_mcuxpresso/py/pw_build_mcuxpresso/gn.py59
-rw-r--r--pw_build_mcuxpresso/py/setup.py18
-rw-r--r--pw_build_mcuxpresso/py/tests/components_test.py28
8 files changed, 343 insertions, 148 deletions
diff --git a/pw_build_mcuxpresso/docs.rst b/pw_build_mcuxpresso/docs.rst
index 180587121..1302d5e0c 100644
--- a/pw_build_mcuxpresso/docs.rst
+++ b/pw_build_mcuxpresso/docs.rst
@@ -1,10 +1,10 @@
.. _module-pw_build_mcuxpresso:
--------------------
+===================
pw_build_mcuxpresso
--------------------
+===================
-The ``pw_build_mcuxpresso`` module provides helper utilizies for building a
+The ``pw_build_mcuxpresso`` module provides helper utilities for building a
target based on an NXP MCUXpresso SDK.
The GN build files live in ``third_party/mcuxpresso`` but are documented here.
@@ -12,21 +12,51 @@ The rationale for keeping the build files in ``third_party`` is that code
depending on an MCUXpresso SDK can clearly see that their dependency is on
third party, not pigweed code.
+-----------------------
Using an MCUXpresso SDK
-=======================
+-----------------------
An MCUXpresso SDK consists of a number of components, each of which has a set
-of sources, headers, pre-processor defines, and dependencies on other
+of sources, headers, preprocessor defines, and dependencies on other
components. These are all described in an XML "manifest" file included in the
SDK package.
To use the SDK within a Pigweed project, the set of components you need must be
-combined into a ``pw_source_set`` that you can depend on. This source set will
-include all of the sources and headers, along with necessary pre-processor
-defines, for those components and their dependencies.
+combined into a library that you can depend on. This library will include all of
+the sources and headers, along with necessary preprocessor defines, for those
+components and their dependencies.
-The source set is defined using the ``pw_mcuxpresso_sdk`` template, providing
-the path to the ``manifest`` XML, along with the names of the components you
-wish to ``include``.
+Optional components
+===================
+Including components will include all of their required dependencies. Where the
+components you include have optional dependencies, they must be satisfied by the
+set of components you include otherwise the library generation will fail with an
+error.
+
+Excluding components
+====================
+Components can be excluded from the generated source set, for example to
+suppress errors about optional dependencies your project does not need, or to
+prevent an unwanted component dependency from being introduced into your
+project.
+
+mcuxpresso_builder
+==================
+``mcuxpresso_builder`` is a utility installed into the environment that is used
+by the GN build scripts in ``third_party/mcuxpresso``, or directly by you to
+generate rules for the Bazel build.
+
+Usage is documented for each build system in the relevant section.
+
+------------
+The GN build
+------------
+Using an MCUxpresso SDK within a Pigweed project that uses the GN Build system
+involves the creation of one or more ``pw_source_set`` targets you can depend on
+in your executable targets.
+
+These source sets sets are defined using the ``pw_mcuxpresso_sdk`` template.
+Provide the path to the ``manifest`` XML, along with the names of the components
+you wish to ``include``.
.. code-block:: text
@@ -46,22 +76,9 @@ wish to ``include``.
deps = [ ":sample_project_sdk" ]
}
-Where the components you include have optional dependencies, they must be
-satisfied by the set of components you include otherwise the GN generation will
-fail with an error.
-
-Excluding components
---------------------
-Components can be excluded from the generated source set, for example to
-suppress errors about optional dependencies your project does not need, or to
-prevent an unwanted component dependency from being introduced into your
-project.
-
-This is accomplished by providing the list of components to ``exclude`` as an
-argument to the template.
-
-For example to replace the FreeRTOS kernel bundled with the MCUXpresso SDK with
-the Pigweed third-party target:
+To exclude components, provide the list to ``exclude`` as an argument to the
+template. For example to replace the FreeRTOS kernel bundled with the MCUXpresso
+SDK with the Pigweed third-party target:
.. code-block:: text
@@ -72,7 +89,7 @@ the Pigweed third-party target:
}
Introducing dependencies
-------------------------
+========================
As seen above, the generated source set can have dependencies added by passing
the ``public_deps`` (or ``deps``) arguments to the template.
@@ -85,7 +102,7 @@ SDK.
To resolve circular dependencies, in addition to the generated source set, two
configs named with the ``__defines`` and ``__includes`` suffixes on the template
-name are generated, to provide the pre-processor defines and include paths that
+name are generated, to provide the preprocessor defines and include paths that
the source set uses.
.. code-block:: text
@@ -111,22 +128,57 @@ the source set uses.
mcuxpresso_builder
==================
-``mcuxpresso_builder`` is a utility that contains the backend scripts used by
-the GN build scripts in ``third_party/mcuxpresso``. You should only need to
-interact with ``mcuxpresso_builder`` directly if you are doing something custom.
+For the GN build, this utility is invoked by the ``pw_mcuxpresso_sdk`` template.
+You should only need to interact with ``mcuxpresso_builder`` directly if you are
+doing something custom.
-project
--------
-This command outputs a GN scope describing the result of expanding the set of
-included and excluded components.
+The ``gn`` subcommand outputs a GN scope describing the result of expanding the
+set of included and excluded components.
The ``--prefix`` option specifies the GN location of the SDK files.
.. code-block:: bash
- mcuxpresso_builder project /path/to/manifest.xml \
+ mcuxpresso_builder gn /path/to/manifest.xml \
--include project_template.evkmimxrt595.MIMXRT595S \
--include utility.debug_console.MIMXRT595S \
--include component.serial_manager_uart.MIMXRT595S \
--exclude middleware.freertos-kernel.MIMXRT595S \
--prefix //path/to/sdk
+
+---------------
+The Bazel build
+---------------
+To use an MCUxpresso SDK within a Pigweed project that uses tha Bazel build
+system, you must use the ``mcuxpresso_builder`` tool directly and place its
+output in ``BUILD`` or ``BUILD.bazel`` files yourself.
+
+Provide the path to the manifest XML, the ``--name`` of the ``cc_library`` to
+create, along with the names of the components you wish to ``--include`` or
+``--exclude``.
+
+.. code-block:: bash
+
+ mcuxpresso_builder bazel /path/to/manifest.xml \
+ --name example_sdk \
+ --include project_template.evkmimxrt595.MIMXRT595S \
+ --include utility.debug_console.MIMXRT595S \
+ --include component.serial_manager_uart.MIMXRT595S \
+ --exclude middleware.freertos-kernel.MIMXRT595S
+
+
+Place the resulting output in a ``BUILD`` file, and then modify your
+``WORKSPACE`` to associate this build file with the path to the MCUxpresso SDK
+checkout.
+
+.. code-block:: python
+
+ new_local_repository(
+ name = "mcuxpresso_sdk",
+ build_file = "//third_party/mcuxpresso_sdk/BUILD",
+ path = "third_party/evkmimxrt595/sdk",
+ )
+
+To add other dependencies, compiler definitions, etc. it is recommended that
+you do so by creating a new target, and add a dependency to it, rather than
+modifying the generated targets.
diff --git a/pw_build_mcuxpresso/py/BUILD.gn b/pw_build_mcuxpresso/py/BUILD.gn
index e640bd372..274fbe4a9 100644
--- a/pw_build_mcuxpresso/py/BUILD.gn
+++ b/pw_build_mcuxpresso/py/BUILD.gn
@@ -20,12 +20,13 @@ pw_python_package("py") {
setup = [
"pyproject.toml",
"setup.cfg",
- "setup.py",
]
sources = [
"pw_build_mcuxpresso/__init__.py",
"pw_build_mcuxpresso/__main__.py",
+ "pw_build_mcuxpresso/bazel.py",
"pw_build_mcuxpresso/components.py",
+ "pw_build_mcuxpresso/gn.py",
]
tests = [ "tests/components_test.py" ]
pylintrc = "$dir_pigweed/.pylintrc"
diff --git a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/__main__.py b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/__main__.py
index c537cf7e4..c2e816898 100644
--- a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/__main__.py
+++ b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/__main__.py
@@ -19,10 +19,12 @@ import pathlib
import sys
try:
- from pw_build_mcuxpresso import components
+ from pw_build_mcuxpresso import bazel, components, gn
except ImportError:
# Load from this directory if pw_build_mcuxpresso is not available.
import components # type: ignore
+ import bazel # type: ignore
+ import gn # type: ignore
def _parse_args() -> argparse.Namespace:
@@ -33,13 +35,22 @@ def _parse_args() -> argparse.Namespace:
dest='command', metavar='<command>', required=True
)
- project_parser = subparsers.add_parser(
- 'project', help='output components of an MCUXpresso project'
+ subparser = subparsers.add_parser(
+ 'gn', help='output components of an MCUXpresso project as GN scope'
)
- project_parser.add_argument('manifest_filename', type=pathlib.Path)
- project_parser.add_argument('--include', type=str, action='append')
- project_parser.add_argument('--exclude', type=str, action='append')
- project_parser.add_argument('--prefix', dest='path_prefix', type=str)
+ subparser.add_argument('manifest_filename', type=pathlib.Path)
+ subparser.add_argument('--include', type=str, action='append')
+ subparser.add_argument('--exclude', type=str, action='append')
+ subparser.add_argument('--prefix', dest='path_prefix', type=str)
+
+ subparser = subparsers.add_parser(
+ 'bazel', help='output an MCUXpresso project as a bazel target'
+ )
+ subparser.add_argument('manifest_filename', type=pathlib.Path)
+ subparser.add_argument('--name', dest='bazel_name', type=str, required=True)
+ subparser.add_argument('--include', type=str, action='append')
+ subparser.add_argument('--exclude', type=str, action='append')
+ subparser.add_argument('--prefix', dest='path_prefix', type=str)
return parser.parse_args()
@@ -48,12 +59,17 @@ def main():
"""Main command line function."""
args = _parse_args()
- if args.command == 'project':
- components.project(
- args.manifest_filename,
- include=args.include,
- exclude=args.exclude,
- path_prefix=args.path_prefix,
+ project = components.Project.from_file(
+ args.manifest_filename,
+ include=args.include,
+ exclude=args.exclude,
+ )
+
+ if args.command == 'gn':
+ gn.gn_output(project, path_prefix=args.path_prefix)
+ if args.command == 'bazel':
+ bazel.bazel_output(
+ project, name=args.bazel_name, path_prefix=args.path_prefix
)
sys.exit(0)
diff --git a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/bazel.py b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/bazel.py
new file mode 100644
index 000000000..3d6d3a9b5
--- /dev/null
+++ b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/bazel.py
@@ -0,0 +1,89 @@
+# Copyright 2023 The Pigweed Authors
+#
+# 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
+#
+# https://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.
+"""Bazel output support."""
+
+from typing import Any, List, Optional
+
+import pathlib
+
+try:
+ from pw_build_mcuxpresso.components import Project
+except ImportError:
+ # Load from this directory if pw_build_mcuxpresso is not available.
+ from components import Project # type: ignore
+
+
+def _bazel_str(val: Any) -> str:
+ """Returns string in Bazel format with correct escaping."""
+ return str(val).replace('"', r'\"').replace('$', r'\$')
+
+
+def _bazel_str_out(name: str, val: Any, indent: int = 0) -> None:
+ """Outputs string in Bazel format with correct escaping."""
+ print(' ' * indent + f'{name} = "{_bazel_str(val)}",')
+
+
+def _bazel_str_list_out(name: str, vals: List[Any], indent: int = 0) -> None:
+ """Outputs list of strings in Bazel format with correct escaping."""
+ if not vals:
+ return
+
+ print(' ' * indent + f'{name} = [')
+ for val in vals:
+ print(' ' * (indent + 1) + f'"{_bazel_str(val)}",')
+ print(' ' * indent + '],')
+
+
+def _bazel_path_list_out(
+ name: str,
+ vals: List[pathlib.Path],
+ path_prefix: Optional[str] = None,
+ indent: int = 0,
+) -> None:
+ """Outputs list of paths in Bazel format with common prefix."""
+ if path_prefix is not None:
+ str_vals = [f'{path_prefix}{str(val)}' for val in vals]
+ else:
+ str_vals = [str(f) for f in vals]
+
+ _bazel_str_list_out(name, sorted(set(str_vals)), indent=indent)
+
+
+def bazel_output(
+ project: Project, name: str, path_prefix: Optional[str] = None
+):
+ """Output Bazel target for a project with the specified components.
+
+ Args:
+ project: MCUXpresso project to output.
+ name: target name to output.
+ path_prefix: string prefix to prepend to all paths.
+ """
+ print('cc_library(')
+ _bazel_str_out('name', name, indent=1)
+ _bazel_path_list_out(
+ 'srcs',
+ project.sources + project.libs,
+ path_prefix=path_prefix,
+ indent=1,
+ )
+ _bazel_path_list_out(
+ 'hdrs', project.headers, path_prefix=path_prefix, indent=1
+ )
+ _bazel_str_list_out('defines', project.defines, indent=1)
+ _bazel_path_list_out(
+ 'includes', project.include_dirs, path_prefix=path_prefix, indent=1
+ )
+
+ print(')')
diff --git a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py
index a7223a434..c664d3f0e 100644
--- a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py
+++ b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/components.py
@@ -13,37 +13,13 @@
# the License.
"""Finds components for a given manifest."""
-from typing import Any, List, Optional, Tuple
+from typing import List, Optional, Tuple
import pathlib
import sys
import xml.etree.ElementTree
-def _gn_str_out(name: str, val: Any):
- """Outputs scoped string in GN format."""
- print(f'{name} = "{val}"')
-
-
-def _gn_list_str_out(name: str, val: List[Any]):
- """Outputs list of strings in GN format with correct escaping."""
- list_str = ','.join(
- '"' + str(x).replace('"', r'\"').replace('$', r'\$') + '"' for x in val
- )
- print(f'{name} = [{list_str}]')
-
-
-def _gn_list_path_out(
- name: str, val: List[pathlib.Path], path_prefix: Optional[str] = None
-):
- """Outputs list of paths in GN format with common prefix."""
- if path_prefix is not None:
- str_val = list(f'{path_prefix}/{str(d)}' for d in val)
- else:
- str_val = list(str(d) for d in val)
- _gn_list_str_out(name, str_val)
-
-
def get_component(
root: xml.etree.ElementTree.Element, component_id: str
) -> Tuple[Optional[xml.etree.ElementTree.Element], Optional[pathlib.Path]]:
@@ -488,42 +464,68 @@ def create_project(
)
-def project(
- manifest_path: pathlib.Path,
- include: Optional[List[str]] = None,
- exclude: Optional[List[str]] = None,
- path_prefix: Optional[str] = None,
-):
- """Output GN scope for a project with the specified components.
+class Project:
+ """Self-contained MCUXpresso project.
- Args:
- manifest_path: path to SDK manifest XML.
- include: list of component ids included in the project.
- exclude: list of component ids excluded from the project.
- path_prefix: string prefix to prepend to all paths.
+ Properties:
+ component_ids: list of component ids compromising the project.
+ defines: list of compiler definitions to build the project.
+ include_dirs: list of include directory paths needed for the project.
+ headers: list of header paths exported by the project.
+ sources: list of source file paths built as part of the project.
+ libs: list of libraries linked to the project.
+ dependencies_satisfied: True if the project dependencies are satisfied.
"""
- assert include is not None, "Project must include at least one component."
-
- tree = xml.etree.ElementTree.parse(manifest_path)
- root = tree.getroot()
-
- (
- component_ids,
- defines,
- include_dirs,
- headers,
- sources,
- libs,
- ) = create_project(root, include, exclude=exclude)
-
- for component_id in component_ids:
- if not check_dependencies(
- root, component_id, component_ids, exclude=exclude
- ):
- return
-
- _gn_list_str_out('defines', defines)
- _gn_list_path_out('include_dirs', include_dirs, path_prefix=path_prefix)
- _gn_list_path_out('public', headers, path_prefix=path_prefix)
- _gn_list_path_out('sources', sources, path_prefix=path_prefix)
- _gn_list_path_out('libs', libs, path_prefix=path_prefix)
+
+ @classmethod
+ def from_file(
+ cls,
+ manifest_path: pathlib.Path,
+ include: Optional[List[str]] = None,
+ exclude: Optional[List[str]] = None,
+ ):
+ """Create a self-contained project with the specified components.
+
+ Args:
+ manifest_path: path to SDK manifest XML.
+ include: list of component ids included in the project.
+ exclude: list of component ids excluded from the project.
+ """
+ tree = xml.etree.ElementTree.parse(manifest_path)
+ root = tree.getroot()
+ return cls(root, include=include, exclude=exclude)
+
+ def __init__(
+ self,
+ manifest: xml.etree.ElementTree.Element,
+ include: Optional[List[str]] = None,
+ exclude: Optional[List[str]] = None,
+ ):
+ """Create a self-contained project with the specified components.
+
+ Args:
+ manifest: parsed manifest XML.
+ include: list of component ids included in the project.
+ exclude: list of component ids excluded from the project.
+ """
+ assert (
+ include is not None
+ ), "Project must include at least one component."
+
+ (
+ self.component_ids,
+ self.defines,
+ self.include_dirs,
+ self.headers,
+ self.sources,
+ self.libs,
+ ) = create_project(manifest, include, exclude=exclude)
+
+ for component_id in self.component_ids:
+ if not check_dependencies(
+ manifest, component_id, self.component_ids, exclude=exclude
+ ):
+ self.dependencies_satisfied = False
+ return
+
+ self.dependencies_satisfied = True
diff --git a/pw_build_mcuxpresso/py/pw_build_mcuxpresso/gn.py b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/gn.py
new file mode 100644
index 000000000..202c4f774
--- /dev/null
+++ b/pw_build_mcuxpresso/py/pw_build_mcuxpresso/gn.py
@@ -0,0 +1,59 @@
+# Copyright 2023 The Pigweed Authors
+#
+# 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
+#
+# https://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.
+"""GN output support."""
+
+from typing import Any, List, Optional
+
+import pathlib
+
+try:
+ from pw_build_mcuxpresso.components import Project
+except ImportError:
+ # Load from this directory if pw_build_mcuxpresso is not available.
+ from components import Project # type: ignore
+
+
+def _gn_list_str_out(name: str, val: List[Any]):
+ """Outputs list of strings in GN format with correct escaping."""
+ list_str = ','.join(
+ '"' + str(x).replace('"', r'\"').replace('$', r'\$') + '"' for x in val
+ )
+ print(f'{name} = [{list_str}]')
+
+
+def _gn_list_path_out(
+ name: str, val: List[pathlib.Path], path_prefix: Optional[str] = None
+):
+ """Outputs list of paths in GN format with common prefix."""
+ if path_prefix is not None:
+ str_val = list(f'{path_prefix}/{str(d)}' for d in val)
+ else:
+ str_val = list(str(d) for d in val)
+ _gn_list_str_out(name, str_val)
+
+
+def gn_output(project: Project, path_prefix: Optional[str] = None):
+ """Output GN scope for a project with the specified components.
+
+ Args:
+ project: MCUXpresso project to output..
+ path_prefix: string prefix to prepend to all paths.
+ """
+ _gn_list_str_out('defines', project.defines)
+ _gn_list_path_out(
+ 'include_dirs', project.include_dirs, path_prefix=path_prefix
+ )
+ _gn_list_path_out('public', project.headers, path_prefix=path_prefix)
+ _gn_list_path_out('sources', project.sources, path_prefix=path_prefix)
+ _gn_list_path_out('libs', project.libs, path_prefix=path_prefix)
diff --git a/pw_build_mcuxpresso/py/setup.py b/pw_build_mcuxpresso/py/setup.py
deleted file mode 100644
index 694c28691..000000000
--- a/pw_build_mcuxpresso/py/setup.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2021 The Pigweed Authors
-#
-# 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
-#
-# https://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.
-"""pw_build_mcuxpresso"""
-
-import setuptools # type: ignore
-
-setuptools.setup() # Package definition in setup.cfg
diff --git a/pw_build_mcuxpresso/py/tests/components_test.py b/pw_build_mcuxpresso/py/tests/components_test.py
index 94ca6828b..8b36a448f 100644
--- a/pw_build_mcuxpresso/py/tests/components_test.py
+++ b/pw_build_mcuxpresso/py/tests/components_test.py
@@ -805,8 +805,8 @@ class CheckDependenciesTest(unittest.TestCase):
self.assertEqual(satisfied, True)
-class CreateProjectTest(unittest.TestCase):
- """create_project tests."""
+class ProjectTest(unittest.TestCase):
+ """Project tests."""
def test_create_project(self):
"""test creating a project."""
@@ -904,21 +904,14 @@ class CreateProjectTest(unittest.TestCase):
</manifest>
'''
root = xml.etree.ElementTree.fromstring(test_manifest_xml)
- (
- component_ids,
- defines,
- include_dirs,
- headers,
- sources,
- libs,
- ) = components.create_project(
- root, ['test', 'frodo'], exclude=['bilbo']
+ project = components.Project(
+ root, ['test', 'frodo'], exclude=['baz', 'bilbo']
)
- self.assertEqual(component_ids, ['test', 'frodo', 'foo', 'bar'])
- self.assertEqual(defines, ['FRODO', 'FOO', 'BAR'])
+ self.assertEqual(project.component_ids, ['test', 'frodo', 'foo', 'bar'])
+ self.assertEqual(project.defines, ['FRODO', 'FOO', 'BAR'])
self.assertEqual(
- include_dirs,
+ project.include_dirs,
[
pathlib.Path('frodo/include'),
pathlib.Path('foo/include'),
@@ -926,7 +919,7 @@ class CreateProjectTest(unittest.TestCase):
],
)
self.assertEqual(
- headers,
+ project.headers,
[
pathlib.Path('frodo/include/frodo.h'),
pathlib.Path('foo/include/foo.h'),
@@ -934,14 +927,15 @@ class CreateProjectTest(unittest.TestCase):
],
)
self.assertEqual(
- sources,
+ project.sources,
[
pathlib.Path('frodo/src/frodo.cc'),
pathlib.Path('foo/src/foo.cc'),
pathlib.Path('bar/src/bar.cc'),
],
)
- self.assertEqual(libs, [pathlib.Path('frodo/libonering.a')])
+ self.assertEqual(project.libs, [pathlib.Path('frodo/libonering.a')])
+ self.assertTrue(project.dependencies_satisfied)
if __name__ == '__main__':