From d3a30bf22da182c9875954fe617cd1829795d833 Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Sat, 15 Jan 2005 13:52:36 +0000 Subject: [PATCH] * LinkerFlag tag support * Build addsys, libwine.a, user32.dll, advapi32.dll, gdi32.dll, msvcrt.dll, and welcome.exe svn path=/branches/xmlbuildsystem/; revision=13055 --- reactos/ReactOS.xml | 8 +- reactos/iface/addsys/addsys.xml | 14 + reactos/iface/addsys/genw32k.c | 24 +- .../iface/native/{module.xml => genntdll.xml} | 0 reactos/lib/advapi32/advapi32.xml | 47 ++ reactos/lib/directory.xml | 15 + reactos/lib/gdi32/gdi32.xml | 35 ++ reactos/lib/libwine/libwine.xml | 5 + reactos/lib/msvcrt/misc/dllmain.c | 4 +- reactos/lib/msvcrt/misc/environ.c | 8 +- reactos/lib/msvcrt/msvcrt.xml | 443 ++++++++++++++++++ reactos/lib/user32/user32.xml | 74 +++ reactos/subsys/directory.xml | 3 + reactos/subsys/system/directory.xml | 3 + reactos/subsys/system/welcome/welcome.xml | 9 + reactos/tools/rbuild/backend/mingw/mingw.cpp | 15 + reactos/tools/rbuild/backend/mingw/mingw.h | 1 + .../rbuild/backend/mingw/modulehandler.cpp | 193 ++++++-- .../rbuild/backend/mingw/modulehandler.h | 20 + reactos/tools/rbuild/include.cpp | 3 +- reactos/tools/rbuild/linkerflag.cpp | 47 ++ reactos/tools/rbuild/makefile | 2 + reactos/tools/rbuild/module.cpp | 12 + reactos/tools/rbuild/project.cpp | 13 +- reactos/tools/rbuild/rbuild.h | 28 +- reactos/tools/rbuild/test.h | 6 + reactos/tools/rbuild/tests/alltests.cpp | 1 + .../tools/rbuild/tests/data/linkerflag.xml | 7 + reactos/tools/rbuild/tests/linkerflagtest.cpp | 19 + 29 files changed, 1008 insertions(+), 51 deletions(-) create mode 100644 reactos/iface/addsys/addsys.xml rename reactos/iface/native/{module.xml => genntdll.xml} (100%) create mode 100644 reactos/lib/advapi32/advapi32.xml create mode 100644 reactos/lib/gdi32/gdi32.xml create mode 100644 reactos/lib/libwine/libwine.xml create mode 100644 reactos/lib/msvcrt/msvcrt.xml create mode 100644 reactos/lib/user32/user32.xml create mode 100644 reactos/subsys/directory.xml create mode 100644 reactos/subsys/system/directory.xml create mode 100644 reactos/subsys/system/welcome/welcome.xml create mode 100644 reactos/tools/rbuild/linkerflag.cpp create mode 100644 reactos/tools/rbuild/tests/data/linkerflag.xml create mode 100644 reactos/tools/rbuild/tests/linkerflagtest.cpp diff --git a/reactos/ReactOS.xml b/reactos/ReactOS.xml index e9f4e3bd7ea..672d03fd17a 100644 --- a/reactos/ReactOS.xml +++ b/reactos/ReactOS.xml @@ -30,8 +30,11 @@ + + + - + @@ -40,4 +43,7 @@ + + + diff --git a/reactos/iface/addsys/addsys.xml b/reactos/iface/addsys/addsys.xml new file mode 100644 index 00000000000..e46f6d23ead --- /dev/null +++ b/reactos/iface/addsys/addsys.xml @@ -0,0 +1,14 @@ + + . + genw32k.c + + + w32ksvc.db + + + ../../subsys/win32k/main/svctab.c + ../../lib/gdi32/misc/win32k.c + ../../lib/user32/misc/win32k.c + + + diff --git a/reactos/iface/addsys/genw32k.c b/reactos/iface/addsys/genw32k.c index 7e5b5bd9612..4b1838fa582 100644 --- a/reactos/iface/addsys/genw32k.c +++ b/reactos/iface/addsys/genw32k.c @@ -299,11 +299,11 @@ process( void usage(char * argv0) { printf("Usage: %s w32ksvc.db w32k.lst ssdt.h win32k.c win32k.c\n" - " w32ksvc.db input file(system calls database)\n" " w32k.lst system functions database\n" " ssdt.h WIN32K service table\n" " win32k.c GDI32 stubs\n" - " win32k.c USER32 stubs\n", + " win32k.c USER32 stubs\n" + " w32ksvc.db input file(system calls database)\n", argv0 ); } @@ -322,34 +322,34 @@ int main(int argc, char* argv[]) return(1); } - in = fopen(argv[1],"rb"); - if (in == NULL) - { - perror("Failed to open input file (system calls database)"); - return(1); - } - - out1 = fopen(argv[2],"wb"); + out1 = fopen(argv[1],"wb"); if (out1 == NULL) { perror("Failed to open output file (WIN32K service table)"); return(1); } - out2 = fopen(argv[3],"wb"); + out2 = fopen(argv[2],"wb"); if (out2 == NULL) { perror("Failed to open output file (GDI32 stubs)"); return(1); } - out3 = fopen(argv[4],"wb"); + out3 = fopen(argv[3],"wb"); if (out3 == NULL) { perror("Failed to open output file (USER32 stubs)"); return(1); } + in = fopen(argv[4],"rb"); + if (in == NULL) + { + perror("Failed to open input file (system calls database)"); + return(1); + } + ret = process(in,out2,out3); rewind(in); ret = makeSystemServiceTable(in, out1); diff --git a/reactos/iface/native/module.xml b/reactos/iface/native/genntdll.xml similarity index 100% rename from reactos/iface/native/module.xml rename to reactos/iface/native/genntdll.xml diff --git a/reactos/lib/advapi32/advapi32.xml b/reactos/lib/advapi32/advapi32.xml new file mode 100644 index 00000000000..5e376c8e461 --- /dev/null +++ b/reactos/lib/advapi32/advapi32.xml @@ -0,0 +1,47 @@ + + + . + + 0x600 + 0x0500 + 0x0501 + ntdll + kernel32 + + crypt.c + crypt_des.c + crypt_lmhash.c + crypt_md4.c + crypt_md5.c + crypt_sha.c + + + dllmain.c + hwprofiles.c + logon.c + shutdown.c + sysfunc.c + + + reg.c + + + ac.c + audit.c + lsa.c + misc.c + sec.c + sid.c + trustee.c + + + eventlog.c + scm.c + sctrl.c + undoc.c + + + privilege.c + token.c + + diff --git a/reactos/lib/directory.xml b/reactos/lib/directory.xml index c61a46c03c7..38bbfdd125e 100644 --- a/reactos/lib/directory.xml +++ b/reactos/lib/directory.xml @@ -1,9 +1,21 @@ + + + + + + + + + + + + @@ -19,3 +31,6 @@ + + + diff --git a/reactos/lib/gdi32/gdi32.xml b/reactos/lib/gdi32/gdi32.xml new file mode 100644 index 00000000000..d88b2e97803 --- /dev/null +++ b/reactos/lib/gdi32/gdi32.xml @@ -0,0 +1,35 @@ + + addsys + + include + + + + 0x0600 + 0x0501 + ntdll + rosrtl + kernel32 + advapi32 + + dllmain.c + + + heap.c + misc.c + stubs.c + stubsa.c + stubsw.c + win32k.c + wingl.c + + + bitblt.c + dc.c + font.c + linedda.c + metafile.c + region.c + text.c + + diff --git a/reactos/lib/libwine/libwine.xml b/reactos/lib/libwine/libwine.xml new file mode 100644 index 00000000000..331521bdf47 --- /dev/null +++ b/reactos/lib/libwine/libwine.xml @@ -0,0 +1,5 @@ + + + + debug.c + diff --git a/reactos/lib/msvcrt/misc/dllmain.c b/reactos/lib/msvcrt/misc/dllmain.c index ad14d56245a..e8057c6a829 100644 --- a/reactos/lib/msvcrt/misc/dllmain.c +++ b/reactos/lib/msvcrt/misc/dllmain.c @@ -91,8 +91,8 @@ DllMain(PVOID hinstDll, ULONG dwReason, PVOID reserved) return FALSE; } - _acmdln = strdup(GetCommandLineA()); - _wcmdln = wcsdup(GetCommandLineW()); + _acmdln = _strdup(GetCommandLineA()); + _wcmdln = _wcsdup(GetCommandLineW()); /* FIXME: more initializations... */ diff --git a/reactos/lib/msvcrt/misc/environ.c b/reactos/lib/msvcrt/misc/environ.c index 152f82e79f9..93d5f31534c 100644 --- a/reactos/lib/msvcrt/misc/environ.c +++ b/reactos/lib/msvcrt/misc/environ.c @@ -165,9 +165,9 @@ char **DuplicateEnvironment(char **original_environment, int wide) for (envptr = original_environment; count > 1; newenvptr++, count--) { if (wide) - *newenvptr = (char*)wcsdup((wchar_t*)*envptr++); + *newenvptr = (char*)_wcsdup((wchar_t*)*envptr++); else - *newenvptr = strdup(*envptr++); + *newenvptr = _strdup(*envptr++); if (*newenvptr == NULL) { for (newenvptr--; newenvptr >= newenv; newenvptr--); @@ -243,7 +243,7 @@ int SetEnv(const wchar_t *option) /* Find the option we're trying to modify. */ for (index = 0, wenvptr = _wenviron; *wenvptr != NULL; wenvptr++, index++) { - if (!wcsnicmp(*wenvptr, option, epos - option)) + if (!_wcsnicmp(*wenvptr, option, epos - option)) { found = 1; break; @@ -277,7 +277,7 @@ int SetEnv(const wchar_t *option) else { /* Make a copy of the option that we will store in the environment block. */ - woption = wcsdup((wchar_t*)option); + woption = _wcsdup((wchar_t*)option); if (woption == NULL) { free(name); diff --git a/reactos/lib/msvcrt/msvcrt.xml b/reactos/lib/msvcrt/msvcrt.xml new file mode 100644 index 00000000000..d9f7e95da89 --- /dev/null +++ b/reactos/lib/msvcrt/msvcrt.xml @@ -0,0 +1,443 @@ + + -nostartfiles + --enable-stdcall-fixup + -lgcc + + . + + + 0x600 + 0x501 + + + + + wine + string + kernel32 + ntdll + + cgets.c + cprintf.c + cputs.c + cscanf.c + getch.c + getche.c + kbhit.c + putch.c + ungetch.c + + + ctype.c + isalnum.c + isalpha.c + isascii.c + iscntrl.c + iscsym.c + isctype.c + isdigit.c + isgraph.c + islower.c + isprint.c + ispunct.c + isspace.c + isupper.c + isxdigit.c + toascii.c + tolower.c + toupper.c + + + chdir.c + chdrive.c + getcwd.c + getdcwd.c + getdfree.c + getdrive.c + mkdir.c + rmdir.c + wchdir.c + wgetcwd.c + wgetdcwd.c + wmkdir.c + wrmdir.c + + + abnorter.c + exhand2.c + matherr.c + seh.s + unwind.c + xcptfil.c + + + chgsign.c + clearfp.c + cntrlfp.c + copysign.c + fpclass.c + fpecode.c + fpreset.c + isnan.c + logb.c + nafter.c + scalb.c + statfp.c + + + access.c + chmod.c + chsize.c + close.c + commit.c + create.c + dup2.c + dup.c + eof.c + filelen.c + fileleni.c + find.c + fmode.c + isatty.c + locking.c + lseek.c + lseeki64.c + mktemp.c + open.c + pipe.c + read.c + setmode.c + sopen.c + stubs.c + tell.c + telli64.c + umask.c + unlink.c + utime.c + waccess.c + wchmod.c + wcreate.c + wfind.c + wmktemp.c + wopen.c + write.c + wunlink.c + wutime.c + + + locale.c + + + acos.c + adjust.c + asin.c + atan2.c + atan.c + cabs.c + ceil.c + cos.c + cosh.c + exp.c + fabs.c + floor.c + fmod.c + frexp.c + huge_val.c + hypot.c + j0_y0.c + j1_y1.c + jn_yn.c + ldexp.c + log10.c + log.c + math.c + modf.c + pow.c + sin.c + sinh.c + sqrt.c + stubs.c + tan.c + tanh.c + + + hanzen.c + ischira.c + iskana.c + iskmoji.c + iskpun.c + islead.c + islwr.c + ismbal.c + ismbaln.c + ismbc.c + ismbgra.c + ismbkaln.c + ismblead.c + ismbpri.c + ismbpun.c + ismbtrl.c + isuppr.c + jistojms.c + jmstojis.c + mbbtype.c + mbccpy.c + mbclen.c + mbscat.c + mbschr.c + mbscmp.c + mbscoll.c + mbscpy.c + mbscspn.c + mbsdec.c + mbsdup.c + mbsicmp.c + mbsicoll.c + mbsinc.c + mbslen.c + mbslwr.c + mbsncat.c + mbsnccnt.c + mbsncmp.c + mbsncoll.c + mbsncpy.c + mbsnextc.c + mbsnicmp.c + mbsnicoll.c + mbsninc.c + mbsnset.c + mbspbrk.c + mbsrchr.c + mbsrev.c + mbsset.c + mbsspn.c + mbsspnp.c + mbsstr.c + mbstok.c + mbstrlen.c + mbsupr.c + + + amsg.c + assert.c + crtmain.c + dllmain.c + environ.c + getargs.c + initterm.c + lock.c + purecall.c + stubs.c + tls.c + + + _cwait.c + _system.c + dll.c + process.c + procid.c + thread.c + threadid.c + threadx.c + + + lfind.c + lsearch.c + + + + setjmp.s + + + + signal.c + + + allocfil.c + clearerr.c + fclose.c + fdopen.c + feof.c + ferror.c + fflush.c + fgetc.c + fgetchar.c + fgetpos.c + fgets.c + fgetws.c + filbuf.c + fileno.c + flsbuf.c + fopen.c + fprintf.c + fputc.c + fputchar.c + fputs.c + fread.c + freopen.c + fscanf.c + fseek.c + fsetpos.c + fsopen.c + ftell.c + fwalk.c + fwrite.c + getc.c + getchar.c + gets.c + getw.c + perror.c + popen.c + printf.c + putc.c + putchar.c + puts.c + putw.c + remove.c + rename.c + rewind.c + rmtmp.c + scanf.c + setbuf.c + setvbuf.c + sprintf.c + sscanf.c + stdhnd.c + tempnam.c + tmpfile.c + tmpnam.c + ungetc.c + vfprintf.c + vfscanf.c + vfwprint.c + vprintf.c + vscanf.c + vsprintf.c + vsscanf.c + wfdopen.c + wrename.c + wtempnam.c + wtmpnam.c + + + abort.c + abs.c + atexit.c + atof.c + atoi.c + atoi64.c + atol.c + atold.c + bsearch.c + div.c + ecvt.c + ecvtbuf.c + errno.c + fcvt.c + fcvtbuf.c + fullpath.c + gcvt.c + getenv.c + itoa.c + itow.c + labs.c + ldiv.c + makepath.c + malloc.c + mbstowcs.c + mbtowc.c + obsol.c + putenv.c + qsort.c + rand.c + rot.c + senv.c + splitp.c + strtod.c + strtol.c + strtold.c + strtoll.c + strtoul.c + strtoull.c + swab.c + wcstod.c + wcstol.c + wcstom.c + wcstomb.c + wcstombs.c + wcstoul.c + wctomb.c + wfulpath.c + witoa.c + witow.c + wmakpath.c + wputenv.c + wsenv.c + wsplitp.c + wtoi.c + wtoi64.c + _exit.c + + + lasttok.c + memicmp.c + strcoll.c + strdup.c + strerror.c + stricmp.c + strlwr.c + strncoll.c + strnicmp.c + strpbrk.c + strrev.c + strset.c + strstr.c + strtok.c + strupr.c + strxfrm.c + + + fstat.c + fstati64.c + futime.c + stat.c + wstat.c + + + clock.c + ctime.c + difftime.c + ftime.c + strdate.c + strftime.c + strtime.c + time.c + tz_vars.c + wctime.c + wstrdate.c + wstrtime.c + + + cpp.c + cppexcept.c + heap.c + thread.c + + + wcscoll.c + wcscspn.c + wcsdup.c + wcsicmp.c + wcslwr.c + wcsnicmp.c + wcspbrk.c + wcsrev.c + wcsset.c + wcsspn.c + wcsstr.c + wcstok.c + wcsupr.c + wcsxfrm.c + wlasttok.c + + diff --git a/reactos/lib/user32/user32.xml b/reactos/lib/user32/user32.xml new file mode 100644 index 00000000000..deb77b42c3b --- /dev/null +++ b/reactos/lib/user32/user32.xml @@ -0,0 +1,74 @@ + + addsys + + include + + + + + 0x0600 + 0x0501 + wine + ntdll + gdi32 + rosrtl + kernel32 + advapi32 + + button.c + combo.c + edit.c + icontitle.c + listbox.c + regcontrol.c + scrollbar.c + static.c + + + dde.c + ddeclient.c + ddeserver.c + desktop.c + display.c + dllmain.c + exit.c + exticon.c + misc.c + object.c + resources.c + strpool.c + stubs.c + timer.c + win32k.c + winhelp.c + winsta.c + wsprintf.c + + + accel.c + bitmap.c + caret.c + class.c + clipboard.c + cursor.c + dc.c + defwnd.c + dialog.c + draw.c + font.c + hook.c + icon.c + input.c + mdi.c + menu.c + message.c + messagebox.c + nonclient.c + paint.c + prop.c + rect.c + text.c + window.c + winpos.c + + diff --git a/reactos/subsys/directory.xml b/reactos/subsys/directory.xml new file mode 100644 index 00000000000..ec975b344bb --- /dev/null +++ b/reactos/subsys/directory.xml @@ -0,0 +1,3 @@ + + + diff --git a/reactos/subsys/system/directory.xml b/reactos/subsys/system/directory.xml new file mode 100644 index 00000000000..fdee0ae1dc8 --- /dev/null +++ b/reactos/subsys/system/directory.xml @@ -0,0 +1,3 @@ + + + diff --git a/reactos/subsys/system/welcome/welcome.xml b/reactos/subsys/system/welcome/welcome.xml new file mode 100644 index 00000000000..25e05253334 --- /dev/null +++ b/reactos/subsys/system/welcome/welcome.xml @@ -0,0 +1,9 @@ + + 0x0501 + 0x0501 + + kernel32 + gdi32 + user32 + welcome.c + diff --git a/reactos/tools/rbuild/backend/mingw/mingw.cpp b/reactos/tools/rbuild/backend/mingw/mingw.cpp index 4c9e01ba747..86005c735e2 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.cpp +++ b/reactos/tools/rbuild/backend/mingw/mingw.cpp @@ -129,6 +129,20 @@ MingwBackend::GenerateGlobalCFlagsAndProperties ( } } +string +MingwBackend::GenerateProjectLFLAGS () +{ + string lflags; + for ( size_t i = 0; i < ProjectNode.linkerFlags.size (); i++ ) + { + LinkerFlag& linkerFlag = *ProjectNode.linkerFlags[i]; + if ( lflags.length () > 0 ) + lflags += " "; + lflags += linkerFlag.flag; + } + return lflags; +} + void MingwBackend::GenerateGlobalVariables () { @@ -146,6 +160,7 @@ MingwBackend::GenerateGlobalVariables () ProjectNode.includes, ProjectNode.defines, ProjectNode.ifs ); + fprintf ( fMakefile, "PROJECT_LFLAGS = %s\n", GenerateProjectLFLAGS ().c_str () ); fprintf ( fMakefile, "\n" ); fprintf ( fMakefile, ".PHONY: clean\n\n" ); diff --git a/reactos/tools/rbuild/backend/mingw/mingw.h b/reactos/tools/rbuild/backend/mingw/mingw.h index 6fc81649163..0f047d82e59 100644 --- a/reactos/tools/rbuild/backend/mingw/mingw.h +++ b/reactos/tools/rbuild/backend/mingw/mingw.h @@ -21,6 +21,7 @@ private: const std::vector& includes, const std::vector& defines, const std::vector& ifs ); + std::string GenerateProjectLFLAGS (); void GenerateGlobalVariables (); void GenerateAllTarget (); FILE* fMakefile; diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp index dd1759256e3..970b85e272f 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.cpp +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.cpp @@ -265,15 +265,38 @@ MingwModuleHandler::GenerateGccIncludeParameters ( const Module& module ) const return parameters; } + +string +MingwModuleHandler::GenerateLinkerParametersFromVector ( const vector& linkerFlags ) const +{ + string parameters; + for ( size_t i = 0; i < linkerFlags.size (); i++ ) + { + LinkerFlag& linkerFlag = *linkerFlags[i]; + if ( parameters.length () > 0 ) + parameters += " "; + parameters += linkerFlag.flag; + } + return parameters; +} + +string +MingwModuleHandler::GenerateLinkerParameters ( const Module& module ) const +{ + return GenerateLinkerParametersFromVector ( module.linkerFlags ); +} + void MingwModuleHandler::GenerateMacros ( - const char* op, + const char* assignmentOperation, const vector& files, const vector& includes, const vector& defines, + const vector* linkerFlags, const vector& ifs, const string& cflags_macro, const string& nasmflags_macro, + const string& linkerflags_macro, const string& objs_macro) const { size_t i; @@ -284,7 +307,7 @@ MingwModuleHandler::GenerateMacros ( fMakefile, "%s %s", cflags_macro.c_str(), - op ); + assignmentOperation ); for ( i = 0; i < includes.size(); i++ ) { fprintf ( @@ -307,14 +330,28 @@ MingwModuleHandler::GenerateMacros ( } fprintf ( fMakefile, "\n" ); } - + + if ( linkerFlags != NULL ) + { + string linkerParameters = GenerateLinkerParametersFromVector ( *linkerFlags ); + if ( linkerParameters.size () > 0 ) + { + fprintf ( + fMakefile, + "%s %s %s\n", + linkerflags_macro.c_str (), + assignmentOperation, + linkerParameters.c_str() ); + } + } + if ( files.size() ) { fprintf ( fMakefile, "%s %s", objs_macro.c_str(), - op ); + assignmentOperation ); for ( i = 0; i < files.size(); i++ ) { fprintf ( @@ -341,9 +378,11 @@ MingwModuleHandler::GenerateMacros ( rIf.files, rIf.includes, rIf.defines, + NULL, rIf.ifs, cflags_macro, nasmflags_macro, + linkerflags_macro, objs_macro ); fprintf ( fMakefile, @@ -357,6 +396,7 @@ MingwModuleHandler::GenerateMacros ( const Module& module, const string& cflags_macro, const string& nasmflags_macro, + const string& linkerflags_macro, const string& objs_macro) const { GenerateMacros ( @@ -364,9 +404,11 @@ MingwModuleHandler::GenerateMacros ( module.files, module.includes, module.defines, + &module.linkerFlags, module.ifs, cflags_macro, nasmflags_macro, + linkerflags_macro, objs_macro ); fprintf ( fMakefile, "\n" ); @@ -374,6 +416,11 @@ MingwModuleHandler::GenerateMacros ( fMakefile, "%s += $(PROJECT_CFLAGS)\n\n", cflags_macro.c_str () ); + + fprintf ( + fMakefile, + "%s_LFLAGS += $(PROJECT_LFLAGS)\n\n", + module.name.c_str () ); } string @@ -447,6 +494,23 @@ MingwModuleHandler::GenerateCommand ( const Module& module, sourceFilename.c_str () ); } +string +MingwModuleHandler::GenerateLinkerCommand ( const Module& module, + const string& linker, + const string& linkerParameters, + const string& objectFilenames ) const +{ + string target ( FixupTargetFilename ( module.GetPath () ) ); + string importLibraryDependencies = GetImportLibraryDependencies ( module ); + return ssprintf ( "%s %s -o %s %s %s %s\n", + linker.c_str (), + linkerParameters.c_str (), + target.c_str (), + objectFilenames.c_str (), + importLibraryDependencies.c_str (), + GetLinkerMacro ( module ).c_str () ); +} + void MingwModuleHandler::GenerateObjectFileTargets ( const Module& module, const vector& files, @@ -523,17 +587,25 @@ MingwModuleHandler::GenerateArchiveTarget ( const Module& module, return archiveFilename; } +string +MingwModuleHandler::GetLinkerMacro ( const Module& module ) const +{ + return ssprintf ( "$(%s_LFLAGS)", + module.name.c_str () ); +} + void MingwModuleHandler::GenerateMacrosAndTargets ( const Module& module, const string& cc, const string& ar ) const { - string cflagsMacro = ssprintf("%s_CFLAGS",module.name.c_str()); - string nasmflagsMacro = ssprintf("%s_NASMFLAGS",module.name.c_str()); - string objectsMacro = ssprintf("%s_OBJS",module.name.c_str()); + string cflagsMacro = ssprintf ("%s_CFLAGS", module.name.c_str ()); + string nasmflagsMacro = ssprintf ("%s_NASMFLAGS", module.name.c_str ()); + string linkerFlagsMacro = ssprintf ("%s_LFLAGS", module.name.c_str ()); + string objectsMacro = ssprintf ("%s_OBJS", module.name.c_str ()); - GenerateMacros ( module, cflagsMacro, nasmflagsMacro, objectsMacro ); + GenerateMacros ( module, cflagsMacro, nasmflagsMacro, linkerFlagsMacro, objectsMacro ); // generate phony target for module name fprintf ( fMakefile, ".PHONY: %s\n", @@ -543,9 +615,9 @@ MingwModuleHandler::GenerateMacrosAndTargets ( module.GetPath().c_str() ); // future references to the macros will be to get their values - cflagsMacro = ssprintf("$(%s)",cflagsMacro.c_str()); - nasmflagsMacro = ssprintf("$(%s)",nasmflagsMacro.c_str()); - objectsMacro = ssprintf("$(%s)",objectsMacro.c_str()); + cflagsMacro = ssprintf ("$(%s)", cflagsMacro.c_str ()); + nasmflagsMacro = ssprintf ("$(%s)", nasmflagsMacro.c_str ()); + objectsMacro = ssprintf ("$(%s)", objectsMacro.c_str ()); string ar_target = GenerateArchiveTarget ( module, ar, objectsMacro ); GenerateObjectFileTargets ( module, cc, cflagsMacro, nasmflagsMacro ); @@ -743,7 +815,8 @@ MingwBuildToolModuleHandler::GenerateBuildToolModuleTarget ( const Module& modul target.c_str (), archiveFilename.c_str () ); fprintf ( fMakefile, - "\t${host_gcc} -o %s %s\n\n", + "\t${host_gcc} %s -o %s %s\n\n", + GetLinkerMacro ( module ).c_str (), target.c_str (), archiveFilename.c_str () ); } @@ -767,7 +840,6 @@ void MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module ) { static string ros_junk ( "$(ROS_TEMPORARY)" ); - //static string ros_output ( "$(ROS_INTERMEDIATE)" ); string target ( FixupTargetFilename(module.GetPath()) ); string workingDirectory = GetWorkingDirectory ( ); string archiveFilename = GetModuleArchiveFilename ( module ); @@ -785,7 +857,8 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module ) archiveFilename.c_str (), importLibraryDependencies.c_str () ); fprintf ( fMakefile, - "\t${gcc} %s -Wl,--base-file,%s -o %s %s %s\n", + "\t${gcc} %s %s -Wl,--base-file,%s -o %s %s %s\n", + GetLinkerMacro ( module ).c_str (), gccOptions.c_str (), base_tmp.c_str (), junk_tmp.c_str (), @@ -804,7 +877,8 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ( const Module& module ) "\t${rm} %s\n", base_tmp.c_str () ); fprintf ( fMakefile, - "\t${gcc} %s -Wl,%s -o %s %s %s\n", + "\t${gcc} %s %s -Wl,%s -o %s %s %s\n", + GetLinkerMacro ( module ).c_str (), gccOptions.c_str (), temp_exp.c_str (), target.c_str (), @@ -882,12 +956,15 @@ MingwKernelModeDLLModuleHandler::GenerateKernelModeDLLModuleTarget ( const Modul target.c_str (), archiveFilename.c_str (), importLibraryDependencies.c_str () ); - + + string linkerParameters ( "-Wl,--subsystem,native -Wl,--entry,_DriverEntry@8 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll" ); + string linkerCommand = GenerateLinkerCommand ( module, + "${gcc}", + linkerParameters, + archiveFilename ); fprintf ( fMakefile, - "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DriverEntry@8 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -mdll -o %s %s %s\n\n", - target.c_str (), - archiveFilename.c_str (), - importLibraryDependencies.c_str () ); + "\t%s\n\n", + linkerCommand.c_str () ); } else { @@ -943,12 +1020,15 @@ MingwNativeDLLModuleHandler::GenerateNativeDLLModuleTarget ( const Module& modul target.c_str (), archiveFilename.c_str (), importLibraryDependencies.c_str () ); - + + string linkerParameters ( "-Wl,--subsystem,native -Wl,--entry,_DllMainCRTStartup@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll" ); + string linkerCommand = GenerateLinkerCommand ( module, + "${gcc}", + linkerParameters, + archiveFilename ); fprintf ( fMakefile, - "\t${gcc} -Wl,--subsystem,native -Wl,--entry,_DllMainCRTStartup@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll -o %s %s %s\n\n", - target.c_str (), - archiveFilename.c_str (), - importLibraryDependencies.c_str () ); + "\t%s\n\n", + linkerCommand.c_str () ); } else { @@ -1005,11 +1085,66 @@ MingwWin32DLLModuleHandler::GenerateWin32DLLModuleTarget ( const Module& module archiveFilename.c_str (), importLibraryDependencies.c_str () ); + string linkerParameters ( "-Wl,--subsystem,console -Wl,--entry,_DllMain@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -mdll" ); + string linkerCommand = GenerateLinkerCommand ( module, + "${gcc}", + linkerParameters, + archiveFilename ); fprintf ( fMakefile, - "\t${gcc} -Wl,--subsystem,console -Wl,--entry,_DllMain@12 -Wl,--image-base,0x10000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -nostdlib -mdll -o %s %s %s\n", - target.c_str (), - archiveFilename.c_str (), - importLibraryDependencies.c_str () ); + "\t%s\n\n", + linkerCommand.c_str () ); + } + else + { + fprintf ( fMakefile, "%s:\n\n", + target.c_str ()); + fprintf ( fMakefile, ".PHONY: %s\n\n", + target.c_str ()); + } +} + + +static MingwWin32GUIModuleHandler win32gui_handler; + +MingwWin32GUIModuleHandler::MingwWin32GUIModuleHandler () + : MingwModuleHandler ( Win32GUI ) +{ +} + +void +MingwWin32GUIModuleHandler::Process ( const Module& module ) +{ + GeneratePreconditionDependencies ( module ); + GenerateWin32GUIModuleTarget ( module ); + GenerateInvocations ( module ); +} + +void +MingwWin32GUIModuleHandler::GenerateWin32GUIModuleTarget ( const Module& module ) +{ + static string ros_junk ( "$(ROS_TEMPORARY)" ); + string target ( FixupTargetFilename ( module.GetPath () ) ); + string workingDirectory = GetWorkingDirectory ( ); + string objectFilenames = GetObjectFilenames ( module ); + string importLibraryDependencies = GetImportLibraryDependencies ( module ); + + if (module.files.size () > 0) + { + GenerateMacrosAndTargetsTarget ( module ); + + fprintf ( fMakefile, "%s: %s %s\n", + target.c_str (), + objectFilenames.c_str (), + importLibraryDependencies.c_str () ); + + string linkerParameters ( "-Wl,--subsystem,windows -Wl,--entry,_WinMainCRTStartup -Wl,--image-base,0x00400000 -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000" ); + string linkerCommand = GenerateLinkerCommand ( module, + "${gcc}", + linkerParameters, + objectFilenames ); + fprintf ( fMakefile, + "\t%s\n\n", + linkerCommand.c_str () ); } else { diff --git a/reactos/tools/rbuild/backend/mingw/modulehandler.h b/reactos/tools/rbuild/backend/mingw/modulehandler.h index c8319127514..e3e420f87f4 100644 --- a/reactos/tools/rbuild/backend/mingw/modulehandler.h +++ b/reactos/tools/rbuild/backend/mingw/modulehandler.h @@ -36,9 +36,14 @@ protected: std::string GetInvocationParameters ( const Invoke& invoke ) const; void GenerateInvocations ( const Module& module ) const; void GeneratePreconditionDependencies ( const Module& module ) const; + std::string GetLinkerMacro ( const Module& module ) const; std::string GenerateMacros ( const Module& module, const std::string& cflags_macro, const std::string& objs_macro ) const; + std::string GenerateLinkerCommand ( const Module& module, + const std::string& linker, + const std::string& linkerParameters, + const std::string& objectFilenames ) const; static FILE* fMakefile; private: std::string ConcatenatePaths ( const std::string& path1, @@ -46,17 +51,22 @@ private: std::string GenerateGccDefineParametersFromVector ( const std::vector& defines ) const; std::string GenerateGccDefineParameters ( const Module& module ) const; std::string GenerateGccIncludeParametersFromVector ( const std::vector& includes ) const; + std::string GenerateLinkerParametersFromVector ( const std::vector& linkerFlags ) const; + std::string GenerateLinkerParameters ( const Module& module ) const; void GenerateMacros ( const char* op, const std::vector& files, const std::vector& includes, const std::vector& defines, + const std::vector* linkerFlags, const std::vector& ifs, const std::string& cflags_macro, const std::string& nasmflags_macro, + const std::string& linkerflags_macro, const std::string& objs_macro) const; void GenerateMacros ( const Module& module, const std::string& cflags_macro, const std::string& nasmflags_macro, + const std::string& linkerflags_macro, const std::string& objs_macro) const; void GenerateGccModuleIncludeVariable ( const Module& module ) const; std::string GenerateGccIncludeParameters ( const Module& module ) const; @@ -160,4 +170,14 @@ private: void GenerateWin32DLLModuleTarget ( const Module& module ); }; + +class MingwWin32GUIModuleHandler : public MingwModuleHandler +{ +public: + MingwWin32GUIModuleHandler (); + virtual void Process ( const Module& module ); +private: + void GenerateWin32GUIModuleTarget ( const Module& module ); +}; + #endif /* MINGW_MODULEHANDLER_H */ diff --git a/reactos/tools/rbuild/include.cpp b/reactos/tools/rbuild/include.cpp index 3e80ec351d7..1111efe9981 100644 --- a/reactos/tools/rbuild/include.cpp +++ b/reactos/tools/rbuild/include.cpp @@ -40,7 +40,8 @@ void Include::ProcessXML() { const XMLAttribute* att; - att = node.GetAttribute("base",false); + att = node.GetAttribute ( "base", + false ); if ( att ) { if ( !module ) diff --git a/reactos/tools/rbuild/linkerflag.cpp b/reactos/tools/rbuild/linkerflag.cpp new file mode 100644 index 00000000000..6ef22c93cb5 --- /dev/null +++ b/reactos/tools/rbuild/linkerflag.cpp @@ -0,0 +1,47 @@ +#include "pch.h" +#include + +#include "rbuild.h" + +using std::string; +using std::vector; + +LinkerFlag::LinkerFlag ( const Project& project_, + const XMLElement& linkerFlagNode ) + : project(project_), + module(NULL), + node(linkerFlagNode) +{ + Initialize(); +} + +LinkerFlag::LinkerFlag ( const Project& project_, + const Module* module_, + const XMLElement& linkerFlagNode ) + : project(project_), + module(module_), + node(linkerFlagNode) +{ + Initialize(); +} + +LinkerFlag::~LinkerFlag () +{ +} + +void +LinkerFlag::Initialize() +{ +} + +void +LinkerFlag::ProcessXML() +{ + if (node.value.size () == 0) + { + throw InvalidBuildFileException ( + node.location, + " is empty." ); + } + flag = node.value; +} diff --git a/reactos/tools/rbuild/makefile b/reactos/tools/rbuild/makefile index b2f9f0c4ec1..7d637ac71ec 100644 --- a/reactos/tools/rbuild/makefile +++ b/reactos/tools/rbuild/makefile @@ -17,6 +17,7 @@ BASE_OBJECTS = \ define.o \ exception.o \ include.o \ + linkerflag.o \ module.o \ project.o \ ssprintf.o \ @@ -28,6 +29,7 @@ TESTS = \ tests/definetest.o \ tests/includetest.o \ tests/invoketest.o \ + tests/linkerflagtest.o \ tests/moduletest.o \ tests/projecttest.o diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index e1a883d73b5..d91f6541c13 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -65,6 +65,8 @@ Module::~Module () delete dependencies[i]; for ( i = 0; i < ifs.size(); i++ ) delete ifs[i]; + for ( i = 0; i < linkerFlags.size(); i++ ) + delete linkerFlags[i]; } void @@ -87,6 +89,8 @@ Module::ProcessXML() dependencies[i]->ProcessXML (); for ( i = 0; i < ifs.size(); i++ ) ifs[i]->ProcessXML(); + for ( i = 0; i < linkerFlags.size(); i++ ) + linkerFlags[i]->ProcessXML(); } void @@ -179,6 +183,11 @@ Module::ProcessXMLSubElement ( const XMLElement& e, ifs.push_back ( pIf ); subs_invalid = false; } + else if ( e.name == "linkerflag" ) + { + linkerFlags.push_back ( new LinkerFlag ( project, this, e ) ); + subs_invalid = true; + } else if ( e.name == "property" ) { throw InvalidBuildFileException ( @@ -209,6 +218,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute ) return NativeDLL; if ( attribute.value == "win32dll" ) return Win32DLL; + if ( attribute.value == "win32gui" ) + return Win32GUI; throw InvalidAttributeValueException ( location, attribute.name, attribute.value ); @@ -224,6 +235,7 @@ Module::GetDefaultModuleExtension () const case StaticLibrary: return ".a"; case Kernel: + case Win32GUI: return ".exe"; case KernelModeDLL: case NativeDLL: diff --git a/reactos/tools/rbuild/project.cpp b/reactos/tools/rbuild/project.cpp index 1dd47919187..6d8a4840674 100644 --- a/reactos/tools/rbuild/project.cpp +++ b/reactos/tools/rbuild/project.cpp @@ -13,7 +13,9 @@ using std::vector; }*/ Project::Project ( const string& filename ) - : xmlfile(filename), node(NULL), head(NULL) + : xmlfile(filename), + node(NULL), + head(NULL) { ReadXml(); } @@ -27,6 +29,8 @@ Project::~Project () delete includes[i]; for ( i = 0; i < defines.size(); i++ ) delete defines[i]; + for ( i = 0; i < linkerFlags.size(); i++ ) + delete linkerFlags[i]; for ( i = 0; i < properties.size(); i++ ) delete properties[i]; for ( i = 0; i < ifs.size(); i++ ) @@ -81,6 +85,8 @@ Project::ProcessXML ( const string& path ) includes[i]->ProcessXML(); for ( i = 0; i < defines.size(); i++ ) defines[i]->ProcessXML(); + for ( i = 0; i < linkerFlags.size(); i++ ) + linkerFlags[i]->ProcessXML(); for ( i = 0; i < properties.size(); i++ ) properties[i]->ProcessXML(); for ( i = 0; i < ifs.size(); i++ ) @@ -134,6 +140,11 @@ Project::ProcessXMLSubElement ( const XMLElement& e, defines.push_back ( define ); subs_invalid = true; } + else if ( e.name == "linkerflag" ) + { + linkerFlags.push_back ( new LinkerFlag ( *this, e ) ); + subs_invalid = true; + } else if ( e.name == "if" ) { If* pOldIf = pIf; diff --git a/reactos/tools/rbuild/rbuild.h b/reactos/tools/rbuild/rbuild.h index c40ea2e4ce0..89f4415d1d1 100644 --- a/reactos/tools/rbuild/rbuild.h +++ b/reactos/tools/rbuild/rbuild.h @@ -32,6 +32,7 @@ class InvokeFile; class Dependency; class ImportLibrary; class If; +class LinkerFlag; class Property; class Project @@ -44,6 +45,7 @@ public: std::vector modules; std::vector includes; std::vector defines; + std::vector linkerFlags; std::vector properties; std::vector ifs; @@ -72,7 +74,8 @@ enum ModuleType Kernel, KernelModeDLL, NativeDLL, - Win32DLL + Win32DLL, + Win32GUI }; @@ -93,6 +96,7 @@ public: std::vector invocations; std::vector dependencies; std::vector ifs; + std::vector linkerFlags; Module ( const Project& project, const XMLElement& moduleNode, @@ -248,6 +252,7 @@ public: void ProcessXML (); }; + class If { public: @@ -269,6 +274,27 @@ public: void ProcessXML(); }; + +class LinkerFlag +{ +public: + const Project& project; + const Module* module; + const XMLElement& node; + std::string flag; + + LinkerFlag ( const Project& project, + const XMLElement& linkerFlagNode ); + LinkerFlag ( const Project& project, + const Module* module, + const XMLElement& linkerFlagNode ); + ~LinkerFlag (); + void ProcessXML(); +private: + void Initialize(); +}; + + class Property { public: diff --git a/reactos/tools/rbuild/test.h b/reactos/tools/rbuild/test.h index 9fc9df90ce5..e8dc2e31c6f 100644 --- a/reactos/tools/rbuild/test.h +++ b/reactos/tools/rbuild/test.h @@ -81,4 +81,10 @@ public: void Run(); }; +class LinkerFlagTest : public BaseTest +{ +public: + void Run(); +}; + #endif /* __TEST_H */ diff --git a/reactos/tools/rbuild/tests/alltests.cpp b/reactos/tools/rbuild/tests/alltests.cpp index f8ac9b7ab05..effcdfb2d63 100644 --- a/reactos/tools/rbuild/tests/alltests.cpp +++ b/reactos/tools/rbuild/tests/alltests.cpp @@ -174,6 +174,7 @@ private: tests.push_back(new DefineTest()); tests.push_back(new IncludeTest()); tests.push_back(new InvokeTest()); + tests.push_back(new LinkerFlagTest()); } }; diff --git a/reactos/tools/rbuild/tests/data/linkerflag.xml b/reactos/tools/rbuild/tests/data/linkerflag.xml new file mode 100644 index 00000000000..843a03ede2f --- /dev/null +++ b/reactos/tools/rbuild/tests/data/linkerflag.xml @@ -0,0 +1,7 @@ + + + -lgcc1 + + -lgcc2 + + diff --git a/reactos/tools/rbuild/tests/linkerflagtest.cpp b/reactos/tools/rbuild/tests/linkerflagtest.cpp new file mode 100644 index 00000000000..1445fa80851 --- /dev/null +++ b/reactos/tools/rbuild/tests/linkerflagtest.cpp @@ -0,0 +1,19 @@ +#include "test.h" + +using std::string; + +void LinkerFlagTest::Run() +{ + string projectFilename ( "tests/data/linkerflag.xml" ); + Project project ( projectFilename ); + ARE_EQUAL(1, project.linkerFlags.size()); + LinkerFlag& linkerFlag1 = *project.linkerFlags[0]; + ARE_EQUAL("-lgcc1", linkerFlag1.flag); + + ARE_EQUAL(1, project.modules.size()); + Module& module1 = *project.modules[0]; + + ARE_EQUAL(1, module1.linkerFlags.size()); + LinkerFlag& linkerFlag2 = *module1.linkerFlags[0]; + ARE_EQUAL("-lgcc2", linkerFlag2.flag); +}