Don't add underscore prefix to amd64 symbols
[reactos.git] / reactos / tools / rbuild / module.cpp
index 62a0a1f..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>
@@ -24,8 +24,6 @@
 using std::string;
 using std::vector;
 
-static const Path defaultPath;
-
 string
 Right ( const string& s, size_t n )
 {
@@ -240,9 +238,9 @@ bool Module::GetBooleanAttribute ( const XMLElement& moduleNode, const char * na
        if ( att != NULL )
        {
                const char* p = att->value.c_str();
-               if ( !_stricmp ( p, "true" ) || !_stricmp ( p, "yes" ) )
+               if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
                        return true;
-               else if ( !_stricmp ( p, "false" ) || !_stricmp ( p, "no" ) )
+               else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
                        return false;
                else
                {
@@ -262,6 +260,7 @@ Module::Module ( const Project& project,
        : project (project),
          node (moduleNode),
          importLibrary (NULL),
+         delayImportLibrary (NULL),
          metadata (NULL),
          bootSector (NULL),
          bootstrap (NULL),
@@ -344,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 () );
 
@@ -360,26 +351,26 @@ Module::Module ( const Project& project,
        {
                CRT = att->value;
 
-               if ( _stricmp ( CRT.c_str (), "auto" ) == 0 )
+               if ( stricmp ( CRT.c_str (), "auto" ) == 0 )
                        CRT = GetDefaultModuleCRT ();
        }
        else
                CRT = GetDefaultModuleCRT ();
 
        const char * crtAttr = CRT.c_str ();
-       if ( crtAttr == NULL || _stricmp ( crtAttr, "none" ) == 0 )
+       if ( crtAttr == NULL || stricmp ( crtAttr, "none" ) == 0 )
                dynamicCRT = false;
-       else if ( _stricmp ( crtAttr, "libc" ) == 0 )
+       else if ( stricmp ( crtAttr, "libc" ) == 0 )
                dynamicCRT = false;
-       else if ( _stricmp ( crtAttr, "msvcrt" ) == 0 )
+       else if ( stricmp ( crtAttr, "msvcrt" ) == 0 )
                dynamicCRT = true;
-       else if ( _stricmp ( crtAttr, "libcntpr" ) == 0 )
+       else if ( stricmp ( crtAttr, "libcntpr" ) == 0 )
                dynamicCRT = false;
-       else if ( _stricmp ( crtAttr, "ntdll" ) == 0 )
+       else if ( stricmp ( crtAttr, "ntdll" ) == 0 )
                dynamicCRT = true;
-       else if ( _stricmp ( crtAttr, "static" ) == 0 )
+       else if ( stricmp ( crtAttr, "static" ) == 0 )
                dynamicCRT = false;
-       else if ( _stricmp ( crtAttr, "dll" ) == 0 )
+       else if ( stricmp ( crtAttr, "dll" ) == 0 )
                dynamicCRT = true;
        else
        {
@@ -454,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;
 
@@ -524,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 )
@@ -601,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 );
@@ -611,9 +648,9 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                const XMLAttribute* att = e.GetAttribute ( "first", false );
                if ( att != NULL )
                {
-                       if ( !_stricmp ( att->value.c_str(), "true" ) )
+                       if ( !stricmp ( att->value.c_str(), "true" ) )
                                first = true;
-                       else if ( _stricmp ( att->value.c_str(), "false" ) )
+                       else if ( stricmp ( att->value.c_str(), "false" ) )
                        {
                                throw XMLInvalidBuildFileException (
                                        e.location,
@@ -628,11 +665,11 @@ Module::ProcessXMLSubElement ( const XMLElement& e,
                {
                        // check for c++ file
                        string ext = GetExtension ( e.value );
-                       if ( !_stricmp ( ext.c_str(), ".cpp" ) )
+                       if ( !stricmp ( ext.c_str(), ".cpp" ) )
                                cplusplus = true;
-                       else if ( !_stricmp ( ext.c_str(), ".cc" ) )
+                       else if ( !stricmp ( ext.c_str(), ".cc" ) )
                                cplusplus = true;
-                       else if ( !_stricmp ( ext.c_str(), ".cxx" ) )
+                       else if ( !stricmp ( ext.c_str(), ".cxx" ) )
                                cplusplus = true;
                }
                File* pFile = new File ( directory,
@@ -673,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;
        }
@@ -704,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 );
@@ -738,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" )
@@ -870,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 (
@@ -877,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;
@@ -925,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" )
@@ -941,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" )
@@ -977,8 +1024,6 @@ Module::GetTargetDirectoryTree () const
                case BootProgram:
                case Iso:
                case LiveIso:
-               case IsoRegTest:
-               case LiveIsoRegTest:
                case ElfExecutable:
                case Cabinet:
                        return OutputDirectory;
@@ -991,6 +1036,7 @@ Module::GetTargetDirectoryTree () const
                case RpcProxy:
                case Alias:
                case IdlHeader:
+               case IdlInterface:
                case MessageHeader:
                        return IntermediateDirectory;
                case TypeDontCare:
@@ -1039,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:
@@ -1068,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:
@@ -1086,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:
@@ -1104,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:
@@ -1156,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:
@@ -1212,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:
@@ -1269,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:
@@ -1316,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;
@@ -1376,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
 {
@@ -1387,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,
@@ -1438,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 )
        {
@@ -1462,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 )
        {
@@ -1705,9 +1768,7 @@ bool
 Bootsector::IsSupportedModuleType ( ModuleType type )
 {
        if ( type == Iso ||
-            type == LiveIso ||
-            type == IsoRegTest ||
-                type == LiveIsoRegTest )
+            type == LiveIso )
        {
                return true;
        }
@@ -1773,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)
 {
@@ -1823,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 )
@@ -1845,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" ));
+
 }
 
 
@@ -1867,9 +1931,9 @@ Property::Property ( const XMLElement& node_,
        if ( att != NULL )
        {
                const char* p = att->value.c_str();
-               if ( !_stricmp ( p, "true" ) || !_stricmp ( p, "yes" ) )
+               if ( !stricmp ( p, "true" ) || !stricmp ( p, "yes" ) )
                        isInternal = true;
-               else if ( !_stricmp ( p, "false" ) || !_stricmp ( p, "no" ) )
+               else if ( !stricmp ( p, "false" ) || !stricmp ( p, "no" ) )
                        isInternal = false;
                else
                {