#include #include #include "arg.h" #include "log.h" #include "dep.h" #include "libs.h" #include "db.h" #include "tmpasm.h" #include "tmpasm_scconfig.h" #include "generator.h" #include "util/arg_auto_set.h" #include "Rev.h" #define version "3.1.5-dev" #define REQ_LIBRND_MAJOR 4 #define REQ_LIBRND_MINOR 2 #define WANT_POLYBOOL_DEFAULT strue #define TOSTR_(x) #x #define TOSTR(x) TOSTR_(x) #include #include /* we are doing /local/pcb/ */ #define LIBRND_SCCONFIG_APP_TREE "pcb" #include #include #include const arg_auto_set_t disable_libs[] = { /* list of --disable-LIBs and the subtree they affect */ {"disable-gd", "libs/gui/gd", arg_lib_nodes, "$do not use gd (many exporters need it)"}, {"enable-bison", "/local/pcb/want_bison", arg_true, "$enable generating language files using bison/flex"}, {"disable-bison", "/local/pcb/want_bison", arg_false, "$disable generating language files using bison/flex"}, {"enable-byaccic", "/local/pcb/want_byaccic", arg_true, "$enable generating language files using byaccic/ureglex"}, {"disable-byaccic", "/local/pcb/want_byaccic", arg_false, "$disable generating language files byaccic/ureglex"}, {"enable-polybool", "/local/pcb/want_polybool", arg_true, "$enable the new polygon clipping library"}, {"disable-polybool", "/local/pcb/want_polybool", arg_false, "$disable the new polygon clipping library"}, #undef plugin_def #undef plugin_header #undef plugin_dep #define plugin_def(name, desc, default_, all_) plugin3_args(name, desc) #define plugin_header(sect) #define plugin_dep(plg, on) #include "plugins.h" {NULL, NULL, NULL, NULL} }; #define TO_STR_(payload) #payload #define TO_STR(payload) TO_STR_(payload) static void help1(void) { rnd_help1("pcb-rnd"); printf(" --dot_pcb_rnd=path .pcb-rnd config path under $HOME/\n"); } #define need_value(msg) \ if (value == NULL) { \ fprintf(stderr, "syntax error; %s\n", msg); \ exit(1); \ } /* Runs when a custom command line argument is found returns true if no further argument processing should be done */ int hook_custom_arg(const char *key, const char *value) { rnd_hook_custom_arg(key, value, disable_libs); /* call arg_auto_print_options() instead */ if (strcmp(key, "dot_pcb_rnd") == 0) { need_value("use --dot_pcb_rnd=dir"); put("/local/pcb/dot_pcb_rnd", value); return 1; } if (strcmp(key, "static") == 0) { put("/local/pcb/want_static", strue); return 1; } if (arg_auto_set(key, value, disable_libs) == 0) { fprintf(stderr, "Error: unknown argument %s\n", key); exit(1); } return 1; /* handled by arg_auto_set() */ } /* Runs before anything else */ int hook_preinit() { return 0; } void librnd_ver_req_min(int exact_major, int min_minor); /* Runs after initialization */ int hook_postinit() { db_mkdir("/local"); db_mkdir("/local/pcb"); rnd_hook_postinit(); put("/local/pcb/want_bison", sfalse); put("/local/pcb/want_byaccic", sfalse); put("/local/pcb/want_static", sfalse); put("/local/pcb/want_polybool", WANT_POLYBOOL_DEFAULT); put("/local/pcb/dot_pcb_rnd", ".pcb-rnd"); put("/local/pcb/librnd_prefix", TO_STR(LIBRND_PREFIX)); librnd_ver_req_min(REQ_LIBRND_MAJOR, REQ_LIBRND_MINOR); return 0; } /* Runs after all arguments are read and parsed */ int hook_postarg() { char *tmp; const char *libad; put("/local/pcb/librnd_template", tmp = str_concat("", TO_STR(LIBRND_PREFIX), "/", get("/local/libarchdir"), "/librnd4/scconfig/template", NULL)); free(tmp); /* if librnd is installed at some custom path, we'll need to have a -I on CFLAGS and -L on LDFLAGS */ libad = get("/local/libarchdir"); if (((strncasecmp(TO_STR(LIBRND_PREFIX), "/usr/include", 12) != 0) && (strncasecmp(TO_STR(LIBRND_PREFIX), "/usr/local/include", 18) != 0)) || (strcmp(libad, "lib") != 0)) { put("/local/pcb/librnd_extra_inc", "-I" TO_STR(LIBRND_PREFIX) "/include"); put("/local/pcb/librnd_extra_ldf", tmp = str_concat("", "-L" TO_STR(LIBRND_PREFIX) "/", libad, NULL)); free(tmp); } return rnd_hook_postarg(TO_STR(LIBRND_PREFIX), "pcb-rnd"); } /* Runs when things should be detected for the host system */ int hook_detect_host() { return rnd_hook_detect_host(); } /* figure if we need the dialogs plugin */ static void calc_dialog_deps(void) { const char *control; int buildin, plugin; /* TODO: get this from librnd */ control = get("/local/module/lib_hid_common/controls"); if (control == NULL) { fprintf(stderr, "librnd configuration error: can't figure how lib_hid_common is configured\n(should be coming from plugin.state as /local/module/lib_hid_common/controls)\n"); exit(1); } buildin = strcmp(control, "buildin") == 0; plugin = strcmp(control, "plugin") == 0; if (buildin) { hook_custom_arg("buildin-draw_csect", NULL); hook_custom_arg("buildin-draw_fontsel", NULL); hook_custom_arg("buildin-dialogs", NULL); hook_custom_arg("buildin-lib_hid_pcbui", NULL); } else if (plugin) { if (!plug_is_buildin("draw_csect")) hook_custom_arg("plugin-draw_csect", NULL); if (!plug_is_buildin("draw_fontsel")) hook_custom_arg("plugin-draw_fontsel", NULL); if (!plug_is_buildin("dialogs")) hook_custom_arg("plugin-dialogs", NULL); if (!plug_is_buildin("lib_hid_pcbui")) hook_custom_arg("plugin-lib_hid_pcbui", NULL); } } /* Runs when things should be detected for the target system */ int hook_detect_target() { int want_gd, want_xml2, want_freetype2, want_fuse; want_gd = plug_is_enabled("export_png"); want_xml2 = plug_is_enabled("io_eagle") || plug_is_enabled("order_pcbway") || plug_is_enabled("stl_export"); want_freetype2 = plug_is_enabled("import_ttf"); want_fuse = plug_is_enabled("export_vfs_fuse"); rnd_hook_detect_cc(); if (rnd_hook_detect_sys() != 0) return 1; if (want_fuse) { require("libs/sul/fuse/*", 0, 0); if (!istrue(get("libs/sul/fuse/presents"))) { report_repeat("WARNING: Since there's no fuse found, disabling export_vfs_fuse plugin...\n"); hook_custom_arg("disable-export_vfs_fuse", NULL); } } if (want_freetype2) { require("libs/sul/freetype2/presents", 0, 0); if (!istrue(get("libs/sul/freetype2/presents"))) { report_repeat("WARNING: Since there's no libfreetype2 found, disabling the import_ttf plugin...\n"); hook_custom_arg("disable-import_ttf", NULL); } } if (want_xml2) { require("libs/sul/libxml2/presents", 0, 0); if (!istrue(get("libs/sul/libxml2/presents"))) { report("libxml2 is not available, disabling io_eagle...\n"); report_repeat("WARNING: Since there's no libxml2 found, disabling the Eagle IO, amf 3d models and pcbway order plugins...\n"); hook_custom_arg("disable-io_eagle", NULL); hook_custom_arg("disable-order_pcbway", NULL); } put("/local/pcb/want_libxml2", strue); } else put("/local/pcb/want_libxml2", strue); calc_dialog_deps(); if (want_gd) { require("libs/gui/gd/presents", 0, 0); if (!istrue(get("libs/gui/gd/presents"))) { report_repeat("WARNING: Since there's no libgd, disabling gd based exports and pixmap imports (png, gif, jpeg)...\n"); hook_custom_arg("disable-export_png", NULL); want_gd = 0; } } else { put("libs/gui/gd/presents", sfalse); } /* yacc/lex - are we able to regenerate languages? */ if (istrue(get("/local/pcb/want_bison"))) { require("parsgen/flex/*", 0, 0); require("parsgen/bison/*", 0, 0); if (!istrue(get("parsgen/flex/presents")) || !istrue(get("parsgen/bison/presents"))) put("/local/pcb/want_parsgen", sfalse); else put("/local/pcb/want_parsgen", strue); } else { report("Bison/flex are disabled, along with parser generation.\n"); put("/local/pcb/want_parsgen", sfalse); } /* byaccic - are we able to regenerate languages? */ if (istrue(get("/local/pcb/want_byaccic"))) { require("parsgen/byaccic/*", 0, 0); require("parsgen/ureglex/*", 0, 0); if (!istrue(get("parsgen/byaccic/presents")) || !istrue(get("parsgen/ureglex/presents"))) put("/local/pcb/want_parsgen_byaccic", sfalse); else put("/local/pcb/want_parsgen_byaccic", strue); } else { report("byaccic/ureglex are disabled, along with parser generation.\n"); put("/local/pcb/want_parsgen_byaccic", sfalse); } /* plugin dependencies */ plugin_deps(1); return 0; } #ifdef GENCALL /* If enabled, generator implements ###call *### and generator_callback is the callback function that will be executed upon ###call### */ void generator_callback(char *cmd, char *args) { printf("* generator_callback: '%s' '%s'\n", cmd, args); } #endif /* Runs after detection hooks, should generate the output (Makefiles, etc.) */ int hook_generate() { char *next, *rev = "non-svn", *curr, *tmp, *sep; int generr = 0; int res = 0; char apiver[32], version_major[32]; long r = 0; int v1, v2, v3; tmp = svn_info(0, "../src", "Revision:"); if (tmp != NULL) { r = strtol(tmp, NULL, 10); rev = str_concat("", "svn r", tmp, NULL); free(tmp); } strcpy(apiver, version); curr = apiver; next = strchr(curr, '.'); *next = '\n'; v1 = atoi(curr); curr = next+1; next = strchr(curr, '.'); *next = '\n'; v2 = atoi(curr); v3 = atoi(next+1); sprintf(apiver, "%01d%01d%02d%05ld", v1, v2, v3, r); strcpy(version_major, version); sep = strchr(version_major, '.'); if (sep != NULL) *sep = '\0'; logprintf(0, "scconfig generate version info: version='%s' rev='%s'\n", version, rev); put("/local/revision", rev); put("/local/version", version); put("/local/version_major", version_major); put("/local/apiver", apiver); put("/local/librnd_ver_req_major", TOSTR(REQ_LIBRND_MAJOR)); put("/local/librnd_ver_req_minor", TOSTR(REQ_LIBRND_MINOR)); printf("\n"); put("/local/pup/sccbox", "../../scconfig/sccbox"); printf("Generating Makefile.conf (%d)\n", generr |= tmpasm("..", "Makefile.conf.in", "Makefile.conf")); printf("Generating src/Makefile (%d)\n", generr |= tmpasm("../src", "Makefile.in", "Makefile")); printf("Generating util/gsch2pcb-rnd/Makefile (%d)\n", generr |= tmpasm("../util", "gsch2pcb-rnd/Makefile.in", "gsch2pcb-rnd/Makefile")); printf("Generating util/bxl2txt/Makefile (%d)\n", generr |= tmpasm("../util", "bxl2txt/Makefile.in", "bxl2txt/Makefile")); printf("Generating pcb-rnd config.h (%d)\n", generr |= tmpasm("..", "config.h.in", "config.h")); if (plug_is_enabled("export_vfs_fuse")) printf("Generating fuse_includes.h (%d)\n", generr |= tmpasm("../src_plugins/export_vfs_fuse", "fuse_includes.h.in", "fuse_includes.h")); if (!generr) { printf("\n\n"); printf("=====================\n"); printf("Configuration summary\n"); printf("=====================\n"); print_sum_setting("/local/pcb/want_parsgen", "Regenerating languages with bison & flex"); print_sum_setting("/local/rnd/debug", "Compilation for debugging"); print_sum_setting_or("/local/rnd/symbols", "Include debug symbols", istrue(get("/local/rnd/debug"))); print_sum_cfg_val("/local/prefix", "installation prefix (--prefix)"); print_sum_cfg_val("/local/confdir", "configuration directory (--confdir)"); print_sum_cfg_val("/local/pcb/dot_pcb_rnd", ".pcb_rnd config dir under $HOME"); print_sum_cfg_val("/local/pcb/want_polybool", "use the new polygon lib (polybool)"); #undef plugin_def #undef plugin_header #undef plugin_dep #define plugin_def(name, desc, default_, all_) plugin3_stat(name, desc) #define plugin_header(sect) printf(sect); #define plugin_dep(plg, on) #include "plugins.h" if (repeat != NULL) { printf("\n%s\n", repeat); } if (all_plugin_check_explicit()) { printf("\nNevertheless the configuration is complete, if you accept these differences\nyou can go on compiling.\n\n"); res = 1; } else printf("\nConfiguration complete, ready to compile.\n\n"); { FILE *f; f = fopen("Rev.stamp", "w"); fprintf(f, "%d", myrev); fclose(f); } } else { fprintf(stderr, "Error generating some of the files\n"); res = 1; } return res; } /* Runs before everything is uninitialized */ void hook_preuninit() { } /* Runs at the very end, when everything is already uninitialized */ void hook_postuninit() { }