Don't add underscore prefix to amd64 symbols
[reactos.git] / reactos / tools / rbuild / module.cpp
index f6ce294..38a104a 100644 (file)
@@ -12,9 +12,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 #include "pch.h"
 #include <assert.h>
@@ -260,6 +260,7 @@ Module::Module ( const Project& project,
        : project (project),
          node (moduleNode),
          importLibrary (NULL),
+         delayImportLibrary (NULL),
          metadata (NULL),
          bootSector (NULL),
          bootstrap (NULL),
@@ -342,14 +343,6 @@ Module::Module ( const Project& project,
        else
                baseaddress = GetDefaultModuleBaseaddress ();
 
-       mangledSymbols = GetBooleanAttribute ( moduleNode, "mangledsymbols" );
-
-       att = moduleNode.GetAttribute ( "underscoresymbols", false );
-       if ( att != NULL )
-               underscoreSymbols = att->value == "true";
-       else
-               underscoreSymbols = false;
-
        isStartupLib = GetBooleanAttribute ( moduleNode, "isstartuplib" );
        isCRT = GetBooleanAttribute ( moduleNode, "iscrt", GetDefaultModuleIsCRT () );
 
@@ -452,6 +445,8 @@ Module::Module ( const Project& project,
        }
        if ( att != NULL )
                allowWarnings = att->value == "true";
+       else if ( project.allowWarningsSet )
+               allowWarnings = project.allowWarnings;
        else
                allowWarnings = false;
 
@@ -522,6 +517,8 @@ Module::~Module ()
                delete linkerFlags[i];
        for ( i = 0; i < stubbedComponents.size(); i++ )
                delete stubbedComponents[i];
+       for ( i = 0; i < cdfiles.size (); i++ )
+               delete cdfiles[i];
        if ( linkerScript )
                delete linkerScript;
        if ( pch )
@@ -599,6 +596,48 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                   const string& relative_path,
                                ParseContext& parseContext )
 {
+       const XMLAttribute* att;
+
+       att = e.GetAttribute ( "compilerset", false );
+
+       if ( att )
+       {
+               CompilerSet compilerSet;
+
+               if ( att->value == "msc" )
+                       compilerSet = MicrosoftC;
+               else if ( att->value == "gcc" )
+                       compilerSet = GnuGcc;
+               else
+                       throw InvalidAttributeValueException (
+                               e.location,
+                               "compilerset",
+                               att->value );
+
+               if ( compilerSet != project.configuration.Compiler )
+                       return;
+       }
+
+       att = e.GetAttribute ( "linkerset", false );
+
+       if ( att )
+       {
+               LinkerSet linkerSet;
+
+               if ( att->value == "mslink" )
+                       linkerSet = MicrosoftLink;
+               else if ( att->value == "ld" )
+                       linkerSet = GnuLd;
+               else
+                       throw InvalidAttributeValueException (
+                               e.location,
+                               "linkerset",
+                               att->value );
+
+               if ( linkerSet != project.configuration.Linker )
+                       return;
+       }
+
        CompilationUnit* pOldCompilationUnit = parseContext.compilationUnit;
        bool subs_invalid = false;
        string subpath ( relative_path );
@@ -671,7 +710,10 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
        }
        else if ( e.name == "library" && e.value.size () )
        {
+               const XMLAttribute* att = e.GetAttribute ( "delayimport", false );
                Library* pLibrary = new Library ( e, *this, e.value );
+               if ( att && !stricmp ( att->value.c_str(), "true" ) )
+                       pLibrary->delayimp = true;
                non_if_data.libraries.push_back ( pLibrary );
                subs_invalid = true;
        }
@@ -702,7 +744,7 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                non_if_data.includes.push_back ( include );
                subs_invalid = true;
        }
-       else if ( e.name == "define" )
+       else if ( e.name == "define" || e.name == "redefine" )
        {
                Define* pDefine = new Define ( project, this, e );
                non_if_data.defines.push_back ( pDefine );
@@ -736,7 +778,8 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                                e.location,
                                "Only one <importlibrary> is valid per module" );
                }
-               SetImportLibrary ( new ImportLibrary ( project, e, this ) );
+               SetImportLibrary ( new ImportLibrary ( project, e, this, false ) );
+               SetDelayImportLibrary ( new ImportLibrary ( project, e, this, true ) );
                subs_invalid = true;
        }
        else if ( e.name == "if" || e.name == "ifnot" )
@@ -868,6 +911,12 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                autoRegister = new AutoRegister ( project, this, e );
                subs_invalid = true;
        }
+       else if ( e.name == "cdfile" )
+       {
+               CDFile* cdfile = new CDFile ( project, e, subpath );
+               cdfiles.push_back ( cdfile );
+               subs_invalid = true;
+       }
        if ( subs_invalid && e.subElements.size() > 0 )
        {
                throw XMLInvalidBuildFileException (
@@ -875,6 +924,8 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                        "<%s> cannot have sub-elements",
                        e.name.c_str() );
        }
+       for ( size_t i = 0; i < cdfiles.size (); i++ )
+               cdfiles[i]->ProcessXML ();
        for ( size_t i = 0; i < e.subElements.size (); i++ )
                ProcessXMLSubElement ( *e.subElements[i], subdirectory, subpath, parseContext );
        parseContext.compilationUnit = pOldCompilationUnit;
@@ -923,10 +974,6 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return Iso;
        if ( attribute.value == "liveiso" )
                return LiveIso;
-       if ( attribute.value == "isoregtest" )
-               return IsoRegTest;
-       if ( attribute.value == "liveisoregtest" )
-               return LiveIsoRegTest;
        if ( attribute.value == "test" )
                return Test;
        if ( attribute.value == "rpcserver" )
@@ -939,6 +986,8 @@ Module::GetModuleType ( const string& location, const XMLAttribute& attribute )
                return Alias;
        if ( attribute.value == "idlheader" )
                return IdlHeader;
+       if ( attribute.value == "idlinterface" )
+               return IdlInterface;
        if ( attribute.value == "embeddedtypelib" )
                return EmbeddedTypeLib;
        if ( attribute.value == "elfexecutable" )
@@ -975,8 +1024,6 @@ Module::GetTargetDirectoryTree () const
                case BootProgram:
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                case ElfExecutable:
                case Cabinet:
                        return OutputDirectory;
@@ -989,6 +1036,7 @@ Module::GetTargetDirectoryTree () const
                case RpcProxy:
                case Alias:
                case IdlHeader:
+               case IdlInterface:
                case MessageHeader:
                        return IntermediateDirectory;
                case TypeDontCare:
@@ -1037,14 +1085,13 @@ Module::GetDefaultModuleExtension () const
                        return ".o";
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                        return ".iso";
                case Test:
                        return ".exe";
                case RpcServer:
                case RpcClient:
                case RpcProxy:
+               case IdlInterface:
                        return ".o";
                case Alias:
                case ElfExecutable:
@@ -1066,7 +1113,8 @@ Module::GetDefaultModuleEntrypoint () const
        switch ( type )
        {
                case Kernel:
-                       return "KiSystemStartup";
+                       if (Environment::GetArch() == "arm") return "KiSystemStartup";
+            return "KiSystemStartup@4";
                case KeyboardLayout:
                case KernelModeDLL:
                case KernelModeDriver:
@@ -1084,16 +1132,10 @@ Module::GetDefaultModuleEntrypoint () const
                        return "DllMain@12";
                case Win32CUI:
                case Test:
-                       if ( isUnicode )
-                               return "wmainCRTStartup";
-                       else
-                               return "mainCRTStartup";
+                       return "mainCRTStartup";
                case Win32SCR:
                case Win32GUI:
-                       if ( isUnicode )
-                               return "wWinMainCRTStartup";
-                       else
-                               return "WinMainCRTStartup";
+                       return "WinMainCRTStartup";
                case BuildTool:
                case StaticLibrary:
                case HostStaticLibrary:
@@ -1102,14 +1144,13 @@ Module::GetDefaultModuleEntrypoint () const
                case BootSector:
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
                case RpcProxy:
                case Alias:
                case BootProgram:
                case IdlHeader:
+               case IdlInterface:
                case MessageHeader:
                case ElfExecutable:
                case EmbeddedTypeLib:
@@ -1154,14 +1195,13 @@ Module::GetDefaultModuleBaseaddress () const
                case BootSector:
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
                case RpcProxy:
                case Alias:
                case BootProgram:
                case IdlHeader:
+               case IdlInterface:
                case MessageHeader:
                case EmbeddedTypeLib:
                case Cabinet:
@@ -1185,7 +1225,7 @@ Module::GetDefaultModuleCRT () const
                        return "static";
                case Win32DLL:
                case Win32OCX:
-                       return "msvcrt";
+                       return "ntdll";
                case NativeDLL:
                case NativeCUI:
                        return "ntdll";
@@ -1210,14 +1250,13 @@ Module::GetDefaultModuleCRT () const
                case BootSector:
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
                case RpcProxy:
                case Alias:
                case BootProgram:
                case IdlHeader:
+               case IdlInterface:
                case MessageHeader:
                case EmbeddedTypeLib:
                case Cabinet:
@@ -1267,13 +1306,12 @@ Module::IsDLL () const
                case BootProgram:
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                case RpcServer:
                case RpcClient:
                case RpcProxy:
                case Alias:
                case IdlHeader:
+               case IdlInterface:
                case MessageHeader:
                case EmbeddedTypeLib:
                case ElfExecutable:
@@ -1314,12 +1352,13 @@ Module::GetInvocationTarget ( const int index ) const
 }
 
 string
-Module::GetEntryPoint(bool leadingUnderscore) const
+Module::GetEntryPoint() const
 {
        string result = "";
        if (entrypoint == "0" || entrypoint == "0x0")
                return "0";
-       if (leadingUnderscore)
+       
+       if (Environment::GetArch() != "arm" && Environment::GetArch() != "amd64")
                result = "_";
 
        result += entrypoint;
@@ -1374,6 +1413,12 @@ Module::SetImportLibrary ( ImportLibrary* importLibrary )
                                        HasImportLibrary () ? "lib" + name + ".a" : output->name );
 }
 
+void
+Module::SetDelayImportLibrary ( ImportLibrary* importLibrary )
+{
+       this->delayImportLibrary = importLibrary;
+}
+
 std::string
 Module::GetDllName () const
 {
@@ -1385,6 +1430,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,
@@ -1436,7 +1499,8 @@ Library::Library ( const XMLElement& _node,
        : node(&_node),
          module(_module),
          name(_name),
-         importedModule(_module.project.LocateModule(_name))
+         importedModule(_module.project.LocateModule(_name)),
+         delayimp(false)
 {
        if ( module.name == name )
        {
@@ -1460,7 +1524,8 @@ Library::Library ( const Module& _module,
        : node(NULL),
          module(_module),
          name(_name),
-         importedModule(_module.project.LocateModule(_name))
+         importedModule(_module.project.LocateModule(_name)),
+         delayimp(false)
 {
        if ( !importedModule )
        {
@@ -1703,9 +1768,7 @@ bool
 Bootsector::IsSupportedModuleType ( ModuleType type )
 {
        if ( type == Iso ||
-            type == LiveIso ||
-            type == IsoRegTest ||
-                type == LiveIsoRegTest )
+            type == LiveIso )
        {
                return true;
        }
@@ -1771,12 +1834,14 @@ Metadata::Metadata ( const XMLElement& _node,
 ImportLibrary::~ImportLibrary ()
 {
        delete source;
+       delete target;
 }
 
 
 ImportLibrary::ImportLibrary ( const Project& project,
                                const XMLElement& node,
-                               const Module* module )
+                               const Module* module,
+                               bool delayimp )
        : XmlNode ( project, node ),
          module (module)
 {
@@ -1821,10 +1886,6 @@ ImportLibrary::ImportLibrary ( const Project& project,
 
        if ( dllname )
                this->dllname = dllname->value;
-       else if ( module->type == StaticLibrary || module->type == HostStaticLibrary )
-               throw XMLInvalidBuildFileException (
-                   node.location,
-                   "<importlibrary> dllname attribute required." );
 
        size_t index = definition->value.find_last_of ( "/\\" );
        if ( index == string::npos )
@@ -1843,6 +1904,11 @@ ImportLibrary::ImportLibrary ( const Project& project,
                                            name,
                                            &node );
        }
+
+       target = new FileLocation ( IntermediateDirectory,
+                                   base->output->relative_path,
+                                   "lib" + module->name + (delayimp ? ".delayimp.a" :  ".a" ));
+
 }