aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2019-04-01 14:30:32 +1100
committerNeil <nyamatongwe@gmail.com>2019-04-01 14:30:32 +1100
commit8c406e0fc4bebda5501d520f1c177fc48d38cd93 (patch)
tree5b6c3a459495aad04c73ee1e75ea858eaa05ff7c /scripts
parent7e849320b326d7c8b41d0aadb3beedb57d85766e (diff)
downloadscintilla-mirror-8c406e0fc4bebda5501d520f1c177fc48d38cd93.tar.gz
Switch generation of make dependencies to Python scripts DepGen.py.
Dependencies files deps.mak and nmdeps.mak are formatted with one file per line as that makes it easier to examine differences between versions.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Dependencies.py149
-rw-r--r--scripts/LexGen.py9
-rw-r--r--scripts/__init__.py0
3 files changed, 158 insertions, 0 deletions
diff --git a/scripts/Dependencies.py b/scripts/Dependencies.py
new file mode 100644
index 000000000..86a2d3b22
--- /dev/null
+++ b/scripts/Dependencies.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+# Dependencies.py - discover, read, and write dependencies file for make.
+# The format like the output from "g++ -MM" which produces a
+# list of header (.h) files used by source files (.cxx).
+# As a module, provides
+# FindPathToHeader(header, includePath) -> path
+# FindHeadersInFile(filePath) -> [headers]
+# FindHeadersInFileRecursive(filePath, includePath, renames) -> [paths]
+# FindDependencies(sourceGlobs, includePath, objExt, startDirectory, renames) -> [dependencies]
+# ExtractDependencies(input) -> [dependencies]
+# TextFromDependencies(dependencies)
+# WriteDependencies(output, dependencies)
+# UpdateDependencies(filepath, dependencies)
+# PathStem(p) -> stem
+# InsertSynonym(dependencies, current, additional) -> [dependencies]
+# If run as a script reads from stdin and writes to stdout.
+# Only tested with ASCII file names.
+# Copyright 2019 by Neil Hodgson <neilh@scintilla.org>
+# The License.txt file describes the conditions under which this software may be distributed.
+# Requires Python 2.7 or later
+
+import codecs, glob, os, sys
+
+from . import FileGenerator
+
+continuationLineEnd = " \\"
+
+def FindPathToHeader(header, includePath):
+ for incDir in includePath:
+ relPath = os.path.join(incDir, header)
+ if os.path.exists(relPath):
+ return relPath
+ return ""
+
+fhifCache = {} # Remember the includes in each file. ~5x speed up.
+def FindHeadersInFile(filePath):
+ if filePath not in fhifCache:
+ headers = []
+ with codecs.open(filePath, "r", "utf-8") as f:
+ for line in f:
+ if line.strip().startswith("#include"):
+ parts = line.split()
+ if len(parts) > 1:
+ header = parts[1]
+ if header[0] != '<': # No system headers
+ headers.append(header.strip('"'))
+ fhifCache[filePath] = headers
+ return fhifCache[filePath]
+
+def FindHeadersInFileRecursive(filePath, includePath, renames):
+ headerPaths = []
+ for header in FindHeadersInFile(filePath):
+ if header in renames:
+ header = renames[header]
+ relPath = FindPathToHeader(header, includePath)
+ if relPath and relPath not in headerPaths:
+ headerPaths.append(relPath)
+ subHeaders = FindHeadersInFileRecursive(relPath, includePath, renames)
+ headerPaths.extend(sh for sh in subHeaders if sh not in headerPaths)
+ return headerPaths
+
+def RemoveStart(relPath, start):
+ if relPath.startswith(start):
+ return relPath[len(start):]
+ return relPath
+
+def ciKey(f):
+ return f.lower()
+
+def FindDependencies(sourceGlobs, includePath, objExt, startDirectory, renames={}):
+ deps = []
+ for sourceGlob in sourceGlobs:
+ sourceFiles = glob.glob(sourceGlob)
+ # Sorting the files minimizes deltas as order returned by OS may be arbitrary
+ sourceFiles.sort(key=ciKey)
+ for sourceName in sourceFiles:
+ objName = os.path.splitext(os.path.basename(sourceName))[0]+objExt
+ headerPaths = FindHeadersInFileRecursive(sourceName, includePath, renames)
+ depsForSource = [sourceName] + headerPaths
+ depsToAppend = [RemoveStart(fn.replace("\\", "/"), startDirectory) for
+ fn in depsForSource]
+ deps.append([objName, depsToAppend])
+ return deps
+
+def PathStem(p):
+ """ Return the stem of a filename: "CallTip.o" -> "CallTip" """
+ return os.path.splitext(os.path.basename(p))[0]
+
+def InsertSynonym(dependencies, current, additional):
+ """ Insert a copy of one object file with dependencies under a different name.
+ Used when one source file is used to create two object files with different
+ preprocessor definitions. """
+ result = []
+ for dep in dependencies:
+ result.append(dep)
+ if (dep[0] == current):
+ depAdd = [additional, dep[1]]
+ result.append(depAdd)
+ return result
+
+def ExtractDependencies(input):
+ """ Create a list of dependencies from input list of lines
+ Each element contains the name of the object and a list of
+ files that it depends on.
+ Dependencies that contain "/usr/" are removed as they are system headers. """
+
+ deps = []
+ for line in input:
+ headersLine = line.startswith(" ") or line.startswith("\t")
+ line = line.strip()
+ isContinued = line.endswith("\\")
+ line = line.rstrip("\\ ")
+ fileNames = line.strip().split(" ")
+ if not headersLine:
+ # its a source file line, there may be headers too
+ sourceLine = fileNames[0].rstrip(":")
+ fileNames = fileNames[1:]
+ deps.append([sourceLine, []])
+ deps[-1][1].extend(header for header in fileNames if "/usr/" not in header)
+ return deps
+
+def TextFromDependencies(dependencies):
+ """ Convert a list of dependencies to text. """
+ text = ""
+ indentHeaders = "\t"
+ joinHeaders = continuationLineEnd + "\n" + indentHeaders
+ for dep in dependencies:
+ object, headers = dep
+ text += object + ":"
+ for header in headers:
+ text += joinHeaders
+ text += header
+ if headers:
+ text += "\n"
+ return text
+
+def UpdateDependencies(filepath, dependencies, comment=""):
+ """ Write a dependencies file if different from dependencies. """
+ FileGenerator.UpdateFile(filepath, comment+TextFromDependencies(dependencies))
+
+def WriteDependencies(output, dependencies):
+ """ Write a list of dependencies out to a stream. """
+ output.write(TextFromDependencies(dependencies))
+
+if __name__ == "__main__":
+ """ Act as a filter that reformats input dependencies to one per line. """
+ inputLines = sys.stdin.readlines()
+ deps = ExtractDependencies(inputLines)
+ WriteDependencies(sys.stdout, deps)
diff --git a/scripts/LexGen.py b/scripts/LexGen.py
index ae7ae99d5..82eb39182 100644
--- a/scripts/LexGen.py
+++ b/scripts/LexGen.py
@@ -14,6 +14,12 @@ from FileGenerator import Regenerate, UpdateLineInFile, \
import ScintillaData
import HFacer
import uuid
+import sys
+
+sys.path.append("../")
+
+import win32.DepGen
+import gtk.DepGen
def UpdateVersionNumbers(sci, root):
UpdateLineInFile(root + "win32/ScintRes.rc", "#define VERSION_SCINTILLA",
@@ -115,6 +121,9 @@ def RegenerateAll(root):
Regenerate(root + "src/Catalogue.cxx", "//", sci.lexerModules)
Regenerate(root + "win32/scintilla.mak", "#", sci.lexFiles)
+ win32.DepGen.Generate()
+ gtk.DepGen.Generate()
+
RegenerateXcodeProject(root + "cocoa/ScintillaFramework/ScintillaFramework.xcodeproj/project.pbxproj",
sci.lexFiles, sci.lexersXcode)
diff --git a/scripts/__init__.py b/scripts/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/scripts/__init__.py