2019-06-19 16:51:22 +00:00
#!/usr/bin/env python3
# This script enables easy, cross-platform building without the need
# to install third-party Python modules.
2019-08-19 10:19:06 +00:00
LXBUILDENV_VERSION = ' 2019.8.19.1 '
2019-06-19 16:51:22 +00:00
import sys
import os
import subprocess
import argparse
DEPS_DIR = " deps "
DEFAULT_DEPS = {
' migen ' : ' https://github.com/m-labs/migen.git ' ,
' litex ' : ' https://github.com/enjoy-digital/litex.git ' ,
' litedram ' : ' https://github.com/enjoy-digital/litedram.git ' ,
' litex_boards ' : ' https://github.com/litex-hub/litex-boards.git ' ,
' litescope ' : ' https://github.com/enjoy-digital/litescope.git ' ,
' pyserial ' : ' https://github.com/pyserial/pyserial.git ' ,
}
OPTIONAL_DEPS = {
' liteeth ' : ' https://github.com/enjoy-digital/liteeth.git ' ,
' liteusb ' : ' https://github.com/enjoy-digital/liteusb.git ' ,
' litepcie ' : ' https://github.com/enjoy-digital/litepcie.git ' ,
' litesdcard ' : ' https://github.com/enjoy-digital/litesdcard.git ' ,
' liteiclink ' : ' https://github.com/enjoy-digital/liteiclink.git ' ,
' litevideo ' : ' https://github.com/enjoy-digital/litevideo.git ' ,
' usb ' : ' https://github.com/pyusb/pyusb.git ' ,
}
# Obtain the path to this script, plus a trailing separator. This will
# be used later on to construct various environment variables for paths
# to a variety of support directories.
script_path = os . path . dirname ( os . path . realpath ( __file__ ) ) + os . path . sep
# Look through the specified file for known variables to get the dependency list
2019-08-19 10:19:06 +00:00
def read_configuration ( filename , args ) :
2019-06-19 16:51:22 +00:00
import ast
# Always check the Python version
dependencies = {
' python ' : 1
}
2019-06-20 15:31:48 +00:00
configuration = {
' skip-git ' : False
}
2019-06-19 16:51:22 +00:00
main_src = " "
try :
with open ( sys . argv [ 0 ] , ' r ' ) as f :
main_src = f . read ( )
main_ast = ast . parse ( main_src , filename = filename )
except :
2019-06-20 15:31:48 +00:00
configuration [ ' dependencies ' ] = list ( dependencies . keys ( ) )
return configuration
2019-06-19 16:51:22 +00:00
# Iterate through the top-level nodes looking for variables named
# LX_DEPENDENCIES or LX_DEPENDENCY and get the values that are
# assigned to them.
for node in ast . iter_child_nodes ( main_ast ) :
if isinstance ( node , ast . Assign ) :
value = node . value
for target in node . targets :
if isinstance ( target , ast . Name ) :
if target . id == " LX_DEPENDENCIES " or target . id == " LX_DEPENDENCY " :
if isinstance ( value , ( ast . List , ast . Tuple ) ) :
for elt in value . elts :
if isinstance ( elt , ast . Str ) :
dependencies [ elt . s ] = 1
elif isinstance ( value , ast . Str ) :
dependencies [ value . s ] = 1
2019-06-20 15:31:48 +00:00
elif target . id == " LX_CONFIGURATION " or target . id == " LX_CONFIG " :
if isinstance ( value , ( ast . List , ast . Tuple ) ) :
for elt in value . elts :
if isinstance ( elt , ast . Str ) :
configuration [ elt . s ] = True
elif isinstance ( value , ast . Str ) :
configuration [ value . s ] = True
2019-06-19 16:51:22 +00:00
# Set up sub-dependencies
if ' riscv ' in dependencies :
dependencies [ ' make ' ] = 1
2019-08-19 10:21:17 +00:00
if args . lx_check_git or ( not configuration [ ' skip-git ' ] and not args . lx_ignore_git ) :
2019-06-20 15:31:48 +00:00
dependencies [ ' git ' ] = 1
configuration [ ' dependencies ' ] = list ( dependencies . keys ( ) )
return configuration
2019-06-19 16:51:22 +00:00
def get_python_path ( script_path , args ) :
# Python has no concept of a local dependency path, such as the C `-I``
# switch, or the nodejs `node_modules` path, or the rust cargo registry.
# Instead, it relies on an environment variable to append to the search
# path.
# Construct this variable by adding each subdirectory under the `deps/`
# directory to the PYTHONPATH environment variable.
python_path = [ ]
if os . path . isdir ( script_path + DEPS_DIR ) :
for dep in os . listdir ( script_path + DEPS_DIR ) :
dep = script_path + DEPS_DIR + os . path . sep + dep
if os . path . isdir ( dep ) :
python_path . append ( dep )
return python_path
def fixup_env ( script_path , args ) :
os . environ [ " PYTHONPATH " ] = os . pathsep . join ( get_python_path ( script_path , 0 ) )
# Set the "LXBUILDENV_REEXEC" variable to prevent the script from continuously
# reinvoking itself.
os . environ [ " LXBUILDENV_REEXEC " ] = " 1 "
# Python randomizes the order in which it traverses hashes, and Migen uses
# hashes an awful lot when bringing together modules. As such, the order
# in which Migen generates its output Verilog will change with every run,
# and the addresses for various modules will change.
# Make builds deterministic so that the generated Verilog code won't change
# across runs.
os . environ [ " PYTHONHASHSEED " ] = " 1 "
# Some Makefiles are invoked as part of the build process, and those Makefiles
# occasionally have calls to Python. Ensure those Makefiles use the same
# interpreter that this script is using.
os . environ [ " PYTHON " ] = sys . executable
# Set the environment variable "V" to 1. This causes Makefiles to print
# the commands they run, which makes them easier to debug.
if " lx_verbose " in args and args . lx_verbose :
os . environ [ " V " ] = " 1 "
# If the user just wanted to print the environment variables, do that and quit.
if args . lx_print_env :
print ( " PYTHONPATH= {} " . format ( os . environ [ " PYTHONPATH " ] ) )
print ( " PYTHONHASHSEED= {} " . format ( os . environ [ " PYTHONHASHSEED " ] ) )
print ( " PYTHON= {} " . format ( sys . executable ) )
print ( " LXBUILDENV_REEXEC= {} " . format ( os . environ [ " LXBUILDENV_REEXEC " ] ) )
sys . exit ( 0 )
# Equivalent to the powershell Get-Command, and kinda like `which`
def get_command ( cmd ) :
if os . name == ' nt ' :
path_ext = os . environ [ " PATHEXT " ] . split ( os . pathsep )
else :
path_ext = [ " " ]
for ext in path_ext :
for path in os . environ [ " PATH " ] . split ( os . pathsep ) :
if os . path . exists ( path + os . path . sep + cmd + ext ) :
return path + os . path . sep + cmd + ext
return None
def check_python_version ( args ) :
import platform
# Litex / Migen require Python 3.5 or newer. Ensure we're running
# under a compatible version of Python.
if sys . version_info [ : 3 ] < ( 3 , 5 ) :
return ( False ,
" python: You need Python 3.5+ (version {} found) " . format ( sys . version_info [ : 3 ] ) )
return ( True , " python 3.5+: ok (Python {} found) " . format ( platform . python_version ( ) ) )
def check_vivado ( args ) :
vivado_path = get_command ( " vivado " )
if vivado_path == None :
# Look for the default Vivado install directory
if os . name == ' nt ' :
base_dir = r " C: \ Xilinx \ Vivado "
else :
base_dir = " /opt/Xilinx/Vivado "
if os . path . exists ( base_dir ) :
for file in os . listdir ( base_dir ) :
bin_dir = base_dir + os . path . sep + file + os . path . sep + " bin "
if os . path . exists ( bin_dir + os . path . sep + " vivado " ) :
os . environ [ " PATH " ] + = os . pathsep + bin_dir
vivado_path = bin_dir
break
if vivado_path == None :
return ( False , " toolchain not found in your PATH " , " download it from https://www.xilinx.com/support/download.html " )
return ( True , " found at {} " . format ( vivado_path ) )
def check_cmd ( args , cmd , name = None , fix = None ) :
if name is None :
name = cmd
path = get_command ( cmd )
if path == None :
return ( False , name + " not found in your PATH " , fix )
return ( True , " found at {} " . format ( path ) )
def check_make ( args ) :
return check_cmd ( args , " make " , " GNU Make " )
def check_riscv ( args ) :
riscv64 = check_cmd ( args , " riscv64-unknown-elf-gcc " , " riscv toolchain " , " download it from https://www.sifive.com/boards/ " )
if riscv64 [ 0 ] == True :
return riscv64
riscv32 = check_cmd ( args , " riscv32-unknown-elf-gcc " , " riscv toolchain " , " download it from https://www.sifive.com/boards/ " )
if riscv32 [ 0 ] == True :
return riscv32
return riscv64
def check_yosys ( args ) :
return check_cmd ( args , " yosys " )
def check_arachne ( args ) :
return check_cmd ( args , " arachne-pnr " )
2019-06-20 15:31:48 +00:00
def check_git ( args ) :
return check_cmd ( args , " git " )
2019-06-19 16:51:22 +00:00
def check_icestorm ( args ) :
2019-08-19 10:19:06 +00:00
return check_cmd ( args , " icepack " )
def check_nextpnr_ice40 ( args ) :
return check_cmd ( args , " nextpnr-ice40 " )
2019-06-19 16:51:22 +00:00
dependency_checkers = {
' python ' : check_python_version ,
' vivado ' : check_vivado ,
' make ' : check_make ,
2019-06-20 15:31:48 +00:00
' git ' : check_git ,
2019-06-19 16:51:22 +00:00
' riscv ' : check_riscv ,
' yosys ' : check_yosys ,
' arachne-pnr ' : check_arachne ,
' icestorm ' : check_icestorm ,
2019-08-19 10:19:06 +00:00
' nextpnr-ice40 ' : check_nextpnr_ice40 ,
2019-06-19 16:51:22 +00:00
}
# Validate that the required dependencies (Vivado, compilers, etc.)
# have been installed.
def check_dependencies ( args , dependency_list ) :
dependency_errors = 0
for dependency_name in dependency_list :
if not dependency_name in dependency_checkers :
2019-08-19 10:19:06 +00:00
print ( ' lxbuildenv: WARNING: Unrecognized dependency " {} " ' . format ( dependency_name ) )
2019-06-19 16:51:22 +00:00
continue
result = dependency_checkers [ dependency_name ] ( args )
if result [ 0 ] == False :
if len ( result ) > 2 :
2019-08-19 10:19:06 +00:00
print ( ' lxbuildenv: {} : {} -- {} ' . format ( dependency_name , result [ 1 ] , result [ 2 ] ) )
2019-06-19 16:51:22 +00:00
else :
2019-08-19 10:19:06 +00:00
print ( ' lxbuildenv: {} : {} ' . format ( dependency_name , result [ 1 ] ) )
2019-06-19 16:51:22 +00:00
dependency_errors = dependency_errors + 1
elif args . lx_check_deps or args . lx_verbose :
2019-08-19 10:19:06 +00:00
print ( ' lxbuildenv: dependency: {} : {} ' . format ( dependency_name , result [ 1 ] ) )
2019-06-19 16:51:22 +00:00
if dependency_errors > 0 :
if args . lx_ignore_deps :
2019-08-19 10:19:06 +00:00
if not args . lx_quiet :
print ( ' lxbuildenv: {} missing dependencies were found but continuing anyway ' . format ( dependency_errors ) )
2019-06-19 16:51:22 +00:00
else :
2019-08-19 10:19:06 +00:00
if not args . lx_quiet :
print ( ' lxbuildenv: To ignore dependencies, re-run with " --lx-ignore-deps " ' )
2019-06-19 16:51:22 +00:00
raise SystemExit ( str ( dependency_errors ) +
" missing dependencies were found " )
if args . lx_check_deps :
sys . exit ( 0 )
# Return True if the given tree needs to be initialized
def check_module_recursive ( root_path , depth , verbose = False , breadcrumbs = [ ] ) :
if verbose :
print ( ' git-dep: checking if " {} " requires updating (depth: {} )... ' . format ( root_path , depth ) )
# If the directory isn't a valid git repo, initialization is required
git_dir_cmd = subprocess . Popen ( [ " git " , " rev-parse " , " --show-toplevel " ] ,
cwd = root_path ,
stdout = subprocess . PIPE ,
stderr = subprocess . PIPE )
( git_stdout , _ ) = git_dir_cmd . communicate ( )
if git_dir_cmd . wait ( ) != 0 :
if verbose :
print ( ' git-dep: missing git directory, starting update... ' )
return True
git_dir = git_stdout . decode ( ) . strip ( )
if git_dir in breadcrumbs :
if verbose :
print ( ' git-dep: root path {} is not in git path ' . format ( root_path ) )
return True
breadcrumbs . append ( git_dir )
if not os . path . exists ( git_dir + os . path . sep + ' .git ' ) :
if verbose :
print ( ' git-dep: .git not found in " {} " ' . format ( git_dir ) )
return True
# If there are no submodules, no initialization needs to be done
if not os . path . isfile ( git_dir + os . path . sep + ' .gitmodules ' ) :
if verbose :
print ( ' git-dep: .gitmodules not found in " {} " , so not updating ' . format ( git_dir ) )
return False
# Loop through the gitmodules to check all submodules
gitmodules = open ( git_dir + os . path . sep + ' .gitmodules ' , ' r ' )
for line in gitmodules :
parts = line . split ( " = " , 2 )
if parts [ 0 ] . strip ( ) == " path " :
path = parts [ 1 ] . strip ( )
if check_module_recursive ( git_dir + os . path . sep + path , depth + 1 , verbose = verbose , breadcrumbs = breadcrumbs ) :
return True
return False
# Determine whether we need to invoke "git submodules init --recurse"
def check_submodules ( script_path , args ) :
if check_module_recursive ( script_path , 0 , verbose = args . lx_verbose ) :
2019-08-19 10:19:06 +00:00
if not args . lx_quiet :
print ( " lxbuildenv: Missing git submodules -- updating " )
print ( " lxbuildenv: To ignore git issues, re-run with --lx-ignore-git " )
2019-06-19 16:51:22 +00:00
subprocess . Popen ( [ " git " , " submodule " , " update " ,
" --init " , " --recursive " ] , cwd = script_path ) . wait ( )
elif args . lx_verbose :
2019-08-19 10:19:06 +00:00
if not args . lx_quiet :
print ( " lxbuildenv: Submodule check: Submodules found " )
2019-06-19 16:51:22 +00:00
def lx_git ( cmd , * args ) :
import subprocess
git_cmd = [ " git " , cmd ]
if args is not None :
for arg in args :
git_cmd = git_cmd + [ arg ]
subprocess . call ( git_cmd )
def lx_print_deps ( ) :
2019-08-19 10:19:06 +00:00
print ( ' lxbuildenv: Supported dependencies: ' )
2019-06-19 16:51:22 +00:00
for dep in dependency_checkers . keys ( ) :
2019-08-19 10:19:06 +00:00
print ( ' lxbuildenv: {} ' . format ( dep ) )
print ( ' lxbuildenv: To define a dependency, add a variable inside {} at the top level called LX_DEPENDENCIES and assign it a list or tuple. ' . format ( sys . argv [ 0 ] ) )
print ( ' lxbuildenv: For example: ' )
print ( ' lxbuildenv: LX_DEPENDENCIES = ( " riscv " , " vivado " ) ' )
2019-06-19 16:51:22 +00:00
def lx_main ( args ) :
if args . lx_print_env :
fixup_env ( script_path , args )
elif args . lx_print_deps :
lx_print_deps ( )
elif args . lx_run is not None :
script_name = args . lx_run [ 0 ]
2019-08-19 10:19:06 +00:00
config = read_configuration ( script_name , args )
2019-06-19 16:51:22 +00:00
fixup_env ( script_path , args )
2019-06-20 15:31:48 +00:00
if not config [ ' skip-git ' ] :
check_submodules ( script_path , args )
2019-06-19 16:51:22 +00:00
try :
sys . exit ( subprocess . Popen (
[ sys . executable ] + [ script_name ] + args . lx_run [ 1 : ] ) . wait ( ) )
except :
sys . exit ( 1 )
elif args . init :
if args . main is None :
main_name = os . getcwd ( ) . split ( os . path . sep ) [ - 1 ] + ' .py '
2019-08-19 10:19:06 +00:00
new_main_name = input ( ' lxbuildenv: What would you like your main program to be called? [ ' + main_name + ' ] ' )
2019-06-19 16:51:22 +00:00
if new_main_name is not None and new_main_name != " " :
main_name = new_main_name
else :
main_name = args . main
if not main_name . endswith ( ' .py ' ) :
main_name = main_name + ' .py '
if args . no_git :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: skipping git initialization " )
2019-06-19 16:51:22 +00:00
else :
if not os . path . exists ( DEPS_DIR ) :
os . mkdir ( DEPS_DIR )
if not os . path . exists ( " .git " ) :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: initializing git repository " )
2019-06-19 16:51:22 +00:00
lx_git ( ' init ' )
else :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: using existing git repository " )
2019-06-19 16:51:22 +00:00
lx_git ( ' add ' , str ( __file__ ) )
for dep_name , dep_url in DEFAULT_DEPS . items ( ) :
dest_path = ' {} {} {} ' . format ( DEPS_DIR , ' / ' , dep_name )
if not os . path . exists ( dest_path ) :
lx_git ( ' submodule ' , ' add ' , dep_url , dest_path )
lx_git ( ' add ' , dest_path )
lx_git ( ' submodule ' , ' update ' , ' --init ' , ' --recursive ' )
if args . no_bin :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: skipping bin/ initialization " )
2019-06-19 16:51:22 +00:00
elif os . path . exists ( " bin " ) :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: bin/ directory exists -- remove bin/ directory to re-initialize " )
2019-06-19 16:51:22 +00:00
else :
bin_tools = {
' mkmscimg ' : ' litex.soc.software.mkmscimg ' ,
' litex_term ' : ' litex.tools.litex_term ' ,
' litex_server ' : ' litex.tools.litex_server ' ,
' litex_sim ' : ' litex.tools.litex_sim ' ,
' litex_read_verilog ' : ' litex.tools.litex_read_verilog ' ,
' litex_simple ' : ' litex.boards.targets.simple ' ,
}
bin_template = """ #!/usr/bin/env python3
import sys
import os
# This script lives in the "bin" directory, but uses a helper script in the parent
# directory. Obtain the current path so we can get the absolute parent path.
script_path = os . path . dirname ( os . path . realpath (
__file__ ) ) + os . path . sep + os . path . pardir + os . path . sep
sys . path . insert ( 0 , script_path )
import lxbuildenv
"""
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: Creating binaries " )
2019-06-19 16:51:22 +00:00
os . mkdir ( " bin " )
for bin_name , python_module in bin_tools . items ( ) :
with open ( ' bin ' + os . path . sep + bin_name , ' w ' , newline = ' \n ' ) as new_bin :
new_bin . write ( bin_template )
new_bin . write ( ' from ' + python_module + ' import main \n ' )
new_bin . write ( ' main() \n ' )
import stat
os . chmod ( ' bin ' + os . path . sep + bin_name , stat . S_IRUSR | stat . S_IRGRP | stat . S_IROTH | stat . S_IXUSR | stat . S_IXGRP | stat . S_IXOTH )
if not args . no_git :
lx_git ( ' add ' , ' --chmod=+x ' , ' bin ' + os . path . sep + bin_name )
if os . path . exists ( main_name ) :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: skipping creation of {} : file exists " . format ( main_name ) )
2019-06-19 16:51:22 +00:00
else :
2019-08-19 10:19:06 +00:00
print ( " lxbuildenv: creating main program {} " . format ( main_name ) )
2019-06-19 16:51:22 +00:00
with open ( main_name , ' w ' ) as m :
program_template = """ #!/usr/bin/env python3
# This variable defines all the external programs that this module
# relies on. lxbuildenv reads this variable in order to ensure
# the build will finish without exiting due to missing third-party
# programs.
LX_DEPENDENCIES = [ " riscv " , " vivado " ]
# Import lxbuildenv to integrate the deps/ directory
import lxbuildenv
# Disable pylint's E1101, which breaks completely on migen
#pylint:disable=E1101
from migen import *
from litex . build . xilinx import VivadoProgrammer , XilinxPlatform
from litex . build . generic_platform import Pins , IOStandard
from litex . soc . integration import SoCSDRAM
from litex . soc . integration . builder import Builder
from litex . soc . integration . soc_core import csr_map_update
_io = [
( " clk50 " , 0 , Pins ( " J19 " ) , IOStandard ( " LVCMOS33 " ) ) ,
]
class Platform ( XilinxPlatform ) :
def __init__ ( self , toolchain = " vivado " , programmer = " vivado " , part = " 35 " ) :
part = " xc7a " + part + " t-fgg484-2 "
def create_programmer ( self ) :
if self . programmer == " vivado " :
return VivadoProgrammer ( flash_part = " n25q128-3.3v-spi-x1_x2_x4 " )
else :
raise ValueError ( " {} programmer is not supported "
. format ( self . programmer ) )
def do_finalize ( self , fragment ) :
XilinxPlatform . do_finalize ( self , fragment )
class BaseSoC ( SoCSDRAM ) :
csr_peripherals = [
" ddrphy " ,
# "dna",
" xadc " ,
" cpu_or_bridge " ,
]
csr_map_update ( SoCSDRAM . csr_map , csr_peripherals )
def __init__ ( self , platform , * * kwargs ) :
clk_freq = int ( 100e6 )
def main ( ) :
platform = Platform ( )
soc = BaseSoC ( platform )
builder = Builder ( soc , output_dir = " build " , csr_csv = " test/csr.csv " )
vns = builder . build ( )
soc . do_exit ( vns )
if __name__ == " __main__ " :
main ( )
"""
m . write ( program_template )
if not args . no_git :
lx_git ( " add " , main_name )
else :
return False
return True
# For the main command, parse args and hand it off to main()
if __name__ == " __main__ " :
parser = argparse . ArgumentParser (
description = " Wrap Python code to enable quickstart " ,
add_help = False )
parser . add_argument (
" -h " , " --help " , ' --lx-help ' , help = " show this help message and exit " , action = " help "
)
parser . add_argument (
' -i ' , ' --init ' , ' --lx-init ' , help = ' initialize a new project ' , action = " store_true "
)
parser . add_argument (
' -m ' , ' --main ' , ' --lx-main ' , help = ' name of main project '
)
parser . add_argument (
' --no-bin ' , ' --lx-no-bin ' , help = " don ' t create a bin/ directory "
)
parser . add_argument (
' --no-git ' , ' --lx-no-git ' , help = " Don ' t create a git repository "
)
parser . add_argument (
' -e ' , ' --print-env ' , ' --lx-print-env ' , dest = " lx_print_env " , help = " print environment variable listing for pycharm, vscode, or bash " , action = " store_true "
)
parser . add_argument (
' -d ' , ' --print-deps ' , ' --lx-print-deps ' , dest = " lx_print_deps " , help = " print all possible dependencies and then exit " , action = " store_true "
)
parser . add_argument (
" --lx-verbose " , help = " increase verboseness of some processes " , action = " store_true "
)
parser . add_argument (
' -r ' , ' --run ' , ' --lx-run ' , dest = ' lx_run ' , help = " run the given script under lxbuildenv " , nargs = argparse . REMAINDER
)
args = parser . parse_args ( )
if not lx_main ( args ) :
parser . print_help ( )
elif not os . path . isfile ( sys . argv [ 0 ] ) :
print ( " lxbuildenv doesn ' t operate while in interactive mode " )
elif " LXBUILDENV_REEXEC " not in os . environ :
parser = argparse . ArgumentParser (
description = " Wrap Python code to enable quickstart " ,
add_help = False )
parser . add_argument (
" --lx-verbose " , help = " increase verboseness of some processes " , action = " store_true "
)
2019-08-19 10:19:06 +00:00
parser . add_argument (
" --lx-quiet " , help = " decrease verboseness of some processes " , action = " store_true "
)
2019-06-19 16:51:22 +00:00
parser . add_argument (
" --lx-print-env " , help = " print environment variable listing for pycharm, vscode, or bash " , action = " store_true "
)
parser . add_argument (
" --lx-check-deps " , help = " check build environment for dependencies such as compiler and fpga tools and then exit " , action = " store_true "
)
parser . add_argument (
" --lx-print-deps " , help = " print all possible dependencies and then exit " , action = " store_true "
)
parser . add_argument (
" --lx-help " , action = " help "
)
parser . add_argument (
" --lx-ignore-deps " , help = " try building even if dependencies are missing " , action = " store_true "
)
2019-08-19 10:19:06 +00:00
parser . add_argument (
" --lx-ignore-git " , help = " don ' t do a check of the git repo " , action = " store_true "
)
parser . add_argument (
" --lx-check-git " , help = " force a git check even if it ' s otherwise disabled " , action = " store_true "
)
2019-06-19 16:51:22 +00:00
( args , rest ) = parser . parse_known_args ( )
2019-08-19 10:19:06 +00:00
if not args . lx_quiet :
print ( " lxbuildenv: v {} (run {} --lx-help for help) " . format ( LXBUILDENV_VERSION , sys . argv [ 0 ] ) )
2019-06-19 16:51:22 +00:00
if args . lx_print_deps :
lx_print_deps ( )
sys . exit ( 0 )
2019-08-19 10:19:06 +00:00
config = read_configuration ( sys . argv [ 0 ] , args )
2019-06-20 15:31:48 +00:00
deps = config [ ' dependencies ' ]
2019-06-19 16:51:22 +00:00
fixup_env ( script_path , args )
check_dependencies ( args , deps )
2019-08-19 10:19:06 +00:00
if args . lx_check_git :
check_submodules ( script_path , args )
elif config [ ' skip-git ' ] :
if not args . lx_quiet :
print ( ' lxbuildenv: Skipping git configuration because " skip-git " was found in LX_CONFIGURATION ' )
print ( ' lxbuildenv: To fetch from git, run {} --lx-check-git ' . format ( " " . join ( sys . argv ) ) )
elif args . lx_ignore_git :
if not args . lx_quiet :
print ( ' lxbuildenv: Skipping git configuration because " --lx-ignore-git " Was specified ' )
else :
2019-06-20 15:31:48 +00:00
check_submodules ( script_path , args )
2019-06-19 16:51:22 +00:00
try :
sys . exit ( subprocess . Popen (
[ sys . executable ] + [ sys . argv [ 0 ] ] + rest ) . wait ( ) )
except :
sys . exit ( 1 )
else :
# Overwrite the deps directory.
# Because we're running with a predefined PYTHONPATH, you'd think that
# the DEPS_DIR would be first.
# Unfortunately, setuptools causes the sitewide packages to take precedence
# over the PYTHONPATH variable.
# Work around this bug by inserting paths into the first index.
for path in get_python_path ( script_path , None ) :
sys . path . insert ( 0 , path )