import sys import os import shutil import multiprocessing import SCons.Util ## Configuration opts = Variables('Local.sc') opts.AddVariables( ("CC", "C Compiler"), ("CXX", "C++ Compiler"), ("AS", "Assembler"), ("LINK", "Linker"), ("BUILDTYPE", "Build type (RELEASE, DEBUG, or PERF)", "RELEASE"), ("VERBOSE", "Show full build information (0 or 1)", "0"), ("NUMCPUS", "Number of CPUs to use for build (0 means auto).", "0"), ("WITH_GPROF", "Include gprof profiling (0 or 1).", "0"), ("PREFIX", "Installation target directory.", "#pxelinux"), ("ARCH", "Target Architecture", "amd64"), ("BOOTDISK_SIZE", "Boot disk size", "128") ) env = Environment(options = opts, tools = ['default'], ENV = os.environ) Help(opts.GenerateHelpText(env)) # Copy environment variables if os.environ.has_key('CC'): env["CC"] = os.getenv('CC') if os.environ.has_key('CXX'): env["CXX"] = os.getenv('CXX') if os.environ.has_key('AS'): env["AS"] = os.getenv('AS') if os.environ.has_key('LD'): env["LINK"] = os.getenv('LD') if os.environ.has_key('CFLAGS'): env.Append(CCFLAGS = SCons.Util.CLVar(os.environ['CFLAGS'])) if os.environ.has_key('CPPFLAGS'): env.Append(CPPFLAGS = SCons.Util.CLVar(os.environ['CPPFLAGS'])) if os.environ.has_key('CXXFLAGS'): env.Append(CXXFLAGS = SCons.Util.CLVar(os.environ['CXXFLAGS'])) if os.environ.has_key('LDFLAGS'): env.Append(LINKFLAGS = SCons.Util.CLVar(os.environ['LDFLAGS'])) #env.Append(CPPFLAGS = [ "-Wall", "-Wformat=2", "-Wextra", "-Wwrite-strings", # "-Wno-unused-parameter", "-Wmissing-format-attribute", # "-Werror" ]) #env.Append(CFLAGS = [ "-Wmissing-prototypes", "-Wmissing-declarations", # "-Wshadow", "-Wbad-function-cast", "-Werror" ]) #env.Append(CXXFLAGS = [ "-Wno-non-template-friend", "-Woverloaded-virtual", # "-Wcast-qual", "-Wcast-align", "-Wconversion", # "-Weffc++", "-std=c++0x", "-Werror" ]) if env["WITH_GPROF"] == "1": env.Append(CPPFLAGS = [ "-pg" ]) env.Append(LINKFLAGS = [ "-pg" ]) if env["BUILDTYPE"] == "DEBUG": env.Append(CPPFLAGS = [ "-g", "-DDEBUG", "-Wall", "-Wno-deprecated-declarations" ]) env.Append(LINKFLAGS = [ "-g", "-rdynamic" ]) elif env["BUILDTYPE"] == "PERF": env.Append(CPPFLAGS = [ "-g", "-DNDEBUG", "-Wall", "-O2"]) env.Append(LDFLAGS = [ "-g", "-rdynamic" ]) elif env["BUILDTYPE"] == "RELEASE": env.Append(CPPFLAGS = ["-DNDEBUG", "-Wall", "-O2"]) else: print "Error BUILDTYPE must be RELEASE or DEBUG" sys.exit(-1) if env["ARCH"] != "amd64": print "Unsupported architecture: " + env["ARCH"] sys.exit(-1) try: hf = open(".git/HEAD", 'r') head = hf.read() if head.startswith("ref: "): if head.endswith("\n"): head = head[0:-1] with open(".git/" + head[5:]) as bf: branch = bf.read() if branch.endswith("\n"): branch = branch[0:-1] env.Append(CPPFLAGS = [ "-DGIT_VERSION=\\\"" + branch + "\\\""]) except IOError: pass if env["VERBOSE"] == "0": env["CCCOMSTR"] = "Compiling $SOURCE" env["CXXCOMSTR"] = "Compiling $SOURCE" env["SHCCCOMSTR"] = "Compiling $SOURCE" env["SHCXXCOMSTR"] = "Compiling $SOURCE" env["ARCOMSTR"] = "Creating library $TARGET" env["RANLIBCOMSTR"] = "Indexing library $TARGET" env["LINKCOMSTR"] = "Linking $TARGET" def GetNumCPUs(env): if env["NUMCPUS"] != "0": return int(env["NUMCPUS"]) return 2*multiprocessing.cpu_count() env.SetOption('num_jobs', GetNumCPUs(env)) def CopyTree(dst, src, env): def DirCopyHelper(src, dst): for f in os.listdir(src): srcPath = os.path.join(src, f) dstPath = os.path.join(dst, f) if os.path.isdir(srcPath): if not os.path.exists(dstPath): os.makedirs(dstPath) DirCopyHelper(srcPath, dstPath) else: env.Command(dstPath, srcPath, Copy("$TARGET", "$SOURCE")) if (not os.path.exists(dst)): os.makedirs(dst) DirCopyHelper(src, dst) # XXX: Hack to support clang static analyzer def CheckFailed(): if os.getenv('CCC_ANALYZER_OUTPUT_FORMAT') != None: return Exit(1) # Configuration conf = env.Configure() if not conf.CheckCC(): print 'Your C compiler and/or environment is incorrectly configured.' CheckFailed() if not conf.CheckCXX(): print 'Your C++ compiler and/or environment is incorrectly configured.' CheckFailed() conf.Finish() Export('env') # Debugging Tools # Create include tree CopyTree('build/include', 'include', env) CopyTree('build/include/sys', 'sys/include', env) CopyTree('build/include/machine', 'sys/' + env['ARCH'] + '/include', env) # Build Targets SConscript('sys/SConscript', variant_dir='build/sys') SConscript('lib/libc/SConscript', variant_dir='build/lib/libc') SConscript('sbin/init/SConscript', variant_dir='build/sbin/init') # Build Tools env["TOOLCHAINBUILD"] = "TRUE" env["CC"] = "cc" env["CXX"] = "c++" SConscript('sbin/newfs_o2fs/SConscript', variant_dir='build/tools/newfs_o2fs') # Install Targets env.Install('$PREFIX/','build/sys/castor') env.Alias('install','$PREFIX') # Boot Disk Target newfs = Builder(action = 'build/tools/newfs_o2fs/newfs_o2fs -s $BOOTDISK_SIZE -m $SOURCE $TARGET') env.Append(BUILDERS = {'BuildImage' : newfs}) bootdisk = env.BuildImage('#build/bootdisk.img', '#release/bootdisk.manifest') Depends(bootdisk, "#build/tools/newfs_o2fs/newfs_o2fs") Depends(bootdisk, "#build/sbin/init/init") Depends(bootdisk, "#build/sys/castor") env.Alias('bootdisk', '#build/bootdisk.img')