diff options
Diffstat (limited to 'py/waf/configure.py')
-rw-r--r-- | py/waf/configure.py | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/py/waf/configure.py b/py/waf/configure.py new file mode 100644 index 0000000000..a85ceb49b9 --- /dev/null +++ b/py/waf/configure.py @@ -0,0 +1,474 @@ +from waflib.Logs import pprint +pprint.__doc__ = None # Make sure waf doesn't see this as a command. +from waflib.Utils import subprocess + +# TODO +# __attribute__((weak) will not work on a cross compile. +# __RTEMS_SIZEOF_VOID_P__ + + +# XXX: BSP hacks that need to be addressed / resolved. +def bsp_hack(ctx, bsp): + if bsp == "m68k/mvme167": + # PowerPC unfortunatly uses macros to define this instead of an integer. + # We need to choose one or the other. + ctx.define('CONSOLE_MINOR', 1) + ctx.define('PRINTK_MINOR', 1) + + # I have no idea why it was done this way. + if bsp.startswith("arm/xilinx_zynq_") and ctx.env.ENABLE_SMP: + ctx.env.ZYNQ_CPUS = 2 + + +# general +def config_h(ctx): + # Are these even needed? + ctx.define_cond('ENABLE_DEBUG', ctx.env.ENABLE_DEBUG) + ctx.define_cond('ENABLE_MP', ctx.env.ENABLE_MP) + ctx.define_cond('ENABLE_MULTILIB', ctx.env.ENABLE_MULTILIB) + ctx.define_cond('ENABLE_NETWORKING', ctx.env.ENABLE_NETWORKING) + ctx.define_cond('ENABLE_NEWLIB', ctx.env.ENABLE_NEWLIB) + ctx.define_cond('ENABLE_POSIX', ctx.env.ENABLE_POSIX) + ctx.define_cond('ENABLE_PTHREADS', ctx.env.ENABLE_PTHREADS) + ctx.define_cond('ENABLE_SERDB', ctx.env.ENABLE_SERDB) + ctx.define_cond('ENABLE_SHELL', ctx.env.ENABLE_SHELL) + ctx.define_cond('ENABLE_SMP', ctx.env.ENABLE_SMP) + + header = ["sys/types.h", "sys/stat.h", "stdlib.h", "memory.h", "string.h", "strings.h", "inttypes.h", "stdint.h", "unistd.h", "getopt.h", "libgen.h"] + for file in header: + ctx.check(header_name=file, features='c cprogram', mandatory=False) + + ctx.check_inline() + ctx.check_func_header('strerror', header_n="string.h", mandatory=True) + ctx.check_func_header('strtol', header_n=["stdlib.h", "limits.h"], mandatory=True) + ctx.check_func_header('basename', header_n="libgen.h", mandatory=True) + + +# cpukit/ +def config_h_libcpu(ctx): + # Mandated by POSIX, decls not present in some versions of newlib, + # some versions stubbed in newlib's rtems crt0 + + + files = ["seteuid", "geteuid", "setegid", "getegid", "setuid", "getuid", "setgid", "getgid", "setsid", "getsid", "setpgid", "getpgid", "setpgrp", "getpgrp"] + for f in files: + ctx.check_func_header(f, header_n="unistd.h", mandatory=False) + + + # Mandated by POSIX, decls not present in some versions of newlib + ctx.check_func_header('flockfile', header_n="stdio.h", mandatory=False) + ctx.check_func_header('funlockfile', header_n="stdio.h", mandatory=False) + ctx.check_func_header('ftrylockfile', header_n="stdio.h", mandatory=False) + + # BSD-isms, used throughout the sources. + func = ["strsep", "strcasecmp", "snprintf", "strdup", "strndup", "strncasecmp", "bcopy", "bcmp", "isascii", "fileno", "strlcpy", "strlcat", "sbrk"] + + # Check for functions supplied by newlib >= 1.17.0 Newlib's posix/ directory + func += ["readdir_r", "isatty", "creat", "opendir", "closedir", "readdir", "rewinddir", "scandir", "seekdir", "sleep", "telldir", "usleep", "__assert", "execl", "execlp", "execle", "execv", "execvp", "execve", "regcomp", "regexec", "regerror", "regfree"] + + # Newlib's unix/ directory + func += ["ttyname", "getcwd"] + for f in func: + ctx.check_func(f, mandatory=False) + + + header = ["tar.h", "errno.h", "sched.h", "sys/cdefs.h", "sys/queue.h", "stdint.h", "inttypes.h", "pthread.h"] + for file in header: + ctx.check(header_name=file, features='c cprogram') + + ctx.check(header_name="pthread.h", features='c cprogram') + + ctx.check_type('pthread_rwlock_t', header_n="pthread.h", mandatory=False) + ctx.check_type('pthread_barrier_t', header_n="pthread.h", mandatory=False) + ctx.check_type('pthread_spinlock_t', header_n="pthread.h", mandatory=False) + ctx.check_func_decl("int pthread_setschedparam(pthread_t, int, const struct sched_param *)", "pthread.h", "PTHREAD_SETSCHEDPARAM_CONST") + ctx.check_func_decl("int pthread_mutex_getprioceiling(const pthread_mutex_t *__restrict, int *)", "pthread.h", "PTHREAD_MUTEX_GETCEILING_CONST") + + ctx.check_func_decl("int mprotect(const void *, size_t, int)", "sys/mman.h", "MPROTECT_CONST") + +#HAVE_PTHREAD_SETSCHEDPARAM_CONST +#include <pthread.h> +#int pthread_setschedparam(pthread_t, int, const struct sched_param *); + + + # pthread-functions not declared in some versions of newlib. + ctx.check_func_header('pthread_attr_getguardsize', header_n="pthread.h", mandatory=False) + ctx.check_func_header('pthread_attr_setguardsize', header_n="pthread.h", mandatory=False) + ctx.check_func_header('pthread_attr_setstack', header_n="pthread.h", mandatory=False) + ctx.check_func_header('pthread_attr_getstack', header_n="pthread.h", mandatory=False) + + ctx.check(header_name="signal.h", features='c cprogram') + ctx.check_type('sighandler_t', header_n="signal.h", mandatory=False) + + # FIXME: Mandatory in SUSv4, optional in SUSv3. + # Not implemented in GCC/newlib, so far. + ctx.check_define("WORD_BIT", "limits.h") + ctx.check_define("LONG_BIT", "limits.h") + +# ctx.check_define("CLOCK_PROCESS_CPUTIME_ID", "time.h") +# ctx.check_define("CLOCK_THREAD_CPUTIME_ID", "time.h") + + types = [ + "uint8_t", "int8_t", + "uint16_t", "int16_t", + "uint32_t", "int32_t", + "uint64_t", "int64_t", + "uintmax_t", "intmax_t", + "uintptr_t", "intptr_t" + ] + for type in types: + ctx.check_type(type, header_n="stdint.h", mandatory=False) + +# ctx.check_size("mode_t") +# ctx.define_cond('HAVE_MD5', True) # XXX: hack for cpukit/mghttpd/mongoose.c + ctx.define('__RTEMS_SIZEOF_MODE_T__', 4) # XXX: This is a hack for cpukit/libfs/src/nfsclient/src/dirutils.c + ctx.define('__RTEMS_SIZEOF_VOID_P__', 4) + ctx.define('__RTEMS_SIZEOF_OFF_T__', 8) + ctx.define('__RTEMS_SIZEOF_TIME_T__', 4) # XXX: hack for cpukit/libmisc/uuid/gen_uuid.c + ctx.define('__RTEMS_SIZEOF_BLKSIZE_T__', 4) # XXX: hack for tests + ctx.define('__RTEMS_SIZEOF_BLKCNT_T__', 4) # XXX: hack +# ctx.check_size("off_t") +# ctx.check_size("void *", define_name="SIZEOF_VOID_P") + + ctx.define('__RTEMS_HAVE_DECL_SIGALTSTACK__', 1) + + ctx.define('HAVE_DECL_PTHREAD_ATTR_GETAFFINITY_NP', 1) + ctx.define('HAVE_DECL_PTHREAD_ATTR_GETGUARDSIZE', 1) + ctx.define('HAVE_DECL_PTHREAD_ATTR_GETSTACK', 1) + ctx.define('HAVE_DECL_PTHREAD_ATTR_SETAFFINITY_NP', 1) + ctx.define('HAVE_DECL_PTHREAD_ATTR_SETGUARDSIZE', 1) + ctx.define('HAVE_DECL_PTHREAD_ATTR_SETSTACK', 1) + ctx.define('HAVE_DECL_PTHREAD_GETAFFINITY_NP', 1) + ctx.define('HAVE_DECL_PTHREAD_SETAFFINITY_NP', 1) + + +def version_header_info(ctx, config): + ctx.define('__RTEMS_MAJOR__', config["rtems_version_major"]) + ctx.define('__RTEMS_MINOR__', config["rtems_version_minor"]) + ctx.define('__RTEMS_REVISION__', config["rtems_version_revision"]) + ctx.define('RTEMS_VERSION', ctx.env.RTEMS_VERSION) + ctx.define('RTEMS_BSP', ctx.env.RTEMS_BSP) + + +# c/ +def config_h_libbsp(ctx): + ctx.define('__RTEMS_SIZEOF_VOID_P__', 4) + + +def cpuopts_h(ctx): + ctx.define_cond('__RTEMS_USE_TICKS_FOR_STATISTICS__', False) # disable nanosecond granularity for statistics + ctx.define_cond('__RTEMS_USE_TICKS_CPU_USAGE_STATISTICS__', False) # disable nanosecond granularity for cpu usage statistics + ctx.define_cond('__RTEMS_USE_TICKS_RATE_MONOTONIC_STATISTICS__', False) # disable nanosecond granularity for period statistics + ctx.define_cond('__RTEMS_DO_NOT_INLINE_THREAD_ENABLE_DISPATCH__', False) # disable inlining _Thread_Enable_dispatch (This improves both the size and coverage analysis.) + ctx.define_cond('__RTEMS_DO_NOT_INLINE_CORE_MUTEX_SEIZE__', False) # disable inlining _Thread_Enable_dispatch (This improves both the size and coverage analysis.) + ctx.define_cond('__RTEMS_DO_NOT_UNROLL_THREADQ_ENQUEUE_PRIORITY__', False) # disable inlining _Thread_queue_Enqueue_priority (This improves both the size and coverage analysis.) + ctx.define_cond('__RTEMS_STRICT_ORDER_MUTEX__', False) # disable strict order mutex (This gives the same behavior as 4.8 and older) + ctx.define_cond('__RTEMS_ADA__', False) # ada/gnat bindings are built-in (Deactivate ada bindings) + + ctx.define_cond('RTEMS_DEBUG', ctx.env.ENABLE_DEBUG) + ctx.define_cond('RTEMS_MULTIPROCESSING', ctx.env.ENABLE_MP) + ctx.define_cond('RTEMS_NETWORKING', ctx.env.ENABLE_NETWORKING) + ctx.define_cond('RTEMS_NEWLIB', ctx.env.ENABLE_NEWLIB) + ctx.define_cond('RTEMS_POSIX_API', ctx.env.ENABLE_POSIX) + ctx.define_cond('RTEMS_SMP', ctx.env.ENABLE_SMP) + + +def depend_version(ctx): + ctx.start_msg("Checking GCC version") + ctx.get_cc_version(ctx.env.CC, gcc=True) + ctx.end_msg(".".join(ctx.env.CC_VERSION)) + + ctx.start_msg("Checking Binutils version") + cmd = ctx.env.BIN_RTEMS_LD + ["-v"] + ctx.env.LD_VERSION = ctx.cmd_and_log(cmd, quiet=0).strip().split(" ")[-1] + ctx.end_msg(ctx.env.LD_VERSION) + + +def build_config(ctx): + ctx.start_msg("DEVEL: Collecting compiler configuration") + cmd = ctx.env.CC + ["-dM", "-E", "-"] + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=None) + p.stdin.write("\n") + gcc_config, stderr = p.communicate() + ctx.end_msg("Done") + + + # XXX: Add 'M' if it is modified see vc-key.sh + ctx.start_msg("DEVEL: Getting revision") + cmd = ["git", "log", "-1", "--format=%H"] + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=None) + ctx.env.REVISION, stderr = p.communicate() + ctx.env.REVISION = ctx.env.REVISION.replace("\n", "") + ctx.end_msg(ctx.env.REVISION) + + with open("build/c4che/%s/%s_cache.py" % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_BSP), "r") as fp: + cache_data = fp.read() + + ctx.start_msg("DEVEL: Writing build information") + from json import JSONEncoder + from time import strftime + + data = JSONEncoder(sort_keys=True).encode({ + "time": int(strftime("%s")), # There is no better way to get seconds across lal platforms? + "revision": ctx.env.REVISION, + "bsp": ctx.env.RTEMS_BSP, + "architecture": ctx.env.RTEMS_ARCH, + "version": { + "gcc": ".".join(ctx.env.CC_VERSION), + "binutils": ctx.env.LD_VERSION + }, + "waf_cache": cache_data, + "gcc_config": gcc_config + }) + file = "build/c4che/%s/build_%s.json" % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_BSP) + with open(file, "w") as fp: + fp.write(data) + ctx.end_msg(file) + + +def cmd_configure(ctx, config): + ctx.load('waf', tooldir='py/waf/') + ctx.load('waf_unit_test') + + from py.config.bsp import get_option_class, get_config_class + from py.config import BuildConfig, RTEMSConfig + + rc = RTEMSConfig(get_option_class(), get_config_class()) + cfg = BuildConfig(rc) + + # Misc funcs + def yesno(val): + return "Yes" if val else "No" + + def write_header(header): + ctx.start_msg("Writing configuration header:") + ctx.write_config_header(header) + ctx.end_msg(header, "PINK") + + def msg(str): + pprint("YELLOW", str) + + def msg_setting(name, val): + pprint("NORMAL", " %-30s: " % name, sep="") + pprint("YELLOW", val) + + + + ###### + # HOST + ###### + + msg("") + msg("--- General Settings ---") + cfg.config_set(ctx, "general") + + ctx.env.RTEMS_VERSION = "%d.%d.%d" % (config["rtems_version_major"], config["rtems_version_minor"], config["rtems_version_revision"]) + ctx.env.RTEMS_VERSION_DATA = "%d.%d" % (config["rtems_version_major"], config["rtems_version_minor"]) + + ctx.env.LIBDIR = "%s/lib" % ctx.env.PREFIX + ctx.env.BINDIR = "%s/bin" % ctx.env.PREFIX + + + + msg("") + msg("--- Host Settings ---") + ctx.setenv('host', ctx.env.derive()) + ctx.load('compiler_c') + ctx.load('compiler_cxx') + + + + if ctx.options.dev_config: + ctx.start_msg('BUILD: Gathering build platform details.') + + # General + from socket import gethostname + from waflib.Utils import unversioned_sys_platform + import platform + + ctx.env.BUILD_HOSTNAME = gethostname() + ctx.env.BUILD_PLATFORM = unversioned_sys_platform() + ctx.env.BUILD_ARCHITECTURE = platform.architecture() + ctx.env.BUILD_MACHINE = platform.machine() + ctx.env.BUILD_PLATFORM = platform.platform() + ctx.env.BUILD_PYTHON_BUILD = platform.python_build() + ctx.env.BUILD_SYSTEM = platform.system() + + # Unix + ctx.env.BUILD_SIGNATURE = platform.uname() + + # Linux + #platform.libc_ver() + #platform.linux_distribution() + + # Windows + #platform.win32_ver() + + ctx.end_msg("Done") + + + ctx.check_library() +# ctx.check_cc(function_name='strerror', header_name="string.h", mandatory=True) +# ctx.check_cc(function_name='strtol', header_name=["stdlib.h", "limits.h"], mandatory=True) +# ctx.check_cc(function_name='basename', header_name="libgen.h", mandatory=True) + + files = ["getopt.h", "libgen.h"] + for f in files: + ctx.check(header_name=f, features='c cprogram') + + # Locate python binary for rtems-config + ctx.find_program("python", var='BIN_PYTHON') + + # Debug + if ctx.options.dev_json: + ctx.env.BUILD_JSON = True + + #XXX: TEMP! + if ctx.options.enable_tests: + ctx.env.ENABLE_TESTS = True + + cfg.config_set(ctx, "host") + write_header("host/include/config.h") + + # Set general BSP options + cfg.config_set(ctx, "bsp") + + # Set timetstamp of config.cfg to enforce re-running configure if it is changed. + from .tools import get_file_mtime + ctx.env.CONFIG_TIMESTAMP = get_file_mtime("config.cfg") + + # Always start with a pristeen env while looping. + env_orig = ctx.env + for bsp in ctx.env.BSP: + +# if ctx.env.ENABLE_SYSTEM_DEP: +# from waflib.Tools import c_preproc +# c_preproc.go_absolute=True + + msg("") + msg("--- Configuring %s ---" % bsp) + ctx.setenv(bsp, env_orig.derive()) + + (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_BSP) = bsp.split("/") + + if ctx.env.ENABLE_PTHREADS: + ctx.define("HAS_PTHREADS", 1) + + + if ctx.env.ENABLE_PTHREADS and not ctx.env.ENABLE_POSIX: + ctx.fatal("Must be built with posix support (ENABLE_POSIX) when using pthreads (ENABLE_PTHREADS)") + + # XXX: Joel says this shouldn't be nessicary. + if ctx.env.ENABLE_MP and not ctx.env.ENABLE_POSIX: + ctx.fatal("Must be built with posix support (ENABLE_POSIX) when using MP (ENABLE_MP)") + + + # Miscellanous setup. + ctx.env.RTEMS_VERSION = "%d.%d.%d.%d" % (config["rtems_version_major"], config["rtems_version_minor"], config["rtems_version_revision"], config["rtems_version_patch"]) + ctx.env.RTEMS_VERSION_DATA = "%d.%d" % (config["rtems_version_major"], config["rtems_version_minor"]) + ctx.env.RTEMS_TOOL_VERSION = config["rtems_tool_version"] + ctx.env.append_value('CFLAGS', '-DHAVE_CONFIG_H') + ctx.env.append_value('CFLAGS', '-D__rtems_%s_%s__' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_BSP.replace("-", "_"))) + ctx.env.LIBDIR = "%s/lib/rtems/%s/%s-%s/" % (ctx.env.PREFIX, ctx.env.RTEMS_VERSION_DATA, ctx.env.RTEMS_ARCH, ctx.env.RTEMS_BSP) + ctx.env.BINDIR = ctx.env.LIBDIR + +#XXX: Re-add after things are fixed. + # Enforce required values. +# required = ["LINKCMDS", "LINK_START", "LINK_END"] +# for value in required: +# if not ctx.env[value]: +# ctx.fatal("%s must be defined in [%s]" % (value, bsp)) + + #XXX: ARM hack + if ctx.env.RTEMS_ARCH == "arm": + ctx.env.LDFLAGS = ctx.env.CFLAGS + + + # Tools. + ctx.find_program('%s-rtems%s-ar' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_AR', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-as' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_AS', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-g++' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_CPP', path_list=ctx.env.PATH_TOOLS, mandatory=False) + ctx.find_program('%s-rtems%s-gcc' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_CC', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-ld' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_LD', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-nm' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_NM', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-ranlib' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_RANLIB', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-strip' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_STRIP', path_list=ctx.env.PATH_TOOLS) + ctx.find_program('%s-rtems%s-run' % (ctx.env.RTEMS_ARCH, ctx.env.RTEMS_TOOL_VERSION), var='BIN_RTEMS_RUN', path_list=ctx.env.PATH_TOOLS, mandatory=False) + ctx.env.AR = ctx.env.BIN_RTEMS_AR + ctx.env.AS = ctx.env.BIN_RTEMS_AS + ctx.env.CC = ctx.env.BIN_RTEMS_CC + ctx.env.CPP = ctx.env.BIN_RTEMS_CPP + ctx.env.RANLIB = ctx.env.BIN_RTEMS_RANLIB + ctx.env.STRIP = ctx.env.BIN_RTEMS_STRIP + ctx.env.LD = ctx.env.BIN_RTEMS_LD + ctx.env.LINK_CC = ctx.env.BIN_RTEMS_CC + ctx.env.LINK_CXX = ctx.env.BIN_RTEMS_CCP + + + # Config (config.h) + config_h(ctx) + config_h_libcpu(ctx) + version_header_info(ctx, config) + cpuopts_h(ctx) #XXX: duplicate info. + write_header("%s/include/config.h" % bsp) + + # BSP options. + cfg.config_set(ctx, ctx.env.RTEMS_BSP, ctx.env.RTEMS_ARCH) + bsp_hack(ctx, bsp) + write_header("%s/include/bspopts.h" % ctx.variant) + config_h_libbsp(ctx) # Eventually there will be an option to exclude this and replace it with something custom. + + # CPU options. + cpuopts_h(ctx) + version_header_info(ctx, config) + write_header("%s/include/rtems/score/cpuopts.h" % bsp) + + ctx.start_msg('Generating GCC spec file') + from py.waf.tools import generate_gcc_spec_file + spec_file = generate_gcc_spec_file(ctx, devel=True) + ctx.end_msg(spec_file) + + + depend_version(ctx) + if ctx.options.dev_config: + build_config(ctx) + + + msg("") + msg("--- Settings for %s ---" % bsp) + msg_setting("Enable Networking", yesno(ctx.env.ENABLE_NETWORKING)) + msg_setting("Enable Multiprocessing", yesno(ctx.env.ENABLE_MP)) + msg_setting("Enable Multilib", yesno(ctx.env.ENABLE_MULTILIB)) + msg_setting("Enable POSIX", yesno(ctx.env.ENABLE_POSIX)) + msg_setting("Enable SMP", yesno(ctx.env.ENABLE_SMP)) + msg_setting("Enable pthreads", "%s (Depends on POSIX)" % yesno(ctx.env.ENABLE_PTHREADS)) + msg("") + msg("Build Options") + msg_setting("CC", " ".join(ctx.env.CC)) + msg_setting("CFLAGS", " ".join(ctx.env.CFLAGS)) + msg_setting("LDFLAGS", " ".join(ctx.env.LDFLAGS)) + + + # Reset the env back to the original in order to print the proper settings below. + ctx.setenv("host", env_orig.derive()) + + msg("") + ctx.start_msg('Generating rtems-config') + from py.waf.tools import generate_rtems_config + generate_rtems_config(ctx, "py/waf/rtems_config.py", "rtems-config", devel=True) + ctx.end_msg("Done") + + + msg("") + msg("--- General Settings (applies to all) --- ") + msg_setting("Enabled BSPs", ", ".join(ctx.env.BSP)) + msg_setting("Install Prefix", ctx.env.PREFIX) + msg_setting("Tool Directory", ctx.env.PATH_TOOLS) + msg("") + msg("Build Options") + msg_setting("CFLAGS", " ".join(ctx.env.CFLAGS)) + msg_setting("LDFLAGS", " ".join(ctx.env.LDFLAGS)) + msg_setting("Enable Debug", yesno(ctx.env.ENABLE_DEBUG)) + + + |