2011-03-26 Adam Barth <abarth@webkit.org>
authorabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Mar 2011 14:38:43 +0000 (14:38 +0000)
committerabarth@webkit.org <abarth@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Mar 2011 14:38:43 +0000 (14:38 +0000)
        Reviewed by Eric Seidel.

        We shouldn't bother running GYP if the generated files are newer than the GYP files
        https://bugs.webkit.org/show_bug.cgi?id=57146

        In the common case, this check will avoid any overhead from processing
        the GYP files.  Another approach to doing this is to add the feature to
        GYP directly, but GYP's approach to this problem is to compute the
        output in its entirety and compare it byte-for-byte against the output
        file.  In the future, it might make sense to add this approach as an
        alternative approach for GYP itself.

        I also removed JavaScriptGlue from the script because we're not really
        going to change JavaScriptGlue over to GYP.  We were using
        JavaScriptGlue as a learning experience.

        * Source/gyp/configure:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@82030 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
Source/gyp/configure

index 86d20e0..1bba659 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2011-03-26  Adam Barth  <abarth@webkit.org>
+
+        Reviewed by Eric Seidel.
+
+        We shouldn't bother running GYP if the generated files are newer than the GYP files
+        https://bugs.webkit.org/show_bug.cgi?id=57146
+
+        In the common case, this check will avoid any overhead from processing
+        the GYP files.  Another approach to doing this is to add the feature to
+        GYP directly, but GYP's approach to this problem is to compute the
+        output in its entirety and compare it byte-for-byte against the output
+        file.  In the future, it might make sense to add this approach as an
+        alternative approach for GYP itself.
+
+        I also removed JavaScriptGlue from the script because we're not really
+        going to change JavaScriptGlue over to GYP.  We were using
+        JavaScriptGlue as a learning experience.
+
+        * Source/gyp/configure:
+
 2011-03-25  Kevin Ollivier  <kevino@theolliviers.com>
 
         [wx] Build fix, don't use the new FPD implementation yet, until we can merge ours with it.
index 84a985c..28d6677 100755 (executable)
 import os
 import subprocess
 
+from optparse import OptionParser
 
-PROJECTS = [
-    "JavaScriptGlue",
-    "JavaScriptCore",
-    "WebCore",
-]
+def chdir_to_source():
+    source_directory = os.path.abspath(os.path.join(__file__, '..', '..'))
+    os.chdir(source_directory)
+
+def gyp():
+    return os.path.join('ThirdParty', 'gyp', 'gyp')
 
+class Project:
+    def __init__(self, name):
+        self._name = name
 
-def create_project(project):
-    subprocess.call([
-        os.path.join('ThirdParty', 'gyp', 'gyp'),
-        os.path.join(project, 'gyp', project + '.gyp'),
-        '-G',
-        'xcode_list_excluded_files=0',
-        '--depth=.',
-    ])
+    def name(self):
+        return self._name
 
+    def inputs(self):
+        return [
+            os.path.join(self._name, 'gyp', self._name + '.gyp'),
+            os.path.join(self._name, self._name + '.gypi'),
+            os.path.join('gyp', 'common.gypi'),
+        ]
 
-def create_all_projects():
-    for project in PROJECTS:
-        create_project(project)
+    def output(self):
+        return os.path.join(self._name, 'gyp', self._name + '.xcodeproj', 'project.pbxproj')
 
+    def should_generate(self):
+        if not os.path.exists(self.output()):
+            return True
+        return os.path.getmtime(self.output()) < self._newest(self.inputs())
+
+    def generate(self):
+        subprocess.call([
+            gyp(),
+            self.inputs()[0],
+            '-G',
+            'xcode_list_excluded_files=0',
+            '--depth=.',
+        ])
+        # GYP doesn't always touch the output file, but we want to touch the
+        # file so that we don't keep trying to regenerate it.
+        os.utime(self.output(), None)
+
+    @staticmethod
+    def _newest(paths):
+        return max([os.path.getmtime(path) for path in paths])
+
+PROJECTS = [
+    Project("JavaScriptCore"),
+    Project("WebCore"),
+]
+
+def projects_to_generate():
+    should_generate = [project for project in PROJECTS if project.should_generate()]
+    already_generated = [project.name() for project in set(PROJECTS) - set(should_generate)]
+
+    if already_generated:
+        print "Not generating %s because the generated files exist and are newer than the GYP files." % ', '.join(already_generated)
+        print "Pass --regenerate-projects to override."
+
+    return should_generate
 
 def main():
-    source_directory = os.path.abspath(os.path.join(__file__, '..', '..'))
-    os.chdir(source_directory)
+    chdir_to_source()
+
+    parser = OptionParser()
     # FIXME: The user should be able to pass which port on the command line.
-    create_all_projects()
+    parser.add_option("--regenerate-projects", dest="regenerate_projects",
+                      default=False, action="store_true",
+                      help="Generate all project files even if they appear to be up to date.")
+    (options, args) = parser.parse_args()
+
+    projects = PROJECTS
+    if not options.regenerate_projects:
+        projects = projects_to_generate()
 
+    for project in projects:
+        print "Generating %s." % project.name()
+        project.generate()
 
 if __name__ == "__main__":
     main()