Last active
January 4, 2021 10:19
-
-
Save ebraraktas/0770c745c1cf5560397ffd412eebcea7 to your computer and use it in GitHub Desktop.
Copy C or C++ include header dependencies recursively
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Example command: | |
# python copy_headers.py --headers tensorflow/lite/model.h tensorflow/lite/interpreter.h \ | |
# --destination MyAwesomeProject/include | |
# --include-dirs ../flatbuffers/include # Note that these are relative to --source-dir | |
# --source-dir ../tensorflow/ | |
import argparse | |
import os | |
import subprocess | |
def get_structure(file, directories): | |
for directory in directories: | |
if file.startswith(directory): | |
structure = os.path.dirname(file[len(directory) + (not directory.endswith('/')):]) | |
return structure | |
return os.path.dirname(file) | |
def copy(src, dst): | |
with open(src, 'rb') as sf, open(dst, 'wb') as df: | |
df.write(sf.read()) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, | |
description="Copy header dependencies recuresively") | |
parser.add_argument("--include-dirs", nargs="*", | |
help="Header include directories, relative to source-dir") | |
parser.add_argument("--headers", nargs="*", required=True, | |
help="Header paths whose dependencies will be copied, relative to source-dir") | |
parser.add_argument("--destination", help="destination directory to copy files", required=True) | |
parser.add_argument("--dry-run", help="Just log, don't copy", action='store_true') | |
parser.add_argument("--gcc-args", help="gcc args to be passed", default="--std=c++11") | |
parser.add_argument("--source-dir", help="gcc args to be passed", default=".") | |
args = parser.parse_args() | |
include_dirs = args.include_dirs if args.include_dirs else [] | |
source_dir = args.source_dir | |
include_dirs.append('.') | |
include_args = [] | |
for include_dir in include_dirs: | |
include_args += ["-I", include_dir] | |
headers = args.headers | |
destination = args.destination | |
dry_run = args.dry_run | |
copy_files = dict() # filepath => directory structure under include dir | |
for header in headers: | |
cmd = ["g++", args.gcc_args] + include_args + ["-MM", header] | |
p = subprocess.Popen(cmd, cwd=source_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
out, err = p.communicate() | |
out = out.decode('utf8') | |
files = out[out.index(':') + 1:].replace('\\', '').split() | |
for file in files: | |
copy_files[os.path.abspath(os.path.join(source_dir, file))] = get_structure(file, include_dirs) | |
for file, file_dir in copy_files.items(): | |
file_destination = os.path.join(destination, file_dir, os.path.basename(file)) | |
if dry_run: | |
print(f'Would copy: {file} => {file_destination}') | |
else: | |
destination_dir = os.path.dirname(file_destination) | |
if not os.path.exists(destination_dir): | |
os.makedirs(destination_dir) | |
copy(file, file_destination) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment