use b_plain export cz/parse opts *O int line_initial_space = 512 cstr cz_config_file cstr src_file, exe_file, xbak_file, c_file, b1_file, bh_file, bbak_file, bbak2_file, log_file, lock_file cstr cz_dir, cz_lib, cz_inc, cz_cc, cz_cxx, libb, gcc_target, gcc_version, gcc_major boolean cz_debug, cz_optimize, cz_profile, cz_standalone, cz_plain, cz_verbose, cz_line_numbers, cz_resolve_includes, cz_bh_no_macros boolean run_in_gdb boolean need_compile, already_compiled vec *cflags, *cxxflags, *ldflags, *ldlibs, *cz_use, *include_path, *b_include_path, *c_include_path, *cxx_include_path int b_include_path_base_len enum { LANG_C, LANG_CXX } cz_lang Stats *libb_stat, *src_stat, *exe_stat, *log_stat cstr cz_L_so, cz_use_s, c_ext, b_ext, srcdir, srcbase, srcname cstr src_file_data init() tok_init() cz_parse_init() NEW(cflags, vec, cstr, 16) NEW(cxxflags, vec, cstr, 16) NEW(ldflags, vec, cstr, 16) NEW(ldlibs, vec, cstr, 16) NEW(cz_use, vec, cstr, 16) NEW(include_path, vec, cstr, 16) NEW(c_include_path, vec, cstr, 16) NEW(b_include_path, vec, cstr, 16) NEW(cxx_include_path, vec, cstr, 16) cz_free() cz_parse_free() vec_free(cflags) vec_free(cxxflags) vec_free(ldflags) vec_free(ldlibs) vec_free(cz_use) vec_free(include_path) vec_free(c_include_path) vec_free(b_include_path) vec_free(cxx_include_path) # other stuff is freed by tofree_block # TODO tok_free() ? config() cz_config_file = tofree(dotfile(".cz")) if exists(cz_config_file) load_config(cz_config_file) cz_lib = Getenv("CZ_LIB") cz_inc = Getenv("CZ_INC") cstr debug_s = Getenv("DEBUG") cz_debug = boolean(debug_s) run_in_gdb = cstr_eq(debug_s, "gdb") cz_optimize = boolean(Getenv("OPTIMIZE", "0")) cz_profile = boolean(Getenv("PROFILE")) cz_standalone = boolean(Getenv("CZ_STANDALONE")) cz_plain = boolean(Getenv("CZ_PLAIN")) cz_verbose = boolean(Getenv("CZ_VERBOSE")) || opt("verbose") cz_line_numbers = boolean(Getenv("CZ_LINE_NUMBERS")) cz_resolve_includes = boolean(Getenv("CZ_RESOLVE_INCLUDES")) cz_bh_no_macros = boolean(Getenv("CZ_BH_NO_MACROS")) cz_lang = cstr_eq(Getenv("CZ_LANG"), "C++") ? LANG_CXX : LANG_C if cstr_eq(program, "cz++") || cstr_case_eq(dflt(opt("lang")), "c++") cz_lang = LANG_CXX splitv(cflags, Getenv("CFLAGS"), ' ') splitv(cxxflags, Getenv("CXXFLAGS"), ' ') splitv(ldflags, Getenv("LDFLAGS"), ' ') splitv(ldlibs, Getenv("LDLIBS"), ' ') splitv(cz_use, Getenv("CZ_USE"), ' ') splitv(include_path, Getenv("INCLUDE_PATH"), PATH_sep) gcc_target = Getenv_or_null("GCC_TARGET") gcc_version = Getenv_or_null("GCC_VERSION") cz_dir_to_lib() cz_lib = tofree(path_cat(cz_dir, "lib")) libb = tofree(path_cat(cz_lib, "libb" SO)) NEW(libb_stat, Stats, libb) tofree(libb_stat) setup() cstr cz_bin = program_dir cz_dir = dir_name(tofree(Strdup(cz_bin))) if !*cz_lib cz_dir_to_lib() if !stat_exists(libb_stat) cz_dir = NULL cstr brace = tofree(which("brace")) if brace cz_bin = dir_name(brace) cz_dir = dir_name(tofree(Strdup(cz_bin))) eif mingw each(d, (cstr)"c:\\cz", "c:\\Program Files\\cz", "d:\\cz", "d:\\Program Files\\cz") if is_dir(d) cz_dir = d cz_bin = tofree(path_cat(cz_dir, "bin")) break if cz_dir cz_lib = tofree(path_cat(cz_dir, "lib")) libb = tofree(path_cat(cz_lib, "libb" SO)) cz_dir_to_lib() if !opt("translate") && !stat_exists(libb_stat) error("please ensure cz, libb and brace are installed and in your PATH") if !*cz_inc cz_inc = tofree(path_cat(cz_dir, "include")) if !is_dir(cz_inc) Free(cz_inc) cz_inc = cz_lib PATH_prepend(cz_bin) bm("done setup 1") vec_push_cstr(ldlibs, "-lm") if cz_standalone cz_L_so = "" else cz_L_so = fformat("-L%s", cz_lib) new(l_libb, buffer, 16) buffer_cat_cstr(l_libb, "-lb") if cz_plain buffer_cat_cstr(l_libb, "_plain") if cz_debug buffer_cat_cstr(l_libb, "_debug") vec_push_cstr(ldlibs, tofree(buffer_to_cstr(l_libb))) cstr I_inc = fformat("-I%s", cz_inc) each(x, (cstr)"-Wall", "-Wextra", "-Wno-long-long", "-I.", I_inc, "-D_GNU_SOURCE", "-D_FILE_OFFSET_BITS=64") vec_push_cstr(cflags, x) if cz_debug vec_push_cstr(cflags, "-ggdb") if cz_optimize vec_push_cstr(cflags, "-O2") if cz_profile vec_push_cstr(cflags, "-pg") bm("done setup 2") vec_push_cstr(cz_use, "cz") each(x, (cstr)"-lm") vec_push_cstr(ldlibs, x) if !cz_plain: vec_push_cstr(cflags, "-I/usr/include/SDL2") # vec_push_cstr(cflags, "-I/usr/include/SDL") each(x, (cstr)"-lpng", "-lSDL2_image", "-lSDL2_mixer", "-lSDL2_ttf", "-lSDL2") # each(x, (cstr)"-lpng", "-lSDL", "-lSDL_mixer") vec_push_cstr(ldlibs, x) if mingw each(x, (cstr)"mingw", "gnu-", "bsd-", "linux-", "modern-", "io-select", "pc") vec_push_cstr(cz_use, x) vec_push_cstr(ldflags, "-Wl,--enable-auto-import,--enable-runtime-pseudo-reloc") vec_push_cstr(ldlibs, "-lws2_32") if !cz_plain each(x, (cstr)"-lopengl32", "-lglu32", "-lgdi32") vec_push_cstr(ldlibs, x) else each(x, (cstr)"unix", "mingw-") vec_push_cstr(cz_use, x) if !cz_plain if exists("/usr/include/X11/Xlib.h") || exists("/usr/X11R6/include/X11/Xlib.h") || exists("/mnt/utmp/codeblocks/usr/include/X11/Xlib.h") vec_push_cstr(cz_use, "x") vec_push_cstr(cflags, "-I/usr/X11R6/include") vec_push_cstr(ldflags, "-L/usr/X11R6/lib") each(x, (cstr)"-lX11", "-lXext") vec_push_cstr(ldlibs, x) else vec_push_cstr(cz_use, "gr_dummy") vec_push_cstr(ldlibs, "-lcrypt") decl(un, struct utsname) uname(un) cstr os = tofree(Strdup(un->sysname)) cstr release = un->release # boolean arm = cstr_begins_with(un->machine, "arm") != NULL lc(os) char *p = strchr(release, '-') if p *p = '\0' if strstr(os, "bsd") || cstr_eq(os, "sunos") || cstr_eq(os, "dragonfly") || cstr_eq(os, "darwin"): vec_push_cstr(cz_use, "bsd") if strstr(os, "netbsd") || strstr(os, "openbsd"): vec_push_cstr(cz_use, "modern-") else: vec_push_cstr(cz_use, "modern") else vec_push_cstr(cz_use, "bsd-") vec_push_cstr(cz_use, os) if !cstr_eq(os, "linux") && !cstr_eq(os, "hurd") && !cstr_eq(os, "gnu") vec_push_cstr(cz_use, "gnu-") if cstr_eq(os, "linux") if version_ge(release, "2.6.20") vec_push_cstr(cz_use, "modern") vec_push_cstr(cz_use, "io-select") # !! epoll doesn't work on regular files ?? # if arm: # vec_push_cstr(cz_use, "io-select") # else: # vec_push_cstr(cz_use, "io-epoll") else each(x, (cstr)"modern-", "io-select") vec_push_cstr(cz_use, x) else each(x, (cstr)"linux-", "io-select") vec_push_cstr(cz_use, x) # devices: TODO N900, etc cstr device if exists("/proc/pandora"): device = "pandora" vec_push_cstr(cz_use, "gles") if !cz_plain: each(x, (cstr)"-lEGL", "-lGLES_CM", "-lpvrPVR2D_X11WSEGL"): vec_push_cstr(ldlibs, x) else: device = "pc" if !cz_plain: vec_push_cstr(ldlibs, "-lGL") vec_push_cstr(cz_use, device) bm("done setup 3") grep(i, cz_use, cstr, cz_use_exists(*i)) uniq_vos(cz_use) vec_squeeze(cz_use) cz_use_s = tofree(joinv(' ', cz_use)) bm("done setup 4") if !(cz_cc = Getenv_or_null("CC")) each(cc, (cstr)"gcc", "tcc", "cc") if tofree(which(cc)) cz_cc = cc break if !cz_debug if !cstr_eq(cz_cc, "tcc") && !cstr_ends_with(cz_cc, "/tcc") vec_push_cstr(ldflags, "-s") # TODO run strip when using tcc? if !(cz_cxx = Getenv_or_null("CXX")) each(cc, (cstr)"g++", "c++") if tofree(which(cc)) cz_cxx = cc break if !cz_cxx cz_cxx = cz_cc bm("done setup 5") if cz_cxx[0] == 'g' vec_push_cstr(cxxflags, "-Weffc++") vec_append(cxxflags, cflags) if cz_cc[0] == 'g' each(x, (cstr)"-pedantic", "-std=gnu99") vec_push_cstr(cflags, x) # TODO recheck if gcc executable is newer than config file :/ if !gcc_target || !gcc_version if !gcc_target gcc_target = tofree(chomp(x("gcc -dumpmachine"))) if !gcc_version gcc_version = tofree(chomp(x("gcc -dumpversion"))) if !exists(cz_config_file) F_out(cz_config_file) sf("GCC_TARGET=\"%s\"", gcc_target) sf("GCC_VERSION=\"%s\"", gcc_version) gcc_major = Strdup(gcc_version) char *p = strchr(gcc_version, '.') if p: p = strchr(p+1, '.') if p: *p = '\0' bm("done setup 6") each(x, b_include_path, c_include_path, cxx_include_path) vec_push(x, (cstr)".") splitv(b_include_path, cz_inc) b_include_path_base_len = veclen(b_include_path) each(x, (cstr) "/MinGW/include/c++/3.2.3", fformat("/usr/include/c++/%s", gcc_major)) vec_push(cxx_include_path, x) each(x, (cstr) "/MinGW/include", "/usr/local/include", fformat("/usr/lib/gcc/%s/%s/include", gcc_target, gcc_version), fformat("/usr/lib/gcc-lib/%s/%s/include", gcc_target, gcc_version), fformat("/usr/%s/include", gcc_target), "/usr/include") vec_push(c_include_path, x) vec_push(cxx_include_path, x) bm("done setup 7") new(dircache, hashtable, cstr_hash, cstr_eq, 53) each(v, c_include_path, cxx_include_path) vec_append(v, include_path) uniqo(v, cstr_hash, cstr_eq) grep(i, v, cstr, cache(dircache, *i, is_dir(*i))) vec_squeeze(v) hashtable_free(dircache) bm("done setup 8") boolean cz_use_exists(cstr u) cstr dir = path_cat(cz_inc, u) boolean rv = is_dir(dir) Free(dir) return rv prepare() # this is for setup that is specific to a src_file fix_path(src_file) src_file = tofree(readlinks(Strdup(src_file))) if cstr_ends_with(src_file, ".b") cz_lang = LANG_C eif cstr_ends_with(src_file, ".bb") cz_lang = LANG_CXX else cstr hb = hashbang(src_file) if hb if strstr(hb, "/bb") || strstr(hb, "/cz++") || \ strstr(hb, " bb") || strstr(hb, " cz++") cz_lang = LANG_CXX Free(hb) if cz_lang == LANG_CXX c_ext = "cc" b_ext = "bb" else c_ext = "c" b_ext = "b" dirbase db = dirbasename(tofree(Strdup(src_file))) srcdir = db.dir # srcbase = db.base # srcname = tofree(Strdup(srcbase)) srcname = db.base cstr dot = strrchr(srcname, '.') if dot *dot = '\0' exe_file = fformat("%s" path__sep_cstr ".%s" EXE, srcdir, srcname) lock_file = fformat("%s" path__sep_cstr ".%s.lock", srcdir, srcname) xbak_file = fformat("%s" path__sep_cstr ".%s.xbak" EXE, srcdir, srcname) c_file = fformat("%s" path__sep_cstr ".%s.%s", srcdir, srcname, c_ext) b1_file = fformat("%s" path__sep_cstr ".%s.%s1", srcdir, srcname, b_ext) bh_file = fformat("%s" path__sep_cstr ".%s.%sh", srcdir, srcname, b_ext) bbak_file = fformat("%s" path__sep_cstr ".%s.bak", srcdir, srcname) bbak2_file = fformat("%s" path__sep_cstr ".%s.bak2", srcdir, srcname) log_file = fformat("%s" path__sep_cstr ".%s.log", srcdir, srcname) system_verbose = cz_verbose # FIXME change / remove BRACE->CZ and LIB/INC, SO/LIB Setenv("BRACE_USE", cz_use_s) Setenv("BRACE_LIB", cz_inc) Setenv("BRACE_SO", cz_lib) dump_settings() warn("options:") dump_options(O) # TODO I need a "stringify" syntax for macros, so could just do # dumpvar(src_file). cpp has one. warn("PATH: %s", Getenv("PATH")) warn("src_file: %s", src_file) warn("exe_file: %s", exe_file) warn("xbak_file: %s", xbak_file) warn("c_file: %s", c_file) warn("bbak_file: %s", bbak_file) warn("bbak2_file: %s", bbak2_file) warn("log_file: %s", log_file) warn("lock_file: %s", lock_file) warn("cz_dir: %s", cz_dir) warn("cz_lib: %s", cz_lib) warn("cz_inc: %s", cz_inc) warn("cz_debug: %d", cz_debug) warn("cz_optimize: %d", cz_optimize) warn("cz_standalone: %d", cz_standalone) warn("cz_plain: %d", cz_plain) warn("cz_verbose: %d", cz_verbose) warn("cz_line_numbers: %d", cz_line_numbers) warn("cz_lang: %d", cz_lang) warn("cz_cc: %s", cz_cc) warn_vec_cstr("cflags:", cflags) warn_vec_cstr("cxxflags:", cxxflags) warn_vec_cstr("ldflags:", ldflags) warn_vec_cstr("ldlibs:", ldlibs) warn_vec_cstr("cz_use:", cz_use) warn("cz_use_s: %s", cz_use_s) warn("gcc_target: %s", gcc_target) warn("gcc_version: %s", gcc_version) warn("gcc_major: %s", gcc_major) warn_vec_cstr("include_path:", include_path) warn_vec_cstr("b_include_path:", b_include_path) warn_vec_cstr("c_include_path:", c_include_path) warn_vec_cstr("cxx_include_path:", cxx_include_path)