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"), ("AR", "Archiver"), ("RANLIB", "Archiver Indexer"), ("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", "Build boot disk (0 or 1)", "0"), ("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('AR'): env["AR"] = os.getenv('AR') if os.environ.has_key('RANLIB'): env["RANLIB"] = os.getenv('RANLIB') 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 = [ "-Wshadow", "-Wno-typedef-redefinition" ]) #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" env["ASCOMSTR"] = "Assembling $TARGET" env["ASPPCOMSTR"] = "Assembling $TARGET" env["ARCOMSTR"] = "Archiving $TARGET" env["RANLIBCOMSTR"] = "Indexing $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('bin/shell/SConscript', variant_dir='build/bin/shell') SConscript('sbin/init/SConscript', variant_dir='build/sbin/init') SConscript('tests/SConscript', variant_dir='build/tests') # Build Tools env["TOOLCHAINBUILD"] = "TRUE" env["CC"] = "cc" env["CXX"] = "c++" env["LINK"] = "cc" 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 if env["BOOTDISK"] == "1": 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/bin/shell/shell") Depends(bootdisk, "#build/sbin/init/init") Depends(bootdisk, "#build/sys/castor") Depends(bootdisk, "#build/tests/threadtest") env.Alias('bootdisk', '#build/bootdisk.img') env.Install('$PREFIX/','#build/bootdisk.img')