pw_toolchain: Fix cp command for Windows
The `cp` executable is not always present on the Windows machine.
This commit adds the fallback mechanism based on the python script
to simulate the desired behaviour of `cp -af` command. The original
behaviour has been kept untouched.
Change-Id: I423542abfdf960ab29ba719f889bf143b462411b
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/29780
Reviewed-by: Michael Spang <spang@google.com>
Commit-Queue: Michael Spang <spang@google.com>
diff --git a/pw_toolchain/py/BUILD.gn b/pw_toolchain/py/BUILD.gn
new file mode 100644
index 0000000..7a27fb7
--- /dev/null
+++ b/pw_toolchain/py/BUILD.gn
@@ -0,0 +1,26 @@
+# 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.
+
+import("//build_overrides/pigweed.gni")
+
+import("$dir_pw_build/python.gni")
+
+pw_python_package("py") {
+ setup = [ "setup.py" ]
+ sources = [
+ "pw_toolchain/__init__.py",
+ "pw_toolchain/copy_with_metadata.py",
+ ]
+ pylintrc = "$dir_pigweed/.pylintrc"
+}
diff --git a/pw_toolchain/py/pw_toolchain/__init__.py b/pw_toolchain/py/pw_toolchain/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pw_toolchain/py/pw_toolchain/__init__.py
diff --git a/pw_toolchain/py/pw_toolchain/copy_with_metadata.py b/pw_toolchain/py/pw_toolchain/copy_with_metadata.py
new file mode 100644
index 0000000..59fde19
--- /dev/null
+++ b/pw_toolchain/py/pw_toolchain/copy_with_metadata.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+# 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.
+"""Emulation of `cp -af src dest`."""
+
+import logging
+import os
+import shutil
+import stat
+import sys
+
+_LOG = logging.getLogger(__name__)
+
+
+def copy_with_metadata(src, dest):
+ """Emulation of `cp -af in out` command."""
+ if not os.path.exists(src):
+ _LOG.error('No such file or directory.')
+ return -1
+
+ try:
+ if os.path.isdir(src):
+ shutil.copytree(src, dest, symlinks=True)
+ else:
+ shutil.copy2(src, dest, follow_symlinks=False)
+ except:
+ _LOG.error('Error during copying procedure.')
+ return -1
+
+ return 0
+
+
+def main():
+ # Require exactly two arguments, source and destination.
+ if (len(sys.argv) - 1) != 2:
+ _LOG.error('Incorrect parameters provided.')
+ return -1
+
+ return copy_with_metadata(sys.argv[1], sys.argv[2])
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/pw_toolchain/py/pw_toolchain/py.typed b/pw_toolchain/py/pw_toolchain/py.typed
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pw_toolchain/py/pw_toolchain/py.typed
diff --git a/pw_toolchain/py/setup.py b/pw_toolchain/py/setup.py
new file mode 100644
index 0000000..088fe50
--- /dev/null
+++ b/pw_toolchain/py/setup.py
@@ -0,0 +1,25 @@
+# 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_toolchain"""
+
+import setuptools # type: ignore
+
+setuptools.setup(name='pw_toolchain',
+ version='0.0.1',
+ author='Pigweed Authors',
+ author_email='pigweed-developers@googlegroups.com',
+ description='Pigweed toolchain wrapper',
+ packages=setuptools.find_packages(),
+ package_data={'pw_toolchain': ['py.typed']},
+ zip_safe=False)
diff --git a/pw_toolchain/universal_tools.gni b/pw_toolchain/universal_tools.gni
index 8fcc062..820276d 100644
--- a/pw_toolchain/universal_tools.gni
+++ b/pw_toolchain/universal_tools.gni
@@ -12,9 +12,18 @@
# License for the specific language governing permissions and limitations under
# the License.
+import("//build_overrides/pigweed.gni")
+
pw_universal_copy = {
if (host_os == "win") {
- command = "cp -af {{source}} {{output}}"
+ cp_command = "cp -af {{source}} {{output}}"
+
+ # Use python script in absence of cp command.
+ copy_tool_path =
+ rebase_path(dir_pw_toolchain) + "/py/pw_toolchain/copy_with_metadata.py"
+ fallback_command = "python $copy_tool_path {{source}} {{output}}"
+
+ command = "cmd /c \"($cp_command > NUL 2>&1) || ($fallback_command)\""
} else {
# Use a hard link if possible as this is faster. Also, Mac doesn't
# preserve timestamps properly with cp -af.