185 lines
6.5 KiB
Python
Executable File
185 lines
6.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
USAGE = """
|
|
fl-build-all: Builds all rules specified in build.py under the current
|
|
directory.
|
|
|
|
(usage: fl-build-all [--mode={verbose|debug|check|fast|unsafe}]
|
|
[--recursive] )
|
|
|
|
This builds the specified target rule and places links to generated files
|
|
and a Makefile in the current directory. I assume that FASTlib is
|
|
installed here: %s
|
|
This will build code outside of the above FASTlib tree, just be sure other
|
|
external rules can are referred by relative paths like "." or "..".
|
|
|
|
BACKGROUND - BUILD RULES
|
|
|
|
Build rules are named in the form path:name where the path is a relative
|
|
path from the current directory, or absolute from the FASTlib C
|
|
directory. For instance:
|
|
|
|
fastlib:fastlib the 'fastlib' package in root of FASTlib tree
|
|
:helper the rule 'helper' in current directory
|
|
..:parent the rule 'parent' in parent directory
|
|
../sib:sib the rule 'sib' in the sibling directory 'sib'
|
|
|
|
The path specifies where the build.py specifying the rule is. Each
|
|
build.py file specifies what rules are defined for that directory;
|
|
nameless rules take the name of the directory.
|
|
|
|
OPTIONAL COMMAND LINE OPTIONS
|
|
|
|
--mode={verbose|debug|check|fast|unsafe|small} = compilation mode
|
|
[verbose] verbosity messages [debug] "i need to use gdb"
|
|
*[check]* assertions and fast [fast] usually fastest
|
|
[unsafe] bad optimizations [small] code size
|
|
--j={1|2|3...} = number of CPU's to compile with
|
|
--recursive = whether to apply fl-build-all recursively under all
|
|
subdirectories
|
|
"""
|
|
|
|
import buildsys # buildsys.py contains the build system
|
|
import os
|
|
import sys
|
|
import fx
|
|
import util
|
|
|
|
# figure out where fastlib is
|
|
fl_build_path = sys.argv[0]
|
|
script_path = os.path.realpath(os.path.dirname(fl_build_path))
|
|
fastlib_path = os.path.dirname(script_path)
|
|
|
|
# normalize path names and ensure a single '/' at the end of them
|
|
code_path = os.path.realpath(fastlib_path).rstrip(os.sep) + os.sep
|
|
curdir = os.path.realpath(os.getcwd()).rstrip(os.sep) + os.sep
|
|
|
|
if fx.param_exists("help"):
|
|
print USAGE % code_path
|
|
sys.exit(1)
|
|
|
|
if curdir.startswith(code_path):
|
|
# When building inside build system, use relative paths from root
|
|
# of build system.
|
|
print "*** Building from within build system"
|
|
#real_path = curdir[len(code_path):]
|
|
real_rootpath = code_path
|
|
real_path = curdir.rstrip(os.sep)
|
|
fake_path = curdir[len(code_path):].replace(os.sep, "/").rstrip("/")
|
|
else:
|
|
# When building from outside build system, use absolute paths.
|
|
# However, for generated files, we need somewhere to put them within
|
|
# the bin/ directory; se use 'OUTSIDE' to signify this.
|
|
print "*** Building from OUTSIDE build system... cross your fingers!"
|
|
print " - I think the build system is here: %s" % code_path
|
|
print " - This is where you are: %s" % curdir
|
|
real_rootpath = code_path
|
|
real_path = os.path.abspath(curdir).rstrip(os.sep)
|
|
fake_path = "external/" + curdir.replace(os.sep, "/").strip("/")
|
|
|
|
# Create build parameters
|
|
|
|
fx.param_default("cflags", "")
|
|
fx.param_default("mode", "check")
|
|
|
|
check_gcc4_existence = os.popen("which gcc4")
|
|
check_gcc4_existence_result = check_gcc4_existence.read()
|
|
check_gcc4_existence.close()
|
|
check_gcc4_existence_result = check_gcc4_existence_result[:len(check_gcc4_existence_result) - 1]
|
|
if len(check_gcc4_existence_result) > 0:
|
|
fx.param_default("compiler", "gcc4")
|
|
else:
|
|
check_gcc4_existence = os.popen("which gcc-4")
|
|
check_gcc4_existence_result = check_gcc4_existence.read()
|
|
check_gcc4_existence.close()
|
|
check_gcc4_existence_result = check_gcc4_existence_result[:len(check_gcc4_existence_result) - 1]
|
|
if len(check_gcc4_existence_result) > 0:
|
|
fx.param_default("compiler", "gcc-4")
|
|
else:
|
|
fx.param_default("compiler", "gcc")
|
|
|
|
fx.param_default("j", "-1")
|
|
fx.param_default("prefix", "")
|
|
fx.param_default("downloader", "/usr/bin/curl")
|
|
target_name = ":VERYSPECIALPYTHONSTRING"
|
|
|
|
implicit = True
|
|
|
|
target_name = target_name.replace(os.sep, "/")
|
|
|
|
makefile_path = os.path.abspath("./Makefile")
|
|
mode = fx.param_str("mode")
|
|
compiler = fx.param_str("compiler")
|
|
cflags = fx.param_str("cflags")
|
|
(kernel, nodename, release, version, arch) = os.uname()
|
|
arch = util.sanitize_basename(arch)
|
|
kernel = util.sanitize_basename(kernel)
|
|
prefix = fx.param_str("prefix")
|
|
downloader = fx.param_str("downloader")
|
|
|
|
# Get the downloader.
|
|
check_curl_existence = os.popen("which curl")
|
|
check_downloader_existence_result = check_curl_existence.read()
|
|
check_curl_existence.close()
|
|
check_downloader_existence_result = check_downloader_existence_result[:len(check_downloader_existence_result) - 1]
|
|
if len(check_downloader_existence_result) == 0:
|
|
check_wget_existence = os.popen("which wget")
|
|
check_downloader_existence_result = check_wget_existence.read()
|
|
check_wget_existence.close()
|
|
check_downloader_existence_result = check_downloader_existence_result[:len(check_downloader_existence_result) - 1]
|
|
downloader = check_downloader_existence_result
|
|
|
|
# Dispatch
|
|
|
|
print "*** Generating Makefile in current directory"
|
|
|
|
params = dict(arch=arch,kernel=kernel,mode=mode,compiler=compiler, \
|
|
cflags=cflags,prefix=prefix,downloader=downloader)
|
|
|
|
print "*** Target Rule: '%s'" % target_name
|
|
|
|
loader = buildsys.Loader(real_rootpath)
|
|
target_shortname = target_name[target_name.index(":")+1:]
|
|
fx.param_default("lib", "fastlib:fastlib")
|
|
lib = fx.param_str("lib")
|
|
posttext = ""
|
|
|
|
def build_all(real_subpath, fake_subpath, target_name, posttext):
|
|
target = loader.find_rule(target_name, real_subpath, fake_subpath, posttext)
|
|
linkrule = buildsys.SymlinkRule([target], real_subpath)
|
|
linkrule.generate(loader.thebuildsys, params)
|
|
|
|
# TODO: Make symbolic link to result
|
|
makefile_lines = loader.thebuildsys.to_makefile()
|
|
|
|
print "*** Running Makefile"
|
|
|
|
util.writelines(makefile_path, makefile_lines)
|
|
|
|
processors = fx.param_int("j")
|
|
make_args = ["make"]
|
|
if processors >= 0:
|
|
make_args.append("-j%d" % processors)
|
|
|
|
retval = util.spawn_redirect(
|
|
os.path.abspath("."),
|
|
make_args,
|
|
infile = None,
|
|
outfile = None,
|
|
errfile = None)
|
|
return retval
|
|
|
|
if fx.param_exists("recursive"):
|
|
print "Recursive build-all..."
|
|
for (subpath, subdirs, subfiles) in os.walk(curdir):
|
|
if 'build.py' in subfiles:
|
|
real_subpath = subpath.rstrip(os.sep)
|
|
fake_subpath = subpath[len(code_path):].replace(os.sep, "/").rstrip("/")
|
|
build_all(real_subpath, fake_subpath, target_name, posttext)
|
|
else:
|
|
print "Non-recursive build-all..."
|
|
if "build.py" in os.listdir(curdir):
|
|
build_all(real_path, fake_path, target_name, posttext)
|
|
else:
|
|
print "build.py file not found..."
|