Home | History | Annotate | Line # | Download | only in dist
      1 #!/bin/sh
      2 # py-compile - Compile a Python program
      3 
      4 scriptversion=2021-02-27.01; # UTC
      5 
      6 # Copyright (C) 2000-2021 Free Software Foundation, Inc.
      7 
      8 # This program is free software; you can redistribute it and/or modify
      9 # it under the terms of the GNU General Public License as published by
     10 # the Free Software Foundation; either version 2, or (at your option)
     11 # any later version.
     12 
     13 # This program is distributed in the hope that it will be useful,
     14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 # GNU General Public License for more details.
     17 
     18 # You should have received a copy of the GNU General Public License
     19 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
     20 
     21 # As a special exception to the GNU General Public License, if you
     22 # distribute this file as part of a program that contains a
     23 # configuration script generated by Autoconf, you may include it under
     24 # the same distribution terms that you use for the rest of that program.
     25 
     26 # This file is maintained in Automake, please report
     27 # bugs to <bug-automake (at] gnu.org> or send patches to
     28 # <automake-patches (at] gnu.org>.
     29 
     30 if test -z "$PYTHON"; then
     31   PYTHON=python
     32 fi
     33 
     34 me=py-compile
     35 
     36 usage_error ()
     37 {
     38   echo "$me: $*" >&2
     39   echo "Try '$me --help' for more information." >&2
     40   exit 1
     41 }
     42 
     43 basedir=
     44 destdir=
     45 while test $# -ne 0; do
     46   case "$1" in
     47     --basedir)
     48       if test $# -lt 2; then
     49         usage_error "option '--basedir' requires an argument"
     50       else
     51         basedir=$2
     52       fi
     53       shift
     54       ;;
     55     --destdir)
     56       if test $# -lt 2; then
     57         usage_error "option '--destdir' requires an argument"
     58       else
     59         destdir=$2
     60       fi
     61       shift
     62       ;;
     63     -h|--help)
     64       cat <<\EOF
     65 Usage: py-compile [--help] [--version] [--basedir DIR] [--destdir DIR] FILES..."
     66 
     67 Byte compile some python scripts FILES.  Use --destdir to specify any
     68 leading directory path to the FILES that you don't want to include in the
     69 byte compiled file.  Specify --basedir for any additional path information you
     70 do want to be shown in the byte compiled file.
     71 
     72 Example:
     73   py-compile --destdir /tmp/pkg-root --basedir /usr/share/test test.py test2.py
     74 
     75 Report bugs to <bug-automake (at] gnu.org>.
     76 EOF
     77       exit $?
     78       ;;
     79     -v|--version)
     80       echo "$me $scriptversion"
     81       exit $?
     82       ;;
     83     --)
     84       shift
     85       break
     86       ;;
     87     -*)
     88       usage_error "unrecognized option '$1'"
     89       ;;
     90     *)
     91       break
     92       ;;
     93   esac
     94   shift
     95 done
     96 
     97 files=$*
     98 if test -z "$files"; then
     99   usage_error "no files given"
    100 fi
    101 
    102 # if basedir was given, then it should be prepended to filenames before
    103 # byte compilation.
    104 if test -z "$basedir"; then
    105   pathtrans="path = file"
    106 else
    107   pathtrans="path = os.path.join('$basedir', file)"
    108 fi
    109 
    110 # if destdir was given, then it needs to be prepended to the filename to
    111 # byte compile but not go into the compiled file.
    112 if test -z "$destdir"; then
    113   filetrans="filepath = path"
    114 else
    115   filetrans="filepath = os.path.normpath('$destdir' + os.sep + path)"
    116 fi
    117 
    118 python_major=`$PYTHON -V 2>&1 | sed -e 's/.* //;s/\..*$//;1q'`
    119 if test -z "$python_major"; then
    120   echo "$me: could not determine $PYTHON major version, guessing 3" >&2
    121   python_major=3
    122 fi
    123 
    124 # The old way to import libraries was deprecated.
    125 if test "$python_major" -le 2; then
    126   import_lib=imp
    127   import_test="hasattr(imp, 'get_tag')"
    128   import_call=imp.cache_from_source
    129 else
    130   import_lib=importlib
    131   import_test="hasattr(sys.implementation, 'cache_tag')"
    132   import_call=importlib.util.cache_from_source
    133 fi
    134 
    135 $PYTHON -c "
    136 import sys, os, py_compile, $import_lib
    137 
    138 files = '''$files'''
    139 
    140 sys.stdout.write('Byte-compiling python modules...\n')
    141 for file in files.split():
    142     $pathtrans
    143     $filetrans
    144     if not os.path.exists(filepath) or not (len(filepath) >= 3
    145                                             and filepath[-3:] == '.py'):
    146 	    continue
    147     sys.stdout.write(file)
    148     sys.stdout.flush()
    149     if $import_test:
    150         py_compile.compile(filepath, $import_call(filepath), path)
    151     else:
    152         py_compile.compile(filepath, filepath + 'c', path)
    153 sys.stdout.write('\n')" || exit $?
    154 
    155 # this will fail for python < 1.5, but that doesn't matter ...
    156 $PYTHON -O -c "
    157 import sys, os, py_compile, $import_lib
    158 
    159 # pypy does not use .pyo optimization
    160 if hasattr(sys, 'pypy_translation_info') and sys.hexversion < 0x03050000:
    161     sys.exit(0)
    162 
    163 files = '''$files'''
    164 sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n')
    165 for file in files.split():
    166     $pathtrans
    167     $filetrans
    168     if not os.path.exists(filepath) or not (len(filepath) >= 3
    169                                             and filepath[-3:] == '.py'):
    170 	    continue
    171     sys.stdout.write(file)
    172     sys.stdout.flush()
    173     if $import_test:
    174         py_compile.compile(filepath, $import_call(filepath), path)
    175     else:
    176         py_compile.compile(filepath, filepath + 'o', path)
    177 sys.stdout.write('\n')" 2>/dev/null || :
    178 
    179 $PYTHON -OO -c "
    180 import sys, os, py_compile, $import_lib
    181 
    182 # python<3.5 does not have split files for -O and -OO
    183 if sys.hexversion < 0x03050000:
    184     sys.exit(0)
    185 
    186 files = '''$files'''
    187 sys.stdout.write('Byte-compiling python modules (optimized versions) ...\n')
    188 for file in files.split():
    189     $pathtrans
    190     $filetrans
    191     if not os.path.exists(filepath) or not (len(filepath) >= 3
    192                                             and filepath[-3:] == '.py'):
    193 	    continue
    194     sys.stdout.write(file)
    195     sys.stdout.flush()
    196     if $import_test:
    197         py_compile.compile(filepath, $import_call(filepath), path)
    198     else:
    199         py_compile.compile(filepath, filepath + 'o', path)
    200 sys.stdout.write('\n')" 2>/dev/null || exit $?
    201 
    202 # Local Variables:
    203 # mode: shell-script
    204 # sh-indentation: 2
    205 # eval: (add-hook 'before-save-hook 'time-stamp)
    206 # time-stamp-start: "scriptversion="
    207 # time-stamp-format: "%:y-%02m-%02d.%02H"
    208 # time-stamp-time-zone: "UTC0"
    209 # time-stamp-end: "; # UTC"
    210 # End:
    211