blob: ec1ba7af1e66d9b6b12c42e088b5fa6999e76ea9 [file] [log] [blame] [edit]
#!/usr/bin/env python3
"""
This file needs to be kept in sync with ../../make/deps.mk
"""
import os
import os.path
MY_DIR = os.path.dirname(os.path.abspath(__file__))
TOP_DIR = os.path.abspath(os.path.join(MY_DIR, "..", ".."))
DEPS_DIR = ".deps"
DEPS_EXT = ".d"
DEPMK_EXT = ".dmk"
def makefile_dir(filepath):
"""Get the directory part of a path in the same way make does.
Python version of the makefile `$(dir xxx)` function.
>>> makefile_dir("blah1")
''
>>> makefile_dir("a/blah2")
'a/'
>>> makefile_dir("../b/blah3")
'../b/'
>>> makefile_dir("./blah4")
''
>>> makefile_dir("/abc/blah6")
'/abc/'
>>> makefile_dir("/blah5")
'/'
"""
dirname = os.path.dirname(os.path.normpath(filepath))
if not dirname or dirname == '.':
return ''
if dirname[-1] != '/':
dirname += '/'
return dirname
def makefile_notdir(filepath):
"""Get the non-directory part of a path in the same way make does.
Python version of the makefile `$(nodir xxxx)` function.
>>> makefile_notdir("blah1")
'blah1'
>>> makefile_notdir("a/blah2")
'blah2'
>>> makefile_notdir("../b/blah3")
'blah3'
>>> makefile_notdir("blah4/")
''
>>> makefile_notdir("/blah5")
'blah5'
>>> makefile_notdir("/abc/blah6")
'blah6'
"""
return os.path.basename(filepath)
def deps_dir(filepath, *, top_dir=TOP_DIR):
"""Get the directory to put dependencies files into.
>>> td = os.path.abspath(os.curdir)
>>> deps_dir("./a/blah", top_dir=td)
'.deps/a/blah'
>>> deps_dir("blah", top_dir=td)
'.deps/blah'
>>> deps_dir("blah.abc", top_dir=td)
'.deps/blah.abc'
>>> deps_dir("/abc3/blah", top_dir='/abc3')
'.deps/blah'
>>> deps_dir("/abc3/blah", top_dir='/abc4')
Traceback (most recent call last):
...
OSError: /abc3/blah is not inside top /abc4
"""
filepath = os.path.normpath(filepath)
if filepath[0] != '/':
filepath = os.path.abspath(filepath)
filepath_notop = filepath.replace(top_dir + '/', '')
if filepath_notop == filepath:
raise IOError("{} is not inside top {}".format(filepath, top_dir))
return "{deps_dir}/{dir}{notdir}".format(
deps_dir=DEPS_DIR,
dir=makefile_dir(filepath_notop),
notdir=makefile_notdir(filepath_notop),
)
def deps_makefile(filepath, *, top_dir=TOP_DIR):
"""Get deps makefile name.
Python version of `$(call deps_makefile,{})` in make/deps.mk
>>> td = os.path.abspath(os.curdir)
>>> deps_makefile("./a/blah", top_dir=td)
'.deps/a/blah.dmk'
>>> deps_makefile("blah", top_dir=td)
'.deps/blah.dmk'
"""
return deps_dir(
"{dir}{notdir}{ext}".format(
dir=makefile_dir(filepath),
notdir=makefile_notdir(filepath),
ext=DEPMK_EXT,
),
top_dir=top_dir
)
def add_dependency(f, from_file, on_file, fmt=None):
"""Record a dependency from file on file."""
if fmt is None:
fmt = "$(call add_dependency,{from_file},{on_file})\n"
f.write(fmt.format(
from_file=from_file,
on_file=on_file,
))
def write_deps(inputfile_name, data):
deps_filename = deps_makefile(inputfile_name)
with open(deps_filename, "w") as f:
f.write(data.getvalue())
print("Generated dependency info", deps_filename)
if __name__ == "__main__":
import doctest
failure_count, test_count = doctest.testmod()
assert test_count > 0
assert failure_count == 0, "Doctests failed!"