diff --git a/configure.ac b/configure.ac index d5e0d2d76..5b11dfc7e 100644 --- a/configure.ac +++ b/configure.ac @@ -1937,6 +1937,8 @@ QF_DEPS(QFDEFS, AC_DEFINE_UNQUOTED(PATH_SEPARATOR, '/', [Define this to your operating system's path separator character]) AC_DEFINE_UNQUOTED(CPP_NAME, "$CPP_NAME", [Define this to the command line for the C preprocessor]) +AC_DEFINE_UNQUOTED(QFCC_INCLUDE_PATH, "$prefix/include/QF/ruamoko", [Define this to where qfcc should look for header files]) +AC_DEFINE_UNQUOTED(QFCC_LIB_PATH, "$prefix/lib/ruamoko", [Define this to where qfcc should look for lib files]) AM_CONDITIONAL(BUILD_GL, test "$BUILD_GL" = "yes") AM_CONDITIONAL(BUILD_SW, test "$BUILD_SW" = "yes") diff --git a/ruamoko/cl_menu/Makefile.am b/ruamoko/cl_menu/Makefile.am index bad9d96f2..e6e2395d7 100644 --- a/ruamoko/cl_menu/Makefile.am +++ b/ruamoko/cl_menu/Makefile.am @@ -42,7 +42,7 @@ menu_src= \ menu_obj=$(addsuffix .qfo,$(basename $(menu_src))) menu.dat$(GZ): $(menu_obj) $(QFCC_DEP) ../lib/libgui.a ../lib/libcsqc.a ../lib/libr.a - $(QFCC) $(QCFLAGS) -p $(STRIP) -o menu.dat $(menu_obj) -l../lib/libgui.a -l../lib/libcsqc.a -l../lib/libr.a + $(QFCC) $(QCFLAGS) -p $(STRIP) -o menu.dat $(menu_obj) ../lib/libgui.a ../lib/libcsqc.a ../lib/libr.a $(GZIP) EXTRA_DIST= $(menu_src) \ diff --git a/ruamoko/game/Makefile.am b/ruamoko/game/Makefile.am index f088b29df..ee3335937 100644 --- a/ruamoko/game/Makefile.am +++ b/ruamoko/game/Makefile.am @@ -30,7 +30,7 @@ game_src= Axe.r GameEntity.r World.r tempent.r game_obj=$(addsuffix .qfo,$(basename $(game_src))) game.dat: $(game_obj) ../lib/libr.a - $(QFCC) $(QCFLAGS) -p $(STRIP) -o game.dat $(game_obj) -l../lib/libr.a + $(QFCC) $(QCFLAGS) -p $(STRIP) -o game.dat $(game_obj) ../lib/libr.a EXTRA_DIST= $(game_src) Axe.h GameEntity.h tempent.h Weapon.h World.h CLEANFILES= *.dat *.sym *.gz *.qfo diff --git a/ruamoko/lib/Makefile.am b/ruamoko/lib/Makefile.am index bc8226767..f26707158 100644 --- a/ruamoko/lib/Makefile.am +++ b/ruamoko/lib/Makefile.am @@ -1,5 +1,7 @@ AUTOMAKE_OPTIONS= foreign +libdir=$(prefix)/lib/ruamoko + QFCC=$(top_builddir)/tools/qfcc/source/qfcc$(EXEEXT) QCFLAGS=-qq -g -Werror QCPPFLAGS=$(INCLUDES) @@ -15,7 +17,7 @@ else libs= endif -noinst_LIBRARIES= $(libs) +lib_LIBRARIES= $(libs) EXTRA_LIBRARIES= $(ruamoko_libs) %.qfo: %.r diff --git a/tools/qfcc/include/linker.h b/tools/qfcc/include/linker.h index 361644085..048b7d408 100644 --- a/tools/qfcc/include/linker.h +++ b/tools/qfcc/include/linker.h @@ -35,6 +35,7 @@ void linker_begin (void); int linker_add_object_file (const char *filename); int linker_add_lib (const char *libname); +void linker_add_path (const char *path); struct qfo_s *linker_finish (void); #endif//__linker_h diff --git a/tools/qfcc/source/linker.c b/tools/qfcc/source/linker.c index bc3b3e1bc..62cd8990b 100644 --- a/tools/qfcc/source/linker.c +++ b/tools/qfcc/source/linker.c @@ -53,6 +53,7 @@ static const char rcsid[] = #include "QF/dstring.h" #include "QF/hash.h" #include "QF/pakfile.h" +#include "QF/va.h" #include "def.h" #include "emit.h" @@ -77,6 +78,11 @@ Xgroup(def) // defgroup_t Xgroup(reloc) // relocgroup_t Xgroup(func) // funcgroup_t +typedef struct path_s { + struct path_s *next; + const char *path; +} path_t; + static hashtab_t *extern_defs; static hashtab_t *defined_defs; static hashtab_t *field_defs; @@ -103,6 +109,9 @@ static int reloc_base; static int func_base; static int line_base; +static path_t *path_head; +static path_t **path_tail = &path_head; + #define DATA(x) (data->data + (x)) #define STRING(x) (strings->strings + (x)) #define TYPE_STRING(x) (type_strings->strings + (x)) @@ -640,22 +649,47 @@ linker_add_object_file (const char *filename) int linker_add_lib (const char *libname) { - pack_t *pack = pack_open (libname); + pack_t *pack; + path_t start = {path_head, "."}; + path_t *path = &start; + const char *path_name; int i, j; int did_something; + if (strncmp (libname, "-l", 2) == 0) { + while (path) { + path_name = va ("%s/lib%s.a", path->path, libname + 2); + pack = pack_open (path_name); + if (pack) + break; + if (errno != ENOENT) { + if (errno) + perror (libname); + return 1; + } + path = path->next; + } + } else { + path_name = libname; + pack = pack_open (path_name); + } + if (!pack) { if (errno) perror (libname); return 1; } + + if (options.verbosity > 1) + puts (path_name); + do { did_something = 0; for (i = 0; i < pack->numfiles; i++) { QFile *f; qfo_t *qfo; - f = Qsubopen (libname, pack->files[i].filepos, + f = Qsubopen (path_name, pack->files[i].filepos, pack->files[i].filelen, 1); qfo = qfo_read (f); Qclose (f); @@ -735,3 +769,13 @@ linker_finish (void) qfo->entity_fields = entity->size; return qfo; } + +void +linker_add_path (const char *path) +{ + path_t *p = malloc (sizeof (path_t)); + p->next = 0; + p->path = path; + *path_tail = p; + path_tail = &p->next; +} diff --git a/tools/qfcc/source/options.c b/tools/qfcc/source/options.c index 1c3859531..78614dae7 100644 --- a/tools/qfcc/source/options.c +++ b/tools/qfcc/source/options.c @@ -49,6 +49,7 @@ static const char rcsid[] = #include "QF/va.h" #include "cpp.h" +#include "linker.h" #include "options.h" #include "qfcc.h" @@ -82,6 +83,7 @@ static struct option const long_options[] = { static const char *short_options = "-" // magic option parsing mode doohicky (must come first) "l:" // lib file + "L:" // lib path "o:" // output file "c" // separate compilation "r" // partial linking @@ -138,7 +140,7 @@ add_file (const char *file) files_size += 16; source_files = realloc (source_files, files_size * sizeof (char *)); } - source_files[num_files++] = strdup (file); + source_files[num_files++] = save_string (file); source_files[num_files] = 0; } @@ -174,12 +176,15 @@ DecodeArgs (int argc, char **argv) this_program); exit (1); } else { - options.output_file = strdup (optarg); + options.output_file = save_string (optarg); } break; case 'l': // lib file add_file (va ("-l%s", optarg)); break; + case 'L': + linker_add_path (optarg); + break; case 'h': // help usage (0); break; @@ -188,10 +193,10 @@ DecodeArgs (int argc, char **argv) exit (0); break; case 's': // src dir - sourcedir = strdup (optarg); + sourcedir = save_string (optarg); break; case 'P': // progs-src - progs_src = strdup (optarg); + progs_src = save_string (optarg); break; case 'p': options.strip_path = atoi (optarg); @@ -307,7 +312,7 @@ DecodeArgs (int argc, char **argv) } break; case 256: // --cpp= - cpp_name = strdup (optarg); + cpp_name = save_string (optarg); break; case 'S': // save temps options.save_temps = true; @@ -361,6 +366,11 @@ DecodeArgs (int argc, char **argv) usage (1); } } + + // add the default paths + add_cpp_def (nva ("-I%s", QFCC_INCLUDE_PATH)); + linker_add_path (QFCC_LIB_PATH); + if (options.verbosity >= 3) yydebug = 1; return optind; diff --git a/tools/qfcc/source/qfcc.c b/tools/qfcc/source/qfcc.c index cc06a0fa2..981474e18 100644 --- a/tools/qfcc/source/qfcc.c +++ b/tools/qfcc/source/qfcc.c @@ -561,10 +561,16 @@ separate_compile (void) qfo_t *qfo; linker_begin (); for (file = source_files; *file; file++) { - if (strncmp (*file, "-l", 2)) - err = linker_add_object_file (*file); - else - err = linker_add_lib (*file + 2); + if (strncmp (*file, "-l", 2)) { + if (strlen (*file) >= 2 + && strcmp (*file + strlen (*file) - 2, ".a") == 0) { + err = linker_add_lib (*file); + } else { + err = linker_add_object_file (*file); + } + } else { + err = linker_add_lib (*file); + } if (err) return err; }