Quellcode durchsuchen

Compile python scripts explicitly instead of compiling an entire folder

Given the fact multiple compile targets can be associated with the same
destination directory, compiling each script explicitly will prevent two
compile targets build in parallel from compiling the same folder.
Jean-Christophe Fillion-Robin vor 12 Jahren
Ursprung
Commit
5800b08f53
1 geänderte Dateien mit 83 neuen und 20 gelöschten Zeilen
  1. 83 20
      CMake/ctkMacroCompilePythonScript.cmake

+ 83 - 20
CMake/ctkMacroCompilePythonScript.cmake

@@ -59,28 +59,21 @@ macro(ctkMacroCompilePythonScript)
     endif()
 
     set(src "${MY_SOURCE_DIR}/${file}")
-    set(tgt "${MY_DESTINATION_DIR}/${file}")
+    set(tgt_file ${file})
     if(IS_ABSOLUTE ${file})
       set(src ${file})
       file(RELATIVE_PATH tgt_file ${CMAKE_CURRENT_BINARY_DIR} ${file})
-      set(tgt "${MY_DESTINATION_DIR}/${tgt_file}")
     endif()
-    
     set_property(GLOBAL APPEND PROPERTY
-      _CTK_${target}_PYTHON_SCRIPTS "${src}|${tgt}")
+      _CTK_${target}_PYTHON_SCRIPTS "${src}|${tgt_file}|${MY_DESTINATION_DIR}")
   endforeach()
-  
-  
-  set_property(GLOBAL APPEND PROPERTY
-      _CTK_${target}_PYTHON_DESTINATION_DIRS "${MY_DESTINATION_DIR}")
       
   if(DEFINED MY_RESOURCES)
     set(resource_input_files)
     foreach(file ${MY_RESOURCES})
       set(src "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
-      set(tgt "${MY_DESTINATION_DIR}/${file}")
       set_property(GLOBAL APPEND PROPERTY
-      _CTK_${target}_PYTHON_RESOURCES "${src}|${tgt}")
+      _CTK_${target}_PYTHON_RESOURCES "${src}|${file}|${MY_DESTINATION_DIR}")
     endforeach()
   endif()
 
@@ -111,12 +104,13 @@ function(_ctk_add_copy_python_files_target target type)
     foreach(entry IN LISTS entries)
       string(REPLACE "|" ";" tuple "${entry}")
       list(GET tuple 0 src)
-      list(GET tuple 1 tgt)
-      get_filename_component(file ${src} NAME)
+      list(GET tuple 1 tgt_file)
+      list(GET tuple 2 dest_dir)
+      set(tgt ${dest_dir}/${tgt_file})
       add_custom_command(DEPENDS ${src}
                          COMMAND ${CMAKE_COMMAND} -E copy ${src} ${tgt}
                          OUTPUT ${tgt}
-                         COMMENT "Copying python ${type}: ${file}")
+                         COMMENT "Copying python ${type}: ${tgt_file}")
       list(APPEND input_files ${src})
       list(APPEND copied_files ${tgt})
     endforeach()
@@ -136,15 +130,19 @@ function(_ctk_add_compile_python_directories_target target)
   if(NOT TARGET ${target_name}) 
     # Byte compile the Python files.
     set(compile_all_script "${CMAKE_CURRENT_BINARY_DIR}/compile_${target}_python_scripts.py")
-    
+
     set(_compileall_code )
-    get_property(destination_dirs GLOBAL PROPERTY _CTK_${target}_PYTHON_DESTINATION_DIRS)
-    list(REMOVE_DUPLICATES destination_dirs)
-    foreach(destination_dir IN LISTS destination_dirs)
-      set(_compileall_code "${_compileall_code}\ncompileall.compile_dir('${destination_dir}')")
+    get_property(entries GLOBAL PROPERTY _CTK_${target}_PYTHON_SCRIPTS)
+    list(REMOVE_DUPLICATES entries)
+    foreach(entry IN LISTS entries)
+      string(REPLACE "|" ";" tuple "${entry}")
+      list(GET tuple 1 tgt_file)
+      list(GET tuple 2 dest_dir)
+      set(tgt ${dest_dir}/${tgt_file})
+      set(_compileall_code "${_compileall_code}\nctk_compile_file('${tgt}', force=1)")
     endforeach()
   
-    message(STATUS "Generate [${target_name}] compileall script: ${compile_all_script}")
+    message(STATUS "Generate [${target_name}] py_compile script: ${compile_all_script}")
     # Generate compile_${target}_python_scripts.py
     file(WRITE ${compile_all_script} "
 #
@@ -153,7 +151,72 @@ function(_ctk_add_compile_python_directories_target target)
 
 # Based on paraview/VTK/Wrapping/Python/compile_all_vtk.py.in
 
-import compileall
+import os
+import sys
+import py_compile
+import struct
+import imp
+
+#
+# Copied function 'compileall.compile_file' introduced in python 2.7 so that code compiled
+# using python 2.6 works.
+#
+# This version of the function has been copied from:
+#   https://github.com/jonashaag/cpython/blob/ce5e5df0c9d8098da05dee26e12ffe2aa331889e/Lib/compileall.py#L61-111
+#
+def ctk_compile_file(fullname, ddir=None, force=0, rx=None, quiet=0):
+    \"\"\"Byte-compile one file.
+
+    Arguments (only fullname is required):
+
+    fullname:  the file to byte-compile
+    ddir:      if given, the directory name compiled in to the
+               byte-code file.
+    force:     if 1, force compilation, even if timestamps are up-to-date
+    quiet:     if 1, be quiet during compilation
+    \"\"\"
+    success = 1
+    name = os.path.basename(fullname)
+    if ddir is not None:
+        dfile = os.path.join(ddir, name)
+    else:
+        dfile = None
+    if rx is not None:
+        mo = rx.search(fullname)
+        if mo:
+            return success
+    if os.path.isfile(fullname):
+        head, tail = name[:-3], name[-3:]
+        if tail == '.py':
+            if not force:
+                try:
+                    mtime = int(os.stat(fullname).st_mtime)
+                    expect = struct.pack('<4sl', imp.get_magic(), mtime)
+                    cfile = fullname + (__debug__ and 'c' or 'o')
+                    with open(cfile, 'rb') as chandle:
+                        actual = chandle.read(8)
+                    if expect == actual:
+                        return success
+                except IOError:
+                    pass
+            if not quiet:
+                print 'Compiling', fullname, '...'
+            try:
+                ok = py_compile.compile(fullname, None, dfile, True)
+            except py_compile.PyCompileError,err:
+                if quiet:
+                    print 'Compiling', fullname, '...'
+                print err.msg
+                success = 0
+            except IOError, e:
+                print "Sorry", e
+                success = 0
+            else:
+                if ok == 0:
+                    success = 0
+    return success
+
+
 @_compileall_code@
 file = open('@CMAKE_CURRENT_BINARY_DIR@/python_compile_@target@_complete', 'w')
 file.write('Done')