@@ -1332,22 +1332,25 @@ def build_extension(
1332
1332
# Run SWIG.
1333
1333
deps_path = f'{ path_cpp } .d'
1334
1334
prerequisites_swig2 = _get_prerequisites ( deps_path )
1335
- if _doit ( path_cpp , path_i , prerequisites_swig , prerequisites_swig2 ):
1336
- run ( f'''
1337
- { swig }
1338
- -Wall
1339
- { "-c++" if cpp else "" }
1340
- -python
1341
- -module { name }
1342
- -outdir { outdir }
1343
- -o { path_cpp }
1344
- -MD -MF { deps_path }
1345
- { includes_text }
1346
- { path_i }
1347
- '''
1348
- )
1349
- else :
1350
- _log (f'Not running swig because up to date: { path_cpp } ' )
1335
+ run_if (
1336
+ f'''
1337
+ { swig }
1338
+ -Wall
1339
+ { "-c++" if cpp else "" }
1340
+ -python
1341
+ -module { name }
1342
+ -outdir { outdir }
1343
+ -o { path_cpp }
1344
+ -MD -MF { deps_path }
1345
+ { includes_text }
1346
+ { path_i }
1347
+ '''
1348
+ ,
1349
+ path_cpp ,
1350
+ path_i ,
1351
+ prerequisites_swig ,
1352
+ prerequisites_swig2 ,
1353
+ )
1351
1354
1352
1355
path_so_leaf = f'_{ name } { _so_suffix ()} '
1353
1356
path_so = f'{ outdir } /{ path_so_leaf } '
@@ -1404,10 +1407,7 @@ def build_extension(
1404
1407
{ defines_text }
1405
1408
{ compiler_extra }
1406
1409
'''
1407
- if _doit ( path_obj , path_cpp , prerequisites_compile ):
1408
- run (command )
1409
- else :
1410
- _log (f'Not compiling because up to date: { path_obj } ' )
1410
+ run_if ( command , path_obj , path_cpp , prerequisites_compile )
1411
1411
1412
1412
command , pythonflags = base_linker (cpp = cpp )
1413
1413
debug2 = '/DEBUG' if debug else ''
@@ -1426,10 +1426,7 @@ def build_extension(
1426
1426
{ path_obj }
1427
1427
{ linker_extra }
1428
1428
'''
1429
- if _doit ( path_so , path_obj , prerequisites_link ):
1430
- run (command )
1431
- else :
1432
- _log (f'Not linking because up to date: { path_so } ' )
1429
+ run_if ( command , path_so , path_obj , prerequisites_link )
1433
1430
1434
1431
else :
1435
1432
@@ -1525,10 +1522,14 @@ def build_extension(
1525
1522
{ linker_extra }
1526
1523
{ pythonflags .ldflags }
1527
1524
'''
1528
- if _doit ( path_so , path_cpp , prerequisites_compile , prerequisites_link , prerequisites ):
1529
- run (command )
1530
- else :
1531
- _log (f'Not compiling+linking because up to date: { path_so } ' )
1525
+ run_if (
1526
+ command ,
1527
+ path_so ,
1528
+ path_cpp ,
1529
+ prerequisites_compile ,
1530
+ prerequisites_link ,
1531
+ prerequisites ,
1532
+ )
1532
1533
1533
1534
if darwin ():
1534
1535
# We need to patch up references to shared libraries in `libs`.
@@ -1548,7 +1549,8 @@ def build_extension(
1548
1549
_log (f'Warning: can not find path of lib={ lib !r} in libpaths={ libpaths } ' )
1549
1550
macos_patch ( path_so , * sublibraries )
1550
1551
1551
- run (f'file { path_so } , check=0' )
1552
+ run (f'ls -l { path_so } ' , check = 0 )
1553
+ run (f'file { path_so } ' , check = 0 )
1552
1554
1553
1555
return path_so_leaf
1554
1556
@@ -1879,52 +1881,127 @@ def _cpu_name():
1879
1881
return f'x{ 32 if sys .maxsize == 2 ** 31 - 1 else 64 } '
1880
1882
1881
1883
1882
- def _doit ( out , in_ , * prerequisites ):
1884
+ def run_if ( command , out , * prerequisites , verbose = True ):
1883
1885
'''
1884
- Returns true/false for whether to run a command .
1886
+ Runs a command only if the output file is not up to date .
1885
1887
1886
- out:
1887
- Output path.
1888
- prerequisites:
1889
- List of input paths or true/false/None. If an item is None it is
1890
- ignored, otherwise if an item is not a string we immediately return it
1891
- cast to a bool.
1892
- '''
1893
- _log ( f'out={ out !r} ' )
1894
- _log ( f'in={ in_ !r} ' )
1895
- def _make_prerequisites (p ):
1896
- if isinstance ( p , (list , tuple )):
1897
- return list (p )
1898
- else :
1899
- return [p ]
1900
- prerequisites_all = list ()
1901
- prerequisites_all .append ( in_ )
1902
- for p in prerequisites :
1903
- prerequisites_all += _make_prerequisites ( p )
1904
- if 0 :
1905
- _log ( 'prerequisites_all:' )
1906
- for i in prerequisites_all :
1907
- _log ( f' { i !r} ' )
1908
- pre_mtime = 0
1909
- pre_path = None
1910
- for prerequisite in prerequisites_all :
1911
- if isinstance ( prerequisite , str ):
1912
- mtime = _fs_mtime_newest ( prerequisite )
1913
- if mtime >= pre_mtime :
1914
- pre_mtime = mtime
1915
- pre_path = prerequisite
1916
- elif prerequisite is None :
1888
+ Args:
1889
+ command:
1890
+ The command to run. We write this into a file <out>.cmd so that we
1891
+ know to run a command if the command itself has changed.
1892
+ out:
1893
+ Path of the output file.
1894
+
1895
+ prerequisites:
1896
+ List of prerequisite paths or true/false/None items. If an item
1897
+ is None it is ignored, otherwise if an item is not a string we
1898
+ immediately return it cast to a bool.
1899
+
1900
+ Returns:
1901
+ True if we ran the command, otherwise None.
1902
+
1903
+
1904
+ If the output file does not exist, the command is run:
1905
+
1906
+ >>> out = 'run_if_test_out'
1907
+ >>> if os.path.exists( out):
1908
+ ... os.remove( out)
1909
+ >>> run_if( f'touch {out}', out, verbose=0)
1910
+ True
1911
+
1912
+ If we repeat, the output file will be up to date so the command is not run:
1913
+
1914
+ >>> run_if( f'touch {out}', out, verbose=0)
1915
+
1916
+ If we change the command, the command is run:
1917
+
1918
+ >>> run_if( f'touch {out}', out, verbose=0)
1919
+ True
1920
+
1921
+ If we add a prerequisite that is newer than the output, the command is run:
1922
+
1923
+ >>> prerequisite = 'run_if_test_prerequisite'
1924
+ >>> run( f'touch {prerequisite}', verbose=0)
1925
+ >>> run_if( f'touch {out}', out, prerequisite, verbose=0)
1926
+ True
1927
+
1928
+ If we repeat, the output will be newer than the prerequisite, so the
1929
+ command is not run:
1930
+
1931
+ >>> run_if( f'touch {out}', out, prerequisite, verbose=1)
1932
+ pipcl.py: run_if(): Not running command because up to date: 'run_if_test_out'
1933
+ '''
1934
+ doit = False
1935
+
1936
+ if not doit :
1937
+ out_mtime = _fs_mtime ( out )
1938
+ if out_mtime == 0 :
1939
+ doit = 'File does not exist: {out!e}'
1940
+
1941
+ cmd_path = f'{ out } .cmd'
1942
+ if os .path .isfile ( cmd_path ):
1943
+ with open ( cmd_path ) as f :
1944
+ cmd = f .read ()
1945
+ else :
1946
+ cmd = None
1947
+ if command != cmd :
1948
+ doit = 'Command has changed'
1949
+
1950
+ if not doit :
1951
+ def _make_prerequisites (p ):
1952
+ if isinstance ( p , (list , tuple )):
1953
+ return list (p )
1954
+ else :
1955
+ return [p ]
1956
+ prerequisites_all = list ()
1957
+ for p in prerequisites :
1958
+ prerequisites_all += _make_prerequisites ( p )
1959
+ if 0 :
1960
+ _log ( 'prerequisites_all:' )
1961
+ for i in prerequisites_all :
1962
+ _log ( f' { i !r} ' )
1963
+ pre_mtime = 0
1964
+ pre_path = None
1965
+ for prerequisite in prerequisites_all :
1966
+ if isinstance ( prerequisite , str ):
1967
+ mtime = _fs_mtime_newest ( prerequisite )
1968
+ if mtime >= pre_mtime :
1969
+ pre_mtime = mtime
1970
+ pre_path = prerequisite
1971
+ elif prerequisite is None :
1972
+ pass
1973
+ elif prerequisite :
1974
+ doit = str (prerequisite )
1975
+ break
1976
+ if not doit :
1977
+ if pre_mtime > out_mtime :
1978
+ doit = f'Prerequisite is new: { pre_path !r} '
1979
+
1980
+ if doit :
1981
+ # Remove `cmd_path` before we run the command, so any failure
1982
+ # will force rerun next time.
1983
+ #
1984
+ try :
1985
+ os .remove ( cmd_path )
1986
+ except Exception :
1917
1987
pass
1918
- else :
1919
- _log ( f'Returning prerequisite={ prerequisite !r} ' )
1920
- return bool (prerequisite )
1921
- out_mtime = _fs_mtime ( out )
1922
- ret = pre_mtime >= out_mtime
1988
+ if verbose :
1989
+ _log ( f'Running command because: { doit } ' )
1990
+
1991
+ run ( command , verbose = verbose )
1992
+
1993
+ # Write the command we ran, into `cmd_path`.
1994
+ with open ( cmd_path , 'w' ) as f :
1995
+ f .write ( command )
1996
+ return True
1997
+ else :
1998
+ if verbose :
1999
+ _log ( f'Not running command because up to date: { out !r} ' )
2000
+
1923
2001
if 0 :
1924
2002
_log ( f'out_mtime={ time .ctime (out_mtime )} pre_mtime={ time .ctime (pre_mtime )} .'
1925
2003
f' pre_path={ pre_path !r} : returning { ret !r} .'
1926
2004
)
1927
- return ret
1928
2005
1929
2006
1930
2007
def _get_prerequisites (path ):
0 commit comments