diff --git a/reactos/tools/log2lines/cache.c b/reactos/tools/log2lines/cache.c index 0d79ea29f62..fd5bcc2c303 100644 --- a/reactos/tools/log2lines/cache.c +++ b/reactos/tools/log2lines/cache.c @@ -11,12 +11,10 @@ #include "util.h" #include "version.h" #include "compat.h" -#include "config.h" -#include "list.h" #include "options.h" #include "help.h" #include "image.h" -#include "revision.h" + #include "log2lines.h" static char *cache_name; @@ -77,11 +75,6 @@ check_directory(int force) char *check_iso; char *check_dir; - if (opt_Revision) - { - revinfo.rev = getRevision(NULL, 1); - revinfo.range = DEF_RANGE; - } check_iso = strrchr(opt_dir, '.'); l2l_dbg(1, "Checking directory: %s\n", opt_dir); if (check_iso && PATHCMP(check_iso, ".7z") == 0) @@ -139,11 +132,6 @@ check_directory(int force) return 1; } } - if (opt_Revision) - { - revinfo.buildrev = getTBRevision(opt_dir); - l2l_dbg(1, "Trunk build revision: %d\n", revinfo.buildrev); - } cache_name = malloc(MAX_PATH); tmp_name = malloc(MAX_PATH); strcpy(cache_name, opt_dir); @@ -238,10 +226,11 @@ create_cache(int force, int skipImageBase) l2l_dbg(0, "Scanning %s ...\n", opt_dir); snprintf(Line, LINESIZE, DIR_FMT, opt_dir, tmp_name); l2l_dbg(1, "Executing: %s\n", Line); - if (system(Line) < 0) + if (system(Line) != 0) { l2l_dbg(0, "Cannot list directory %s\n", opt_dir); l2l_dbg(1, "Failed to execute: '%s'\n", Line); + remove(tmp_name); return 2; } l2l_dbg(0, "Creating cache ..."); diff --git a/reactos/tools/log2lines/cache.h b/reactos/tools/log2lines/cache.h index 5a2f7485d3e..b33e5f9b4b5 100644 --- a/reactos/tools/log2lines/cache.h +++ b/reactos/tools/log2lines/cache.h @@ -13,3 +13,5 @@ int read_cache(void); int create_cache(int force, int skipImageBase); #endif /* __L2L_CACHE_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/cmd.c b/reactos/tools/log2lines/cmd.c new file mode 100644 index 00000000000..72877dcb822 --- /dev/null +++ b/reactos/tools/log2lines/cmd.c @@ -0,0 +1,291 @@ +/* + * ReactOS log2lines + * Written by Jan Roeloffzen + * + * - Cli for escape commands + */ +#include +#include +#include + +#include "util.h" +#include "cmd.h" +#include "options.h" +#include "log2lines.h" +#include "help.h" + +/* When you edit the cmd line and/or use the history instead of just typing, + * a bunch of editing BS and space characters + * is inserted, so the string looks right on the console but still + * starts with the original string: + */ +static char +*backSpaceEdit(char *s) +{ + char c; + char *edit = s; + char *text = s; + + while (( c = *edit++ )) + { + switch (c) + { + case KDBG_BS_CHAR: + if (text > s) + text --; + break; + default: + *text++ = c; + } + } + *text = '\0'; + + return s; +} + +static int +handle_switch(FILE *outFile, int *sw, char *arg, char *desc) +{ + int changed =0; + int x = 0; + + if (arg && (strcmp(arg,"") != 0)) + { + x = atoi(arg); + if (x != *sw) + { + *sw = x; + changed = 1; + } + } + if (desc) + { + esclog(outFile, "%s is %d (%s)\n", desc, *sw, changed ? "changed":"unchanged"); + if (!arg) + esclog(outFile, "(readonly)\n"); + } + + return changed; +} + +static int +handle_switch_str(FILE *outFile, char *sw, char *arg, char *desc) +{ + int changed =0; + + if (arg) + { + if (strcmp(arg,"") != 0) + { + if (strcmp(arg,KDBG_ESC_OFF) == 0) + { + if (*sw) + changed = 1; + *sw = '\0'; + } + else if (strcmp(arg, sw) != 0) + { + strcpy(sw, arg); + changed = 1; + } + } + } + if (desc) + { + esclog(outFile, "%s is \"%s\" (%s)\n", desc, sw, changed ? "changed":"unchanged"); + if (!arg) + esclog(outFile, "(readonly)\n"); + } + + return changed; +} + +static int +handle_switch_pstr(FILE *outFile, char **psw, char *arg, char *desc) +{ + int changed =0; + + if (arg) + { + if (strcmp(arg,"") != 0) + { + if (strcmp(arg,KDBG_ESC_OFF) == 0) + { + if (*psw) + changed = 1; + free(*psw); + *psw = NULL; + } + else + { + if (!*psw) + { + *psw = malloc(LINESIZE); + **psw = '\0'; + } + + if (strcmp(arg, *psw) != 0) + { + strcpy(*psw, arg); + changed = 1; + } + } + } + } + if (desc) + { + esclog(outFile, "%s is \"%s\" (%s)\n", desc, *psw, changed ? "changed":"unchanged"); + if (!arg) + esclog(outFile, "(readonly)\n"); + } + + return changed; +} + +char +handle_escape_cmd(FILE *outFile, char *Line, char *path, char *LineOut) +{ + char cmd; + char sep = '\n'; + char *arg; + char *l = Line; + int res = 1; + int cnt = 0; + int changed = 0; + + l = backSpaceEdit(l); + if (l[1] != KDBG_ESC_CHAR) + return l[1]; //for reprocessing as not escaped + + log(outFile, "\n"); + + l += 2; //skip space+escape character + if ( (cnt=sscanf(l,"%c%c",&cmd,&sep)) < 1) + { + esclog(outFile, "Command expected\n"); + res = 0; + } + + if (res && cnt==2 && sep != ' ') + { + esclog(outFile, "' ' expected\n"); + res = 0; + } + l++; //skip cmd + while ( *l == ' ')l++; //skip more spaces + arg = l; + opt_cli = 1; + switch (cmd) + { + case 'h': + usage(1); + break; + case 'b': + if (handle_switch(outFile, &opt_buffered, arg, "-b Logfile buffering")) + set_LogFile(logFile); //re-open same logfile + break; + case 'c': + handle_switch(outFile, &opt_console, NULL, "-c Console option"); + break; + case 'd': + handle_switch_str(outFile, opt_dir, NULL, "-d Directory option"); + break; + case 'l': + if (handle_switch_str(outFile, opt_logFile, arg, "-l logfile")) + set_LogFile(logFile); //open new logfile + break; + case 'm': + handle_switch(outFile, &opt_Mark, arg, "-m mark (*)"); + break; + case 'M': + handle_switch(outFile, &opt_Mark, arg, "-M Mark (?)"); + break; + case 'P': + handle_switch_str(outFile, opt_Pipe, NULL, "-P Pipeline option"); + break; + case 'q': + opt_quit = 1; + esclog(outFile, "Bye!\n"); + break; + case 'r': + handle_switch(outFile, &opt_raw, arg, "-r Raw"); + break; + case 'R': + changed = handle_switch_pstr(outFile, &opt_Revision, arg, NULL); + if (opt_Revision) + { + if (strstr(opt_Revision, "check") == opt_Revision) + { + esclog(outFile, "-R is \"%s\" (%s)\n", opt_Revision, changed ? "changed":"unchanged"); + } + else if (strstr(opt_Revision, "regscan") == opt_Revision) + { + char *s = strchr(opt_Revision, ','); + + revinfo.range = DEF_RANGE; + if (s) + { + *s++ = '\0'; + revinfo.range = atoi(s); + } + regscan(outFile); + } + else if (strstr(opt_Revision, "regclear") == opt_Revision) + { + list_clear(&sources); + summ.regfound = 0; + esclog(outFile, "cleared regression scan results\n"); + } + } + break; + case 's': + if (strcmp(arg,"clear") == 0) + { + memset(&summ, 0, sizeof(SUMM)); + esclog(outFile, "Statistics cleared\n"); + } + else + stat_print(outFile, &summ); + break; + case 'S': + cnt = sscanf(arg, "%d+%d", &opt_Source, &opt_SrcPlus); + if (opt_Source) + { + handle_switch(outFile, &opt_undo, "1", "-u Undo"); + handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess"); + } + esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath); + esclog(outFile, "(Setting source tree not implemented)\n"); + break; + case 't': + handle_switch(outFile, &opt_twice, arg, "-t Translate twice"); + break; + case 'T': + handle_switch(outFile, &opt_twice, arg, NULL); + handle_switch(outFile, &opt_Twice, arg, "-T Translate for (address-1)"); + break; + case 'u': + handle_switch(outFile, &opt_undo, arg, "-u undo"); + break; + case 'U': + handle_switch(outFile, &opt_undo, arg, NULL); + handle_switch(outFile, &opt_redo, arg, "-U Undo and reprocess"); + break; + case 'v': + handle_switch(outFile, &opt_verbose, arg, "-v Verbosity"); + break; + case 'z': + handle_switch_str(outFile, opt_7z, NULL, "-z 7z path"); + break; + default: + if (strchr(optchars, cmd)) + esclog(outFile, "Command not implemented in cli: %c %s\n",cmd, arg) + else + esclog(outFile, "Unknown command: %c %s\n",cmd, arg); + } + opt_cli = 0; + + memset(Line, '\0', LINESIZE); // flushed + + return KDBG_ESC_CHAR; //handled escaped command +} diff --git a/reactos/tools/log2lines/cmd.h b/reactos/tools/log2lines/cmd.h new file mode 100644 index 00000000000..c6b7d052043 --- /dev/null +++ b/reactos/tools/log2lines/cmd.h @@ -0,0 +1,26 @@ +/* + * ReactOS log2lines + * Written by Jan Roeloffzen + * + * - Cli for escape commands + */ + +#ifndef __L2L_CMD_H__ +#define __L2L_CMD_H__ + +#include + +#define KDBG_BS_CHAR 0x08 +#define KDBG_ESC_CHAR '`' +#define KDBG_ESC_STR "`" +#define KDBG_ESC_RESP "| L2L- " +#define KDBG_ESC_OFF "off" +#define KDBG_PROMPT "kdb:>" //Start interactive (-c) after this pattern +#define KDBG_CONT "---" //Also after this pattern (prompt with no line ending) +#define KDBG_DISCARD "Command '" KDBG_ESC_STR //Discard responses at l2l escape commands + +char handle_escape_cmd(FILE *outFile, char *Line, char *path, char *LineOut); + +#endif /* __L2L_CMD_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/compat.h b/reactos/tools/log2lines/compat.h index dfc1b4203ba..76d87681ce0 100644 --- a/reactos/tools/log2lines/compat.h +++ b/reactos/tools/log2lines/compat.h @@ -37,3 +37,5 @@ #endif /* __L2L_COMPAT_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/config.h b/reactos/tools/log2lines/config.h index a11ed1e2444..c1a29d22f9c 100644 --- a/reactos/tools/log2lines/config.h +++ b/reactos/tools/log2lines/config.h @@ -15,7 +15,6 @@ #define CACHEFILE "log2lines.cache" #define TRKBUILDPREFIX "bootcd-" #define SVN_PREFIX "/trunk/reactos/" -#define KDBG_PROMPT "kdbg>" #define PIPEREAD_CMD "piperead -c" @@ -32,3 +31,5 @@ PATH_STR "reactos" PATH_STR "reactos > " DEV_NULL #define NAMESIZE 80 #endif /* __L2L_CONFIG_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/help.c b/reactos/tools/log2lines/help.c index a0484a7512a..37e6bf400f8 100644 --- a/reactos/tools/log2lines/help.c +++ b/reactos/tools/log2lines/help.c @@ -10,6 +10,7 @@ #include "compat.h" #include "config.h" #include "options.h" +#include "cmd.h" #include "help.h" char *verboseUsage = @@ -76,7 +77,7 @@ char *verboseUsage = " - regscan[,]:\n" " Scan for regression candidates. Essentially it tries to find\n" " matches between the SVN log entries and the sources hit by\n" -" the backtrace.\n" +" a backtrace (bt) command.\n" " is the amount of revisions to look back from the build\n" " revision (default 500)\n" " The output of '-R regscan' is printed after EOF. The 'Changed path'\n" @@ -130,7 +131,25 @@ char *verboseUsage = " : Specify path to 7z. See also option -d.\n" " Default: '7z'\n" "\n" -"Examples:\n" +"CLI escape commands:\n" +" It is possible to change options and perform actions from the 'kdb:>' prompt\n" +" By prepending the `(backquote) character to the option.\n" +" Example: 'kdb:> `l new.log' changes the current logfile to 'new.log'.\n" +" Flag options like 'b' are given a numeric value of 0 (off) or 1 (on).\n" +" Options accepting a string as argument can be cleared by the value '" KDBG_ESC_OFF "'.\n" +" Some ClI commands are read only or not (entirely) implemented.\n" +" If no value is provided, the current one is printed.\n" +" There are only a few extra ClI commands or with different behaviour:\n" +" - `h : shows this helptext (without exiting)\n" +" - `q : quits log2lines\n" +" - `R regscan : the output is printed immediately (do a 'bt' first)\n" +" - `R regclear : clears previous regscan matches\n" +" - `s : the output is printed immediately\n" +" - `s clear : clears all statistics.\n" +" - `S : only and can be set.\n" +" - `v : sets the current debug loglevel\n" +"\n" +"Option Examples:\n" " Setup: A VMware machine with its serial port set to: '\\\\.\\pipe\\kdbg'.\n\n" " Just recreate cache after a svn update or a new module has been added:\n" " log2lines -F\n\n" @@ -179,7 +198,42 @@ char *verboseUsage = " \n" " | R--- Conflict : source(44191) > build(43850)\n" " | 2664 else\n" -" | 2665 rc = MSIREG_OpenUserDataKey(comp->ComponentId,\n" +" | 2665 rc = MSIREG_OpenUserDataKey(comp->ComponentId,\n\n" +"CLI Examples: (some are based on the option examples above)\n" +" Use '`R check' to show that action.c has been changed after the build:\n" +" kdb:> `R check\n" +" | L2L- -R is \"check\" (changed)\n" +" kdb:> bt\n" +" \n" +" | 0780 if (create)\n" +" | 0781 rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);\n" +" \n" +" | R--- Conflict : source(44191) > build(43850)\n" +" | 2664 else\n" +" | 2665 rc = MSIREG_OpenUserDataKey(comp->ComponentId,\n\n" +" kdb:>\n\n" +" Generate source lines. Show 2 lines of context plus 1 additional line.\n" +" The -Uu options are dependent on -S:\n" +" kdb:> `S 2+1\n" +" | L2L- -u Undo is 1 (changed)\n" +" | L2L- -U Undo and reprocess is 1 (changed)\n" +" | L2L- -S Sources option is 2+1,\"C:\\ROS\\reactos\\\" \n" +" | L2L- (Setting source tree not implemented)\n" +" kdb:> bt\n" +" \n" +" | 0188 {\n" +" | 0189 r = MSI_ViewFetch( view, &rec );\n" +" | ----\n" +" | 0190 if( r != ERROR_SUCCESS )\n" +" kdb:>\n\n" +" Change logfile:\n" +" kdb:> `l\n" +" | L2L- -l logfile is "" (unchanged)\n" +" kdb:> `l new.log\n" +" | L2L- -l logfile is \"new.log\" (changed)\n" +" kdb:> `l off\n" +" | L2L- -l logfile is "" (changed)\n" +" kdb:>\n" "\n"; void diff --git a/reactos/tools/log2lines/help.h b/reactos/tools/log2lines/help.h index 8116a7dcb22..5f2ab3893da 100644 --- a/reactos/tools/log2lines/help.h +++ b/reactos/tools/log2lines/help.h @@ -13,3 +13,5 @@ extern char *verboseUsage; void usage(int verbose); #endif /* __L2L_HELP_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/image.c b/reactos/tools/log2lines/image.c index 555196ec856..f94abcb59c8 100644 --- a/reactos/tools/log2lines/image.c +++ b/reactos/tools/log2lines/image.c @@ -4,6 +4,7 @@ * * - Image functions for symbol info */ +#include #include #include #include diff --git a/reactos/tools/log2lines/image.h b/reactos/tools/log2lines/image.h index 6c510a09748..acc6712e695 100644 --- a/reactos/tools/log2lines/image.h +++ b/reactos/tools/log2lines/image.h @@ -20,3 +20,5 @@ int get_ImageBase(char *fname, size_t *ImageBase); #endif /* __L2L_IMAGE_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/list.c b/reactos/tools/log2lines/list.c index 2fa306f4a14..4491d079252 100644 --- a/reactos/tools/log2lines/list.c +++ b/reactos/tools/log2lines/list.c @@ -66,6 +66,19 @@ entry_insert(PLIST list, PLIST_MEMBER pentry) return pentry; } +void list_clear(PLIST list) +{ + PLIST_MEMBER pentry = list->phead; + PLIST_MEMBER pnext; + while (pentry) + { + pnext = pentry->pnext; + entry_delete(pentry); + pentry = pnext; + } + list->phead = list->ptail = NULL; +} + #if 0 LIST_MEMBER * entry_remove(LIST *list, LIST_MEMBER *pentry) diff --git a/reactos/tools/log2lines/list.h b/reactos/tools/log2lines/list.h index ce0934f794e..e23fbc48cbe 100644 --- a/reactos/tools/log2lines/list.h +++ b/reactos/tools/log2lines/list.h @@ -12,7 +12,6 @@ typedef struct entry_struct typedef struct list_struct { - off_t st_size; PLIST_MEMBER phead; PLIST_MEMBER ptail; } LIST,*PLIST; @@ -22,5 +21,8 @@ PLIST_MEMBER entry_delete(PLIST_MEMBER pentry); PLIST_MEMBER entry_insert(PLIST list, PLIST_MEMBER pentry); PLIST_MEMBER cache_entry_create(char *Line); PLIST_MEMBER sources_entry_create(PLIST list, char *path, char *prefix); +void list_clear(PLIST list); #endif /* __L2L_LIST_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/log2lines.c b/reactos/tools/log2lines/log2lines.c index 03c49445785..1ad94f2fb0e 100644 --- a/reactos/tools/log2lines/log2lines.c +++ b/reactos/tools/log2lines/log2lines.c @@ -2,7 +2,7 @@ * ReactOS log2lines * Written by Jan Roeloffzen * - * - Initialization and main loop + * - Initialization, translation and main loop */ #include @@ -13,17 +13,18 @@ #include "util.h" #include "version.h" #include "compat.h" -#include "config.h" -#include "list.h" #include "options.h" #include "image.h" #include "cache.h" #include "log2lines.h" #include "help.h" +#include "cmd.h" static FILE *stdIn = NULL; static FILE *stdOut = NULL; +static const char *kdbg_prompt = KDBG_PROMPT; +static const char *kdbg_cont = KDBG_CONT; LIST sources; LINEINFO lastLine; @@ -65,6 +66,8 @@ log_file(FILE *outFile, char *fileName, int line) i++; } fclose(src); + if ( i < min ) + log(outFile, "| S--- source has only %d lines! (check source/revision)\n", i); } else l2l_dbg(1, "Can't open: %s (check " SOURCES_ENV ")\n", s); @@ -332,7 +335,7 @@ translate_line(FILE *outFile, char *Line, char *path, char *LineOut) /* Strip all lines added by this tool: */ char buf[NAMESIZE]; if (sscanf(s, "| %s", buf) == 1) - if (buf[0] == '0' || strcmp(buf, "----") == 0 || strcmp(buf, "R---") == 0 || atoi(buf)) + if (buf[0] == '0' || strcmp(buf, "----") == 0 || strcmp(buf, "L2L-") == 0 || strcmp(buf, "S---") == 0 || strcmp(buf, "R---") == 0 || atoi(buf)) res = 0; } @@ -410,6 +413,9 @@ translate_files(FILE *inFile, FILE *outFile) int c; unsigned char ch; int i = 0; + const char *pc = kdbg_cont; + const char *p = kdbg_prompt; + const char *p_eos = p + sizeof(KDBG_PROMPT) - 1; //end of string pos if (Line && path && LineOut) { @@ -418,23 +424,53 @@ translate_files(FILE *inFile, FILE *outFile) { while ((c = fgetc(inFile)) != EOF) { + if (opt_quit)break; + ch = (unsigned char)c; if (!opt_raw) { switch (ch) { case '\n': - translate_line(outFile, Line, path, LineOut); + if ( strncmp(Line, KDBG_DISCARD, sizeof(KDBG_DISCARD)-1) == 0 ) + { + memset(Line, '\0', LINESIZE); // flushed + } + else + { + Line[1] = handle_escape_cmd(outFile, Line, path, LineOut); + if (Line[1] != KDBG_ESC_CHAR) + { + if (p == p_eos) + { + //kdbg prompt, so already echoed char by char + memset(Line, '\0', LINESIZE); + translate_char(c, outFile); + } + else + { + translate_line(outFile, Line, path, LineOut); + translate_char(c, outFile); + report(outFile); + } + } + } i = 0; - translate_char(c, outFile); - report(outFile); + p = kdbg_prompt; + pc = kdbg_cont; break; case '<': i = 0; Line[i++] = ch; break; case '>': - if (i) + if (ch == *p) + { + p = p_eos; + translate_line(outFile, Line, path, LineOut); + } + + if (p != p_eos) { if (i < LINESIZE) { @@ -452,21 +488,27 @@ translate_files(FILE *inFile, FILE *outFile) i = 0; break; default: - if (i) + if (ch == *p)p++; + if (ch == *pc)pc++; + if (i < LINESIZE) { - if (i < LINESIZE) + Line[i++] = ch; + if (p == p_eos) { - Line[i++] = ch; + translate_char(c, outFile); } - else + else if (!*pc) { translate_line(outFile, Line, path, LineOut); - translate_char(c, outFile); i = 0; } } else + { + translate_line(outFile, Line, path, LineOut); translate_char(c, outFile); + i = 0; + } } } else @@ -477,6 +519,8 @@ translate_files(FILE *inFile, FILE *outFile) { // Line by line, slightly faster but less interactive while (fgets(Line, LINESIZE, inFile) != NULL) { + if (opt_quit)break; + if (!opt_raw) { translate_line(outFile, Line, path, LineOut); @@ -552,26 +596,8 @@ main(int argc, const char **argv) read_cache(); l2l_dbg(4, "Cache read complete\n"); - if (*opt_logFile) - { - logFile = fopen(opt_logFile, "a"); - if (logFile) - { - // disable buffering so fflush is not needed - if (!opt_buffered) - { - l2l_dbg(1, "Disabling log buffering on %s\n", opt_logFile); - setbuf(logFile, NULL); - } - else - l2l_dbg(1, "Enabling log buffering on %s\n", opt_logFile); - } - else - { - l2l_dbg(0, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno)); - return 2; - } - } + if (set_LogFile(logFile)) + return 2; l2l_dbg(4, "opt_logFile processed\n"); if (opt_Pipe) @@ -584,8 +610,6 @@ main(int argc, const char **argv) l2l_dbg(0, "Could not popen '%s' (%s)\n", opt_Pipe, strerror(errno)); free(opt_Pipe); opt_Pipe = NULL; } - - free(opt_Pipe); opt_Pipe = NULL; } l2l_dbg(4, "opt_Pipe processed\n"); diff --git a/reactos/tools/log2lines/log2lines.mak b/reactos/tools/log2lines/log2lines.mak index 5e4e14c31ae..358fd83d4e8 100644 --- a/reactos/tools/log2lines/log2lines.mak +++ b/reactos/tools/log2lines/log2lines.mak @@ -30,6 +30,7 @@ LOG2LINES_SOURCES = \ $(LOG2LINES_BASE_)image.c \ $(LOG2LINES_BASE_)stat.c \ $(LOG2LINES_BASE_)revision.c \ + $(LOG2LINES_BASE_)cmd.c \ $(LOG2LINES_BASE_)log2lines.c \ $(RSYM_BASE_)rsym_common.c @@ -83,6 +84,10 @@ $(LOG2LINES_INT_)revision.o: $(LOG2LINES_BASE_)revision.c | $(LOG2LINES_INT) $(ECHO_HOSTCC) ${host_gcc} $(LOG2LINES_HOST_CFLAGS) -c $< -o $@ +$(LOG2LINES_INT_)cmd.o: $(LOG2LINES_BASE_)cmd.c | $(LOG2LINES_INT) + $(ECHO_HOSTCC) + ${host_gcc} $(LOG2LINES_HOST_CFLAGS) -c $< -o $@ + .PHONY: log2lines_clean log2lines_clean: -@$(rm) $(LOG2LINES_TARGET) $(LOG2LINES_OBJECTS) 2>$(NUL) diff --git a/reactos/tools/log2lines/options.c b/reactos/tools/log2lines/options.c index 1ed55edea7f..88d7f4b9e37 100644 --- a/reactos/tools/log2lines/options.c +++ b/reactos/tools/log2lines/options.c @@ -13,6 +13,7 @@ #include "compat.h" #include "config.h" #include "help.h" +#include "log2lines.h" #include "options.h" char *optchars = "bcd:fFhl:mMP:rR:sS:tTuUvz:"; @@ -25,6 +26,8 @@ int opt_console = 0; // -c int opt_mark = 0; // -m int opt_Mark = 0; // -M char *opt_Pipe = NULL; // -P +int opt_quit = 0; // -q (cli only) +int opt_cli = 0; // (cli internal) int opt_raw = 0; // -r int opt_stats = 0; // -s int opt_Source = 0; // -S [+][,] @@ -46,29 +49,45 @@ int optionInit(int argc, const char **argv) char *s; strcpy(opt_dir, ""); + strcpy(opt_logFile, ""); + strcpy(opt_7z, CMD_7Z); strcpy(opt_SourcesPath, ""); if ((s = getenv(SOURCES_ENV))) strcpy(opt_SourcesPath, s); + revinfo.rev = getRevision(NULL, 1); + revinfo.range = DEF_RANGE; + revinfo.buildrev = getTBRevision(opt_dir); + l2l_dbg(1, "Trunk build revision: %d\n", revinfo.buildrev); strcpy(opt_scanned, ""); for (i = 1; i < argc; i++) { - if (strcmp(argv[i],"-P")==0) + if ((argv[i][0] == '-') && (i+1 < argc)) { - //Because its argument can contain spaces we cant use getopt(), a known bug: - if (i+1 < argc) + //Because these arguments can contain spaces we cant use getopt(), a known bug: + switch (argv[i][1]) { + case 'd': + strcpy(opt_dir, argv[i+1]); + break; + case 'l': + strcpy(opt_logFile, argv[i+1]); + break; + case 'P': free(opt_Pipe); opt_Pipe = malloc(LINESIZE); strcpy(opt_Pipe, argv[i+1]); + break; + case 'z': + strcpy(opt_7z, argv[i+1]); + break; } } strcat(opt_scanned, argv[i]); strcat(opt_scanned, " "); } + l2l_dbg(4,"opt_scanned=[%s]\n",opt_scanned); - strcpy(opt_logFile, ""); - strcpy(opt_7z, CMD_7Z); return 0; } @@ -91,7 +110,7 @@ int optionParse(int argc, const char **argv) break; case 'd': optCount++; - strcpy(opt_dir, optarg); + //just count, see optionInit() break; case 'f': opt_force++; @@ -107,7 +126,7 @@ int optionParse(int argc, const char **argv) break; case 'l': optCount++; - strcpy(opt_logFile, optarg); + //just count, see optionInit() break; case 'm': opt_mark++; @@ -120,7 +139,7 @@ int optionParse(int argc, const char **argv) break; case 'P': optCount++; - //just count, see above + //just count, see optionInit() break; case 'R': optCount++; @@ -137,6 +156,12 @@ int optionParse(int argc, const char **argv) if (i == 1) sscanf(optarg, "%*d,%s", opt_SourcesPath); l2l_dbg(3, "Sources option parse result: %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath); + if (opt_Source) + { + /* need to retranslate for source info: */ + opt_undo++; + opt_redo++; + } break; case 't': opt_twice++; @@ -166,16 +191,15 @@ int optionParse(int argc, const char **argv) } optCount++; } + if(opt_console) + { + l2l_dbg(2, "Note: use 's' command in console mode. Statistics option disabled\n"); + opt_stats = 0; + } if (opt_SourcesPath[0]) { strcat(opt_SourcesPath, PATH_STR); } - if (opt_Source) - { - /* need to retranslate for source info: */ - opt_undo++; - opt_redo++; - } if (!opt_dir[0]) { strcpy(opt_dir, opt_SourcesPath); diff --git a/reactos/tools/log2lines/options.h b/reactos/tools/log2lines/options.h index 77ae8a55bfa..8051eaa9880 100644 --- a/reactos/tools/log2lines/options.h +++ b/reactos/tools/log2lines/options.h @@ -18,6 +18,8 @@ extern int opt_console; // -c extern int opt_mark; // -m extern int opt_Mark; // -M extern char *opt_Pipe; // -P +extern int opt_quit; // -q (cli only) +extern int opt_cli; // (cli internal) extern int opt_raw; // -r extern int opt_stats; // -s extern int opt_Source; // -S [+][,] @@ -38,3 +40,5 @@ int optionInit(int argc, const char **argv); int optionParse(int argc, const char **argv); #endif /* __L2L_OPTIONS_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/revision.c b/reactos/tools/log2lines/revision.c index 74a03528686..5a05bc66ef3 100644 --- a/reactos/tools/log2lines/revision.c +++ b/reactos/tools/log2lines/revision.c @@ -13,7 +13,6 @@ #include "compat.h" #include "util.h" #include "options.h" -#include "revision.h" #include "log2lines.h" static void @@ -195,7 +194,7 @@ regscan(FILE *outFile) char path[MAX_PATH]; char path2[MAX_PATH]; int wflag = 0; - log(outFile, "\nRegression candidates:\n"); + clilog(outFile, "Regression candidates:\n"); while (( pos = findRev(finx, &r) )) { if (r < (revinfo.buildrev - revinfo.range)) @@ -216,11 +215,11 @@ regscan(FILE *outFile) { if (wflag == 1) { - log(outFile, "%sChanged paths:\n", line); + clilog(outFile, "%sChanged paths:\n", line); summ.regfound++; wflag = 2; } - log(outFile, "%s", line2); + clilog(outFile, "%s", line2); } } else @@ -229,11 +228,11 @@ regscan(FILE *outFile) if (wflag == 2) { int i = 0; - log(outFile, "\n"); + clilog(outFile, "\n"); while (fgets(line2, LINESIZE, flog)) { i++; - log(outFile, "%s", line2); + clilog(outFile, "%s", line2); if (strncmp(LOGBOTTOM, line2, sizeof(LOGBOTTOM) - 1) == 0) break; } diff --git a/reactos/tools/log2lines/revision.h b/reactos/tools/log2lines/revision.h index 145052e0c53..7a43be9b77a 100644 --- a/reactos/tools/log2lines/revision.h +++ b/reactos/tools/log2lines/revision.h @@ -26,3 +26,5 @@ int regscan(FILE *outFile); int updateSvnlog(void); #endif /* __L2L_REVISION_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/stat.c b/reactos/tools/log2lines/stat.c index 79870857f74..6f8e5fe83c2 100644 --- a/reactos/tools/log2lines/stat.c +++ b/reactos/tools/log2lines/stat.c @@ -10,7 +10,7 @@ #include "version.h" #include "options.h" -#include "stat.h" +#include "util.h" #include "log2lines.h" void @@ -18,22 +18,22 @@ stat_print(FILE *outFile, PSUMM psumm) { if (outFile) { - fprintf(outFile, "\n*** LOG2LINES SUMMARY ***\n"); - fprintf(outFile, "Translated: %d\n", psumm->translated); - fprintf(outFile, "Reverted: %d\n", psumm->undo); - fprintf(outFile, "Retranslated: %d\n", psumm->redo); - fprintf(outFile, "Skipped: %d\n", psumm->skipped); - fprintf(outFile, "Differ: %d\n", psumm->diff); - fprintf(outFile, "Differ (function/source): %d\n", psumm->majordiff); - fprintf(outFile, "Revision conflicts: %d\n", psumm->revconflicts); - fprintf(outFile, "Regression candidates: %d\n", psumm->regfound); - fprintf(outFile, "Offset error: %d\n", psumm->offset_errors); - fprintf(outFile, "Total: %d\n", psumm->total); - fprintf(outFile, "-------------------------------\n"); - fprintf(outFile, "Log2lines version: " LOG2LINES_VERSION "\n"); - fprintf(outFile, "Directory: %s\n", opt_dir); - fprintf(outFile, "Passed options: %s\n", opt_scanned); - fprintf(outFile, "-------------------------------\n"); + clilog(outFile, "*** LOG2LINES SUMMARY ***\n"); + clilog(outFile, "Translated: %d\n", psumm->translated); + clilog(outFile, "Reverted: %d\n", psumm->undo); + clilog(outFile, "Retranslated: %d\n", psumm->redo); + clilog(outFile, "Skipped: %d\n", psumm->skipped); + clilog(outFile, "Differ: %d\n", psumm->diff); + clilog(outFile, "Differ (function/source): %d\n", psumm->majordiff); + clilog(outFile, "Revision conflicts: %d\n", psumm->revconflicts); + clilog(outFile, "Regression candidates: %d\n", psumm->regfound); + clilog(outFile, "Offset error: %d\n", psumm->offset_errors); + clilog(outFile, "Total: %d\n", psumm->total); + clilog(outFile, "-------------------------------\n"); + clilog(outFile, "Log2lines version: " LOG2LINES_VERSION "\n"); + clilog(outFile, "Directory: %s\n", opt_dir); + clilog(outFile, "Passed options: %s\n", opt_scanned); + clilog(outFile, "-------------------------------\n"); } } diff --git a/reactos/tools/log2lines/stat.h b/reactos/tools/log2lines/stat.h index df0990a872f..6aced4766cd 100644 --- a/reactos/tools/log2lines/stat.h +++ b/reactos/tools/log2lines/stat.h @@ -28,3 +28,5 @@ void stat_print(FILE *outFile, PSUMM psumm); void stat_clear(PSUMM psumm); #endif /* __L2L_STAT_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/util.c b/reactos/tools/log2lines/util.c index a60a7a74a80..50887e3c456 100644 --- a/reactos/tools/log2lines/util.c +++ b/reactos/tools/log2lines/util.c @@ -15,6 +15,39 @@ #include "util.h" #include "options.h" +int +set_LogFile(FILE *logFile) +{ + if (*opt_logFile) + { + if (logFile) + fclose(logFile); + logFile = NULL; + + if (strcmp(opt_logFile,"none") == 0) + return 0; //just close + + logFile = fopen(opt_logFile, "a"); + if (logFile) + { + // disable buffering so fflush is not needed + if (!opt_buffered) + { + l2l_dbg(1, "Disabling log buffering on %s\n", opt_logFile); + setbuf(logFile, NULL); + } + else + l2l_dbg(1, "Enabling log buffering on %s\n", opt_logFile); + } + else + { + l2l_dbg(0, "Could not open logfile %s (%s)\n", opt_logFile, strerror(errno)); + return 2; + } + } + return 0; +} + int file_exists(char *name) { diff --git a/reactos/tools/log2lines/util.h b/reactos/tools/log2lines/util.h index 2facfb5c3c9..b4736f598f0 100644 --- a/reactos/tools/log2lines/util.h +++ b/reactos/tools/log2lines/util.h @@ -8,6 +8,9 @@ #ifndef __L2L_UTIL_H__ #define __L2L_UTIL_H__ +#include + +#include "cmd.h" #define log(outFile, fmt, ...) \ { \ @@ -16,6 +19,19 @@ fprintf(logFile, fmt, ##__VA_ARGS__); \ } +#define esclog(outFile, fmt, ...) \ + { \ + log(outFile, KDBG_ESC_RESP fmt, ##__VA_ARGS__); \ + } + +#define clilog(outFile, fmt, ...) \ + { \ + if (opt_cli) \ + esclog(outFile, fmt, ##__VA_ARGS__) \ + else \ + log(outFile, fmt, ##__VA_ARGS__); \ + } + #define l2l_dbg(level, ...) \ { \ if (opt_verbose >= level) \ @@ -29,5 +45,8 @@ const char *getFmt(const char *a); long my_atoi(const char *a); int isOffset(const char *a); int copy_file(char *src, char *dst); +int set_LogFile(FILE *logFile); #endif /* __L2L_UTIL_H__ */ + +/* EOF */ diff --git a/reactos/tools/log2lines/version.h b/reactos/tools/log2lines/version.h index 6f257ce3639..9a42e4904a3 100644 --- a/reactos/tools/log2lines/version.h +++ b/reactos/tools/log2lines/version.h @@ -8,6 +8,8 @@ #ifndef __L2L_VERSION_H__ #define __L2L_VERSION_H__ -#define LOG2LINES_VERSION "1.12b" +#define LOG2LINES_VERSION "2.1" #endif /* __L2L_VERSION_H__ */ + +/* EOF */ diff --git a/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak b/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak index c46409784c0..f54acd005a7 100644 --- a/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak +++ b/reactos/tools/rbuild/backend/mingw/compilers/gcc.mak @@ -16,6 +16,12 @@ BUILTIN_CFLAGS+= -fno-optimize-sibling-calls endif BUILTIN_CXXFLAGS+= -fno-optimize-sibling-calls +# Add -fno-set-stack-executable required for x86/MinGW +ifneq (,$(filter $(ARCH), i386)) + BUILTIN_CFLAGS+= -fno-set-stack-executable + BUILTIN_CXXFLAGS+= -fno-set-stack-executable +endif + #(module, source, dependencies, cflags, output) define RBUILD_DEPENDS @@ -161,4 +167,3 @@ ${call RBUILD_intermediate_dir,$(2)}$$(SEP).gch_$(1)$$(SEP)$(notdir $(2)).gch: $ endif endef - diff --git a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak index d97e40bd2ec..ad95cfb0337 100644 --- a/reactos/tools/rbuild/backend/mingw/linkers/ld.mak +++ b/reactos/tools/rbuild/backend/mingw/linkers/ld.mak @@ -1,5 +1,6 @@ -LDFLAG_DLL:=-shared -LDFLAG_DRIVER:=-shared --subsystem=native +# -exclude-all-symbols disables autoexporting all symbols *if none were found* (either in a DEF file or using __declspec(dllexport) +LDFLAG_DLL:=-shared -exclude-all-symbols +LDFLAG_DRIVER:=-shared --subsystem=native -exclude-all-symbols LDFLAG_NOSTDLIB:=-nostartfiles -nostdlib LDFLAG_CONSOLE:=--subsystem=console LDFLAG_WINDOWS:=--subsystem=windows diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index 2eb5a263fb7..bb5d1fc5ca8 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -487,11 +487,8 @@ MingwBackend::GenerateGlobalVariables () const fputs ( "BUILTIN_CXXINCLUDES+= $(TARGET_CPPFLAGS)\n", fMakefile ); fprintf ( fMakefile, "PROJECT_CCLIBS := \"$(shell ${TARGET_CC} -print-libgcc-file-name)\"\n" ); - fprintf ( fMakefile, "PROJECT_CXXLIBS := \"$(shell ${TARGET_CPP} -print-file-name=libstdc++.a)\" \"$(shell ${TARGET_CPP} -print-libgcc-file-name)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingw32.a)\" \"$(shell ${TARGET_CPP} -print-file-name=libmingwex.a)\" " ); - /* hack to get libgcc_eh.a, should check mingw version or something */ if (Environment::GetArch() == "amd64") - fprintf ( fMakefile, " \"$(shell ${TARGET_CPP} -print-file-name=libgcc_eh.a)\"" ); /* hack to get _get_output_format, needed by libmingwex */ else if (Environment::GetArch() == "i386") fprintf ( fMakefile, "\"$(shell ${TARGET_CPP} -print-file-name=ofmt_stub.a)\""); @@ -916,7 +913,7 @@ MingwBackend::GetBinutilsVersion ( const string& binutilsCommand ) bool MingwBackend::IsSupportedCompilerVersion ( const string& compilerVersion ) { - if ( strcmp ( compilerVersion.c_str (), "4.4.2") < 0 ) + if ( strcmp ( compilerVersion.c_str (), "4.4.0") < 0 ) return false; else return true; @@ -980,18 +977,18 @@ MingwBackend::IsSupportedBinutilsVersion ( const string& binutilsVersion ) { int digit = binutilsVersion.find_last_of("."); if(digit == -1) - { + { printf("Unable to detect binutils version!\n"); return false; - } - + } + string date = string(binutilsVersion, digit + 1); if(date.length() == 8) { /* This is a real date in the format YYYYMMDD. - Check whether we have at least Binutils 20091017 (older versions - don't support the -exclude-all-symbols option we use). */ - if(strcmp(date.c_str(), "20091119") < 0) + Check whether we have at least Binutils 20091016 (the oldest one + we were still using after upgrading to RosBE 1.5). */ + if(strcmp(date.c_str(), "20091016") < 0) return false; } else diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index 282112fda26..254ade6aab1 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -1021,7 +1021,7 @@ MingwModuleHandler::GenerateObjectMacros ( } CleanupCompilationUnitVector ( sourceCompilationUnits ); - if ( IsSpecDefinitionFile() ) + if ( module.IsSpecDefinitionFile() ) { const FileLocation *stubs_file = new FileLocation( IntermediateDirectory, @@ -1826,7 +1826,7 @@ MingwModuleHandler::GenerateRules () } - spec = IsSpecDefinitionFile(); + spec = module.IsSpecDefinitionFile(); if(spec) { @@ -1985,23 +1985,6 @@ MingwModuleHandler::GeneratePreconditionDependencies () fprintf ( fMakefile, "\n" ); } -SpecFileType -MingwModuleHandler::IsSpecDefinitionFile () const -{ - if(!module.importLibrary) - return None; - - std::string ext = GetExtension ( *module.importLibrary->source ); - - if ( ext == ".spec" ) - return Spec; - - if ( ext == ".pspec" ) - return PSpec; - - return None; -} - /* caller needs to delete the returned object */ const FileLocation* MingwModuleHandler::GetDefinitionFilename () const @@ -2009,7 +1992,7 @@ MingwModuleHandler::GetDefinitionFilename () const if ( module.importLibrary == NULL ) return NULL; - if ( IsSpecDefinitionFile () ) + if ( module.IsSpecDefinitionFile () ) { return new FileLocation ( IntermediateDirectory, module.importLibrary->source->relative_path, diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index b0687177d9a..797f075812a 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -32,13 +32,6 @@ PrefixFilename ( const std::string& filename, const std::string& prefix ); -enum SpecFileType -{ - None, - Spec = 1, - PSpec = 2 -}; - class MingwModuleHandler { public: diff --git a/reactos/tools/rbuild/backend/msvc/msvc.cpp b/reactos/tools/rbuild/backend/msvc/msvc.cpp index 90aa37c0ddc..8991147a61a 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.cpp +++ b/reactos/tools/rbuild/backend/msvc/msvc.cpp @@ -83,7 +83,6 @@ MSVCBackend::MSVCBackend(Project &project, void MSVCBackend::Process() { - // TODO FIXME wine hack? bool only_msvc_headers = false; while ( m_configurations.size () > 0 ) @@ -95,14 +94,14 @@ void MSVCBackend::Process() m_configurations.push_back ( new MSVCConfiguration( Debug )); m_configurations.push_back ( new MSVCConfiguration( Release )); - m_configurations.push_back ( new MSVCConfiguration( Speed )); +// m_configurations.push_back ( new MSVCConfiguration( Speed )); m_configurations.push_back ( new MSVCConfiguration( RosBuild )); if (!only_msvc_headers) { m_configurations.push_back ( new MSVCConfiguration( Debug, ReactOSHeaders )); m_configurations.push_back ( new MSVCConfiguration( Release, ReactOSHeaders )); - m_configurations.push_back ( new MSVCConfiguration( Speed, ReactOSHeaders )); +// m_configurations.push_back ( new MSVCConfiguration( Speed, ReactOSHeaders )); } if ( configuration.CleanAsYouGo ) { @@ -118,6 +117,22 @@ void MSVCBackend::Process() filename_sln += "_auto.sln"; printf ( "Creating MSVC workspace: %s\n", filename_sln.c_str() ); + //Write a property page for each configuration + for ( size_t icfg = 0; icfg < m_configurations.size(); icfg++ ) + { + MSVCConfiguration* cfg = m_configurations[icfg]; + + //RosBuild doesn't need a property page + if(cfg->optimization == RosBuild) + continue; + + string filename_props( cfg->name ); + filename_props += ".vsprops"; + //Write the propery pages files + PropsMaker propsMaker( configuration, &ProjectNode, filename_props, cfg ); + propsMaker._generate_props( _get_solution_version(), _get_studio_version() ); + } + // Write out the project files ProcessModules(); @@ -376,7 +391,7 @@ MSVCBackend::_get_object_files ( const Module& module, vector& out) cons void MSVCBackend::_get_def_files ( const Module& module, vector& out) const { - if (module.HasImportLibrary ()) + if (module.HasImportLibrary()) { #if 0 string modulename = module.GetBasePath (); diff --git a/reactos/tools/rbuild/backend/msvc/msvc.h b/reactos/tools/rbuild/backend/msvc/msvc.h index fde4b81657e..4be80c64c99 100644 --- a/reactos/tools/rbuild/backend/msvc/msvc.h +++ b/reactos/tools/rbuild/backend/msvc/msvc.h @@ -179,6 +179,7 @@ class VCProjMaker : public ProjMaker private: void _generate_standard_configuration( const Module& module, const MSVCConfiguration& cfg, BinaryType binaryType ); void _generate_makefile_configuration( const Module& module, const MSVCConfiguration& cfg ); + std::string _get_file_path( FileLocation* file, std::string relative_path); }; class VCXProjMaker : public ProjMaker @@ -222,4 +223,34 @@ class SlnMaker void _generate_sln_configurations ( std::string vcproj_guid ); }; +class PropsMaker +{ + public: + PropsMaker ( Configuration& buildConfig, + Project* ProjectNode, + std::string filename_props, + MSVCConfiguration* msvc_configs); + + ~PropsMaker (); + + void _generate_props ( std::string solution_version, std::string studio_version ); + + private: + Configuration m_configuration; + Project* m_ProjectNode; + FILE* OUT; + MSVCConfiguration* m_msvc_config; + bool debug; + bool release; + bool speed; + bool use_ros_headers; + + void _generate_header(); + void _generate_tools_defaults(); + void _generate_macro(std::string Name, std::string Value, bool EvairomentVariable); + void _generate_global_includes(); + void _generate_global_definitions(); + void _generate_footer(); + +}; #endif // __MSVC_H__ diff --git a/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules b/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules new file mode 100644 index 00000000000..d61a5247496 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/s_as_mscpp.rules @@ -0,0 +1,44 @@ + + + + + + + + + + + + + diff --git a/reactos/tools/rbuild/backend/msvc/spec.rules b/reactos/tools/rbuild/backend/msvc/spec.rules new file mode 100644 index 00000000000..7aa12cb2598 --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/spec.rules @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + diff --git a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp index 73b32c5effe..29a0c78fe3f 100644 --- a/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp +++ b/reactos/tools/rbuild/backend/msvc/vcprojmaker.cpp @@ -80,6 +80,28 @@ VCProjMaker::~VCProjMaker() fclose ( OUT ); } +std::string +VCProjMaker::_get_file_path( FileLocation* file, std::string relative_path) +{ + if (file->directory == SourceDirectory) + { + // We want the full path here for directory support later on + return Path::RelativeFromDirectory (file->relative_path, relative_path ); + } + else if(file->directory == IntermediateDirectory) + { + return std::string("$(obj)\\") + file->relative_path; + } + else if(file->directory == OutputDirectory) + { + return std::string("$(out)\\") + file->relative_path; + } + + return std::string(""); +} + + + void VCProjMaker::_generate_proj_file ( const Module& module ) { @@ -91,7 +113,6 @@ VCProjMaker::_generate_proj_file ( const Module& module ) // make sure the containers are empty header_files.clear(); includes.clear(); - includes_ros.clear(); libraries.clear(); common_defines.clear(); @@ -110,21 +131,8 @@ VCProjMaker::_generate_proj_file ( const Module& module ) printf ( "Creating MSVC project: '%s'\n", vcproj_file.c_str() ); string path_basedir = module.GetPathToBaseDir (); - string intenv = Environment::GetIntermediatePath (); - string outenv = Environment::GetOutputPath (); - string outdir; - string intdir; string vcdir; - if ( intenv == "obj-i386" ) - intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ - else - intdir = intenv; - - if ( outenv == "output-i386" ) - outdir = path_basedir + "output-i386"; - else - outdir = outenv; if ( configuration.UseVSVersionInPath ) { @@ -135,93 +143,65 @@ VCProjMaker::_generate_proj_file ( const Module& module ) vector source_files, resource_files; vector ifs_list; - ifs_list.push_back ( &module.project.non_if_data ); - ifs_list.push_back ( &module.non_if_data ); - while ( ifs_list.size() ) + const IfableData& data = module.non_if_data/**ifs_list.back()*/; + const vector& files = data.files; + for ( i = 0; i < files.size(); i++ ) { - const IfableData& data = *ifs_list.back(); - ifs_list.pop_back(); - const vector& files = data.files; - for ( i = 0; i < files.size(); i++ ) - { - if (files[i]->file.directory != SourceDirectory) - continue; + string path = _get_file_path(&files[i]->file, module.output->relative_path); + string file = path + std::string("\\") + files[i]->file.name; - // We want the full path here for directory support later on - string path = Path::RelativeFromDirectory ( - files[i]->file.relative_path, - module.output->relative_path ); - string file = path + std::string("\\") + files[i]->file.name; - - if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) - resource_files.push_back ( file ); - else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) - header_files.push_back ( file ); - else - source_files.push_back ( file ); - } - const vector& incs = data.includes; - for ( i = 0; i < incs.size(); i++ ) - { - string path = Path::RelativeFromDirectory ( - incs[i]->directory->relative_path, - module.output->relative_path ); - if ( module.type != RpcServer && module.type != RpcClient ) - { - if ( path.find ("/include/reactos/idl") != string::npos) - { - include_idl = true; - continue; - } - } - // switch between general headers and ros headers - if ( !strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\ddk", 11 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\GL", 10 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\psdk", 12 ) || - !strncmp(incs[i]->directory->relative_path.c_str(), "include\\reactos\\wine", 20 ) ) - { - if (strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 )) - // not crt include - includes_ros.push_back ( path ); - } - else - { - includes.push_back ( path ); - } - } - const vector& libs = data.libraries; - for ( i = 0; i < libs.size(); i++ ) - { - string libpath = outdir + "\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\---\\" + libs[i]->name + ".lib"; - libraries.push_back ( libpath ); - } - const vector& defs = data.defines; - for ( i = 0; i < defs.size(); i++ ) - { - if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) - continue; - - if ( defs[i]->value[0] ) - common_defines.insert( defs[i]->name + "=" + defs[i]->value ); - else - common_defines.insert( defs[i]->name ); - } - for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) - { - Property& prop = *p->second; - if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) - baseaddr = prop.value; - } + if ( !stricmp ( Right(file,3).c_str(), ".rc" ) ) + resource_files.push_back ( file ); + else if ( !stricmp ( Right(file,2).c_str(), ".h" ) ) + header_files.push_back ( file ); + else + source_files.push_back ( file ); } - /* include intermediate path for reactos.rc */ - string version = intdir + "\\include"; - includes.push_back (version); - version += "\\reactos"; - includes.push_back (version); + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + string path = _get_file_path(incs[i]->directory, module.output->relative_path); - string include_string; + if ( module.type != RpcServer && module.type != RpcClient ) + { + if ( path.find ("/include/reactos/idl") != string::npos) + { + include_idl = true; + continue; + } + } + includes.push_back ( path ); + } + const vector& libs = data.libraries; + for ( i = 0; i < libs.size(); i++ ) + { + string libpath = "$(out)\\" + libs[i]->importedModule->output->relative_path + "\\" + _get_vc_dir() + "\\$(ConfigurationName)\\" + libs[i]->name + ".lib"; + libraries.push_back ( libpath ); + } + const vector& defs = data.defines; + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if ( defs[i]->value[0] ) + common_defines.insert( defs[i]->name + "=" + defs[i]->value ); + else + common_defines.insert( defs[i]->name ); + } + for ( std::map::const_iterator p = data.properties.begin(); p != data.properties.end(); ++ p ) + { + Property& prop = *p->second; + if ( strstr ( module.baseaddress.c_str(), prop.name.c_str() ) ) + baseaddr = prop.value; + } + + if(module.IsSpecDefinitionFile()) + { + std::string path = _get_file_path(module.importLibrary->source, module.output->relative_path); + source_files.push_back ( path + std::string("\\") + module.importLibrary->source->name ); + } fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\r\n" ); fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); + fprintf ( OUT, "\t\t\r\n" ); + fprintf ( OUT, "\t\r\n" ); + // Set the binary type string module_type = GetExtension(*module.output); BinaryType binaryType; @@ -335,21 +324,8 @@ VCProjMaker::_generate_proj_file ( const Module& module ) { const MSVCConfiguration& config = *m_configurations[iconfig]; - if (( isrcfile == 0 ) && ( module.pch != NULL )) - { - /* little hack to speed up PCH */ - fprintf ( OUT, "%s\t\r\n" ); - fprintf ( OUT, "%s\t\t\r\n", indent_tab.c_str() ); - fprintf ( OUT, "%s\t\r\n", indent_tab.c_str() ); - } - //if (configuration.VSProjectVersion < "8.00") { - if ((source_file.find(".idl") != string::npos) || ((source_file.find(".asm") != string::npos || tolower(source_file.at(source_file.size() - 1)) == 's'))) + if ((source_file.find(".idl") != string::npos) || ((source_file.find(".asm") != string::npos))) { fprintf ( OUT, "%s\t\r\n", indent_tab.c_str() ); } - else if ((tolower(source_file.at(source_file.size() - 1)) == 's')) - { - fprintf ( OUT, "%s\t\t\tName=\"VCCustomBuildTool\"\r\n", indent_tab.c_str() ); - fprintf ( OUT, "%s\t\t\tCommandLine=\"cl /E "$(InputPath)" %s /D__ASM__ | as -o "$(OutDir)\\$(InputName).obj"\"\r\n", indent_tab.c_str(), include_string.c_str() ); - fprintf ( OUT, "%s\t\t\tOutputs=\"$(OutDir)\\$(InputName).obj\"/>\r\n", indent_tab.c_str() ); - } fprintf ( OUT, "%s\t\r\n", indent_tab.c_str() ); } //} @@ -452,24 +422,19 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, BinaryType binaryType ) { string path_basedir = module.GetPathToBaseDir (); - string intenv = Environment::GetIntermediatePath (); - string outenv = Environment::GetOutputPath (); - string outdir; - string intdir; string vcdir; - bool debug = ( cfg.optimization == Debug ); - bool release = ( cfg.optimization == Release ); - bool speed = ( cfg.optimization == Speed ); - bool include_idl = false; - string include_string; size_t i; string intermediatedir = ""; string importLib; - // don't do the work m_configurations.size() times - if (module.importLibrary != NULL) + + if(module.IsSpecDefinitionFile()) + { + importLib = "$(IntDir)\\$(ProjectName).def"; + } + else if (module.importLibrary != NULL) { intermediatedir = module.output->relative_path + vcdir; importLib = _strip_gcc_deffile(module.importLibrary->source->name, module.importLibrary->source->relative_path, intermediatedir); @@ -491,17 +456,6 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, else CfgType = ConfigUnknown; - - if ( intenv == "obj-i386" ) - intdir = path_basedir + "obj-i386"; /* append relative dir from project dir */ - else - intdir = intenv; - - if ( outenv == "output-i386" ) - outdir = path_basedir + "output-i386"; - else - outdir = outenv; - if ( configuration.UseVSVersionInPath ) { vcdir = DEF_SSEP + _get_vc_dir(); @@ -510,30 +464,68 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, fprintf ( OUT, "\t\trelative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); - fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\\%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str (), cfg.name.c_str() ); - } - else - { - fprintf ( OUT, "\t\t\tOutputDirectory=\"%s\\%s%s\"\r\n", outdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); - fprintf ( OUT, "\t\t\tIntermediateDirectory=\"%s\\%s%s\"\r\n", intdir.c_str (), module.output->relative_path.c_str (), vcdir.c_str () ); - } + if ( configuration.UseConfigurationInPath ) + { + fprintf ( OUT, "\t\t\tOutputDirectory=\"$(out)\\%s%s\\$(ConfigurationName)\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"$(obj)\\%s%s\\$(ConfigurationName)\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); + } + else + { + fprintf ( OUT, "\t\t\tOutputDirectory=\"$(out)\\%s%s\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); + fprintf ( OUT, "\t\t\tIntermediateDirectory=\"$(obj)\\%s%s\"\r\n", module.output->relative_path.c_str (), vcdir.c_str () ); + } fprintf ( OUT, "\t\t\tConfigurationType=\"%d\"\r\n", CfgType ); + + fprintf ( OUT, "\t\t\tInheritedPropertySheets=\"%s%s.vsprops\"\r\n", path_basedir.c_str (), cfg.name.c_str ()); fprintf ( OUT, "\t\t\tCharacterSet=\"2\"\r\n" ); fprintf ( OUT, "\t\t\t>\r\n" ); - fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\tOptimization=\"%d\"\r\n", release ? 2 : 0 ); + fprintf ( OUT, "\t\t\t\r\n" ); - fprintf ( OUT, "\t\t\t\tAdditionalIncludeDirectories=\"" ); - bool multiple_includes = false; - fprintf ( OUT, "./;" ); - for ( i = 0; i < includes.size(); i++ ) + + fprintf ( OUT, "\t\t\t 0 ) - fprintf ( OUT, ";" ); + fprintf ( OUT, "\t\t\t\tPreprocessorDefinitions=\"" ); + for ( StringSet::iterator it1=defines.begin(); it1!=defines.end(); it1++ ) + { + string unescaped = *it1; + fprintf ( OUT, "%s ; ", _replace_str(unescaped, "\"","").c_str() ); + } + fprintf ( OUT, "\"\r\n" ); - string unescaped = *it1; - fprintf ( OUT, "%s", _replace_str(unescaped, "\"","").c_str() ); - } - fprintf ( OUT, "\"\r\n" ); - fprintf ( OUT, "\t\t\t\tForcedIncludeFiles=\"%s\"\r\n", "warning.h"); - fprintf ( OUT, "\t\t\t\tMinimalRebuild=\"%s\"\r\n", speed ? "TRUE" : "FALSE" ); - fprintf ( OUT, "\t\t\t\tBasicRuntimeChecks=\"0\"\r\n" ); - fprintf ( OUT, "\t\t\t\tRuntimeLibrary=\"%d\"\r\n", debug ? 3 : 2 ); // 3=/MDd 2=/MD - fprintf ( OUT, "\t\t\t\tBufferSecurityCheck=\"FALSE\"\r\n" ); - fprintf ( OUT, "\t\t\t\tEnableFunctionLevelLinking=\"FALSE\"\r\n" ); + //disable precompiled headers for now +#if 0 + if ( module.pch != NULL ) + { + fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); + string pch_path = Path::RelativeFromDirectory ( + module.pch->file->name, + module.output->relative_path ); + string::size_type pos = pch_path.find_last_of ("/"); + if ( pos != string::npos ) + pch_path.erase(0, pos+1); + fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() ); - if ( module.pch != NULL ) - { - fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"2\"\r\n" ); - string pch_path = Path::RelativeFromDirectory ( - module.pch->file->name, - module.output->relative_path ); - string::size_type pos = pch_path.find_last_of ("/"); - if ( pos != string::npos ) - pch_path.erase(0, pos+1); - fprintf ( OUT, "\t\t\t\tPrecompiledHeaderThrough=\"%s\"\r\n", pch_path.c_str() ); + // Only include from the same module + pos = pch_path.find("../"); + if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end()) + header_files.push_back(pch_path); + } +#endif - // Only include from the same module - pos = pch_path.find("../"); - if (pos == string::npos && std::find(header_files.begin(), header_files.end(), pch_path) == header_files.end()) - header_files.push_back(pch_path); - } - else - { - fprintf ( OUT, "\t\t\t\tUsePrecompiledHeader=\"0\"\r\n" ); - } + if ( module.cplusplus ) + fprintf ( OUT, "\t\t\t\tCompileAs=\"2\"\r\n" ); - fprintf ( OUT, "\t\t\t\tWholeProgramOptimization=\"%s\"\r\n", release ? "FALSE" : "FALSE"); - if ( release ) - { - fprintf ( OUT, "\t\t\t\tFavorSizeOrSpeed=\"1\"\r\n" ); - fprintf ( OUT, "\t\t\t\tStringPooling=\"true\"\r\n" ); - } - - fprintf ( OUT, "\t\t\t\tWarningLevel=\"%s\"\r\n", speed ? "0" : "3" ); - fprintf ( OUT, "\t\t\t\tDetect64BitPortabilityProblems=\"%s\"\r\n", "FALSE"); - if ( !module.cplusplus ) - fprintf ( OUT, "\t\t\t\tCompileAs=\"1\"\r\n" ); - - if ( module.type == Win32CUI || module.type == Win32GUI ) - { - fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 0 ); // 0=__cdecl - } - else - { - fprintf ( OUT, "\t\t\t\tCallingConvention=\"%d\"\r\n", 2 ); // 2=__stdcall - } - - fprintf ( OUT, "\t\t\t\tDebugInformationFormat=\"%s\"/>\r\n", speed ? "0" : release ? "3": "4"); // 3=/Zi 4=ZI + fprintf ( OUT, "\t\t\t/>\r\n"); fprintf ( OUT, "\t\t\t\r\n" ); - if ( binaryType == Lib ) + if ( binaryType != Lib ) + { + fprintf ( OUT, "\t\t\t 0) - fprintf ( OUT, ";" ); - } - // Add conventional libraries dirs for (i = 0; i < libraries.size (); i++) { if ( i > 0 ) fprintf ( OUT, ";" ); - string libpath = libraries[i].c_str(); - libpath.replace (libpath.find("---"), 3, cfg.name); - libpath = libpath.substr (0, libpath.find_last_of ("\\") ); - fprintf ( OUT, "%s", libpath.c_str() ); - } + string libpath = libraries[i].c_str(); + libpath = libpath.substr (0, libpath.find_last_of ("\\") ); + fprintf ( OUT, "%s", libpath.c_str() ); + } fprintf ( OUT, "\"\r\n" ); - fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() ); - fprintf ( OUT, "\t\t\t\tLinkIncremental=\"%d\"\r\n", debug ? 2 : 1 ); - fprintf ( OUT, "\t\t\t\tGenerateDebugInformation=\"%s\"\r\n", speed ? "FALSE" : "TRUE" ); - fprintf ( OUT, "\t\t\t\tLinkTimeCodeGeneration=\"%d\"\r\n", release? 0 : 0); // whole program optimization - - if ( debug ) - fprintf ( OUT, "\t\t\t\tProgramDatabaseFile=\"$(OutDir)/%s.pdb\"\r\n", module.name.c_str() ); - + fprintf ( OUT, "\t\t\t\tOutputFile=\"$(OutDir)/%s%s\"\r\n", module.name.c_str(), module_type.c_str() ); if ( binaryType == Sys ) { if (module.GetEntryPoint() == "0") @@ -833,6 +729,8 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, } fprintf ( OUT, "\t\t\t\tTargetMachine=\"%d\"/>\r\n", 1 ); } + fprintf ( OUT, "\t\t\t/>\r\n" ); + } fprintf ( OUT, "\t\t\t\r\n " ); + } + + fprintf ( OUT, "\"/>\r\n " ); fprintf ( OUT, "\t\t\t\r\n" ); @@ -883,6 +772,8 @@ void VCProjMaker::_generate_standard_configuration( const Module& module, fprintf ( OUT, "\t\t\t\tName=\"VCWebDeploymentTool\"/>\r\n" ); fprintf ( OUT, "\t\t\r\n" ); } + fprintf ( OUT, "\t\t\r\n" ); +} void diff --git a/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp b/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp new file mode 100644 index 00000000000..bd0733919df --- /dev/null +++ b/reactos/tools/rbuild/backend/msvc/vspropsmaker.cpp @@ -0,0 +1,274 @@ +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include +#include +#include +#include +#include +#include + +#include + +#include "msvc.h" + +using std::string; +using std::vector; +using std::set; + +typedef set StringSet; + +#ifdef OUT +#undef OUT +#endif//OUT + +PropsMaker::PropsMaker ( Configuration& buildConfig, + Project* ProjectNode, + std::string filename_props, + MSVCConfiguration* msvc_configs) +{ + m_configuration = buildConfig; + m_ProjectNode = ProjectNode; + + m_msvc_config = msvc_configs; + + debug = ( m_msvc_config->optimization == Debug ); + release = ( m_msvc_config->optimization == Release ); + speed = ( m_msvc_config->optimization == Speed ); + use_ros_headers = (m_msvc_config->headers == ReactOSHeaders); + + OUT = fopen ( filename_props.c_str(), "wb" ); + + if ( !OUT ) + { + printf ( "Could not create file '%s'.\n", filename_props.c_str() ); + } +} + +PropsMaker::~PropsMaker ( ) +{ + fclose ( OUT ); +} + +void +PropsMaker::_generate_header() +{ + fprintf ( OUT, "\r\n" ); + fprintf ( OUT, "\r\n", m_msvc_config->name.c_str() ); +} + +void +PropsMaker::_generate_tools_defaults() +{ + fprintf ( OUT, "\t\r\n"); + + //Linker + fprintf ( OUT, "\t\r\n"); + + //Librarian + fprintf ( OUT, "\t\r\n"); + + //Resource compiler + fprintf ( OUT, "\t\t\t\r\n"); +} + +void +PropsMaker::_generate_macro(std::string Name, + std::string Value, + bool EvairomentVariable) +{ + fprintf ( OUT, "\t\r\n"); +} + +void +PropsMaker::_generate_global_includes() +{ + //Generate global includes + //they will be used by the c compiler, the resource compiler + //and the preprocessor for .s and .pspec files + + fprintf ( OUT, "\tnon_if_data; + //const vector& files = data.files; + size_t i; + const vector& incs = data.includes; + for ( i = 0; i < incs.size(); i++ ) + { + if ((strncmp(incs[i]->directory->relative_path.c_str(), "include\\crt", 11 ) || + strncmp(incs[i]->directory->relative_path.c_str(), "include\\ddk", 11 ) || + strncmp(incs[i]->directory->relative_path.c_str(), "include\\GL", 10 ) || + strncmp(incs[i]->directory->relative_path.c_str(), "include\\psdk", 12 ) || + strncmp(incs[i]->directory->relative_path.c_str(), "include\\reactos\\wine", 20 )) && + ! use_ros_headers) + { + continue; + } + + if(incs[i]->directory->directory == SourceDirectory) + fprintf ( OUT, ""$(src)\\"); + else if (incs[i]->directory->directory == IntermediateDirectory) + fprintf ( OUT, ""$(obj)\\"); + else if (incs[i]->directory->directory == OutputDirectory) + fprintf ( OUT, ""$(out)\\"); + else + continue; + + fprintf ( OUT, incs[i]->directory->relative_path.c_str()); + fprintf ( OUT, "" ; "); + } + + fprintf ( OUT, ""$(obj)\\include" ; "); + fprintf ( OUT, ""$(obj)\\include\\reactos" ; "); + + if ( !use_ros_headers ) + { + // Add WDK or PSDK paths, if user provides them + if (getenv ( "BASEDIR" ) != NULL) + { + string WdkBase = getenv ( "BASEDIR" ); + fprintf ( OUT, ""%s\\inc\\api" ; ", WdkBase.c_str()); + fprintf ( OUT, ""%s\\inc\\crt" ; ", WdkBase.c_str()); + fprintf ( OUT, ""%s\\inc\\ddk" ; ", WdkBase.c_str()); + } + } + fprintf ( OUT, "\"\r\n"); + fprintf ( OUT, "\t\tPerformEnvironmentSet=\"true\"\r\n"); + fprintf( OUT, "\t/>\r\n"); +} + +void +PropsMaker::_generate_global_definitions() +{ + + string global_defines = ""; + + fprintf ( OUT, "\tnon_if_data; + const vector& defs = data.defines; + size_t i; + + for ( i = 0; i < defs.size(); i++ ) + { + if ( defs[i]->backend != "" && defs[i]->backend != "msvc" ) + continue; + + if ( defs[i]->value[0] ) + fprintf ( OUT, "%s=%s",defs[i]->name.c_str(), defs[i]->value.c_str()); + else + fprintf ( OUT, defs[i]->name.c_str()); + fprintf ( OUT, " ; "); + } + + fprintf ( OUT, "\"\r\n"); + fprintf ( OUT, "\t\tPerformEnvironmentSet=\"true\"\r\n"); + fprintf( OUT, "\t/>\r\n"); +} + +void +PropsMaker::_generate_footer() +{ + fprintf ( OUT, "\r\n"); +} + + +void +PropsMaker::_generate_props ( std::string solution_version, + std::string studio_version ) +{ + _generate_header(); + _generate_tools_defaults(); + + string srcdir = Environment::GetSourcePath(); + string intdir = Environment::GetIntermediatePath (); + string outdir = Environment::GetOutputPath (); + string rosbedir = Environment::GetVariable("_ROSBE_BASEDIR"); + + if ( intdir == "obj-i386" ) + intdir = srcdir + "\\obj-i386"; /* append relative dir from project dir */ + + if ( outdir == "output-i386" ) + outdir = srcdir + "\\output-i386"; + + //Generate global macros + _generate_macro("src", srcdir, true); + _generate_macro("out", outdir, true); + _generate_macro("obj", intdir, true); + _generate_macro("Tools", "$(out)\\tools", true); + _generate_macro("RosBE", rosbedir, true); + + _generate_global_includes(); + _generate_global_definitions(); + _generate_footer(); +} diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index 5e4071d65dd..9d3d3351d6a 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -1436,6 +1436,24 @@ Module::GetDllName () const throw new InvalidOperationException ( __FILE__, __LINE__, "Module %s has no dllname." ); } +SpecFileType +Module::IsSpecDefinitionFile () const +{ + if(!importLibrary) + return None; + + std::string ext = GetExtension ( *importLibrary->source ); + + if ( ext == ".spec" ) + return Spec; + + if ( ext == ".pspec" ) + return PSpec; + + return None; +} + + File::File ( DirectoryLocation directory, const string& relative_path, const string& name, diff --git a/reactos/tools/rbuild/project.cpp b/reactos/tools/rbuild/project.cpp index 4a2a0313bdf..5e194a5e45a 100644 --- a/reactos/tools/rbuild/project.cpp +++ b/reactos/tools/rbuild/project.cpp @@ -63,6 +63,14 @@ Environment::GetIntermediatePath () } /* static */ string +Environment::GetSourcePath () +{ + char temp[_MAX_PATH]; + getcwd(temp, _MAX_PATH); + return string(temp); +} + +string Environment::GetOutputPath () { string defaultOutput = diff --git a/reactos/tools/rbuild/rbuild.cpp b/reactos/tools/rbuild/rbuild.cpp index 1119f22ca0f..dc098a819c4 100644 --- a/reactos/tools/rbuild/rbuild.cpp +++ b/reactos/tools/rbuild/rbuild.cpp @@ -134,6 +134,11 @@ ParseVCProjectSwitch ( if (configuration.VSProjectVersion.length() == 3) //7.1 configuration.VSProjectVersion.append("0"); + //We should set this here because in the end we will use + //msc sompiler so we need to parse msc specidic + //definitions and includes + configuration.Compiler = MicrosoftC; + break; case 'c': configuration.VSConfigurationType = string (&switchStart[3]); diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index 239c03ed556..9ecb9520e82 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -167,6 +167,13 @@ enum LinkerSet MicrosoftLink }; +enum SpecFileType +{ + None, + Spec = 1, + PSpec = 2 +}; + class Configuration { public: @@ -197,6 +204,7 @@ public: static std::string GetArch (); static std::string GetIntermediatePath (); static std::string GetOutputPath (); + static std::string GetSourcePath (); static std::string GetCdOutputPath (); static std::string GetInstallPath (); static std::string GetAutomakeFile ( const std::string& defaultFile ); @@ -427,6 +435,7 @@ public: void InvokeModule () const; void ProcessXML (); std::string GetDllName() const; + SpecFileType IsSpecDefinitionFile () const; private: void SetImportLibrary ( ImportLibrary* importLibrary ); void SetDelayImportLibrary ( ImportLibrary* importLibrary ); diff --git a/reactos/tools/rbuild/rbuild.mak b/reactos/tools/rbuild/rbuild.mak index f64e21d2335..1a3138f7d14 100644 --- a/reactos/tools/rbuild/rbuild.mak +++ b/reactos/tools/rbuild/rbuild.mak @@ -209,6 +209,7 @@ RBUILD_BACKEND_MSVC_BASE_SOURCES = $(addprefix $(RBUILD_MSVC_BASE_), \ slnmaker.cpp \ vcprojmaker.cpp \ vcxprojmaker.cpp \ + vspropsmaker.cpp \ ) RBUILD_BACKEND_SOURCES = \ @@ -496,7 +497,11 @@ $(RBUILD_MSVC_INT_)msvc.o: $(RBUILD_MSVC_BASE_)msvc.cpp $(RBUILD_HEADERS) | $(RB $(RBUILD_MSVC_INT_)projmaker.o: $(RBUILD_MSVC_BASE_)projmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ - + +$(RBUILD_MSVC_INT_)vspropsmaker.o: $(RBUILD_MSVC_BASE_)vspropsmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) + $(ECHO_HOSTCC) + ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ + $(RBUILD_MSVC_INT_)slnmaker.o: $(RBUILD_MSVC_BASE_)slnmaker.cpp $(RBUILD_HEADERS) | $(RBUILD_MSVC_INT) $(ECHO_HOSTCC) ${host_gpp} $(RBUILD_HOST_CXXFLAGS) -c $< -o $@ diff --git a/reactos/tools/rbuild/rbuild.vcproj b/reactos/tools/rbuild/rbuild.vcproj index b207f17118a..763850a1804 100644 --- a/reactos/tools/rbuild/rbuild.vcproj +++ b/reactos/tools/rbuild/rbuild.vcproj @@ -1,7 +1,7 @@ + +