📄 modulehandler.cpp
字号:
/*
* Copyright (C) 2005 Casper S. Hornstrup
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
*/
#include "../../pch.h"
#include <assert.h>
#include "../../rbuild.h"
#include "mingw.h"
#include "modulehandler.h"
using std::string;
using std::vector;
#define CLEAN_FILE(f) clean_files.push_back ( f );
static string ros_temp = "$(TEMPORARY)";
MingwBackend*
MingwModuleHandler::backend = NULL;
FILE*
MingwModuleHandler::fMakefile = NULL;
string
PrefixFilename (
const string& filename,
const string& prefix )
{
if ( !prefix.length() )
return filename;
string out;
const char* pfilename = filename.c_str();
const char* p1 = strrchr ( pfilename, '/' );
const char* p2 = strrchr ( pfilename, '\\' );
if ( p1 || p2 )
{
if ( p2 > p1 )
p1 = p2;
out += string(pfilename,p1-pfilename) + cSep;
pfilename = p1 + 1;
}
out += prefix + pfilename;
return out;
}
string
GetTargetMacro ( const Module& module, bool with_dollar )
{
string s ( module.name );
strupr ( &s[0] );
s += "_TARGET";
if ( with_dollar )
return ssprintf ( "$(%s)", s.c_str() );
return s;
}
MingwModuleHandler::MingwModuleHandler (
const Module& module_ )
: module(module_)
{
use_pch = false;
}
MingwModuleHandler::~MingwModuleHandler()
{
}
/*static*/ void
MingwModuleHandler::SetBackend ( MingwBackend* backend_ )
{
backend = backend_;
}
/*static*/ void
MingwModuleHandler::SetMakefile ( FILE* f )
{
fMakefile = f;
}
void
MingwModuleHandler::EnablePreCompiledHeaderSupport ()
{
use_pch = true;
}
/* static*/ string
MingwModuleHandler::RemoveVariables ( string path)
{
size_t i = path.find ( '$' );
if ( i != string::npos )
{
size_t j = path.find ( ')', i );
if ( j != string::npos )
{
if ( j + 2 < path.length () && path[j + 1] == cSep )
return path.substr ( j + 2);
else
return path.substr ( j + 1);
}
}
return path;
}
/*static*/ string
MingwModuleHandler::PassThruCacheDirectory (
const string &file,
Directory* directoryTree )
{
string directory ( GetDirectory ( RemoveVariables ( file ) ) );
if ( directoryTree == NULL )
return file;
string generatedFilesDirectory = backend->AddDirectoryTarget ( directory,
directoryTree );
if ( directory.find ( generatedFilesDirectory ) != string::npos )
/* This path already includes the generated files directory variable */
return file;
else
{
if ( file == "" )
return generatedFilesDirectory;
return generatedFilesDirectory + sSep + file;
}
}
/*static*/ string
MingwModuleHandler::PassThruCacheDirectory (const FileLocation* fileLocation )
{
return PassThruCacheDirectory ( fileLocation->filename,
fileLocation->directory );
}
/*static*/ Directory*
MingwModuleHandler::GetTargetDirectoryTree (
const Module& module )
{
if ( module.type == StaticLibrary )
return backend->intermediateDirectory;
return backend->outputDirectory;
}
/*static*/ string
MingwModuleHandler::GetTargetFilename (
const Module& module,
string_list* pclean_files )
{
string target = PassThruCacheDirectory (
NormalizeFilename ( module.GetPath () ),
GetTargetDirectoryTree ( module ) );
if ( pclean_files )
{
string_list& clean_files = *pclean_files;
CLEAN_FILE ( target );
}
return target;
}
/*static*/ string
MingwModuleHandler::GetImportLibraryFilename (
const Module& module,
string_list* pclean_files )
{
string target = PassThruCacheDirectory (
NormalizeFilename ( module.GetDependencyPath () ),
backend->intermediateDirectory );
if ( pclean_files )
{
string_list& clean_files = *pclean_files;
CLEAN_FILE ( target );
}
return target;
}
/*static*/ MingwModuleHandler*
MingwModuleHandler::InstanciateHandler (
const Module& module,
MingwBackend* backend )
{
MingwModuleHandler* handler;
switch ( module.type )
{
case BuildTool:
handler = new MingwBuildToolModuleHandler ( module );
break;
case StaticLibrary:
handler = new MingwStaticLibraryModuleHandler ( module );
break;
case ObjectLibrary:
handler = new MingwObjectLibraryModuleHandler ( module );
break;
case Kernel:
handler = new MingwKernelModuleHandler ( module );
break;
case NativeCUI:
handler = new MingwNativeCUIModuleHandler ( module );
break;
case Win32CUI:
handler = new MingwWin32CUIModuleHandler ( module );
break;
case Win32SCR:
case Win32GUI:
handler = new MingwWin32GUIModuleHandler ( module );
break;
case KernelModeDLL:
handler = new MingwKernelModeDLLModuleHandler ( module );
break;
case NativeDLL:
handler = new MingwNativeDLLModuleHandler ( module );
break;
case Win32DLL:
handler = new MingwWin32DLLModuleHandler ( module );
break;
case Win32OCX:
handler = new MingwWin32OCXModuleHandler ( module );
break;
case KernelModeDriver:
handler = new MingwKernelModeDriverModuleHandler ( module );
break;
case BootLoader:
handler = new MingwBootLoaderModuleHandler ( module );
break;
case BootSector:
handler = new MingwBootSectorModuleHandler ( module );
break;
case BootProgram:
handler = new MingwBootProgramModuleHandler ( module );
break;
case Iso:
handler = new MingwIsoModuleHandler ( module );
break;
case LiveIso:
handler = new MingwLiveIsoModuleHandler ( module );
break;
case IsoRegTest:
handler = new MingwIsoModuleHandler ( module );
break;
case LiveIsoRegTest:
handler = new MingwLiveIsoModuleHandler ( module );
break;
case Test:
handler = new MingwTestModuleHandler ( module );
break;
case RpcServer:
handler = new MingwRpcServerModuleHandler ( module );
break;
case RpcClient:
handler = new MingwRpcClientModuleHandler ( module );
break;
case Alias:
handler = new MingwAliasModuleHandler ( module );
break;
case IdlHeader:
handler = new MingwIdlHeaderModuleHandler ( module );
break;
case EmbeddedTypeLib:
handler = new MingwEmbeddedTypeLibModuleHandler ( module );
break;
default:
throw UnknownModuleTypeException (
module.node.location,
module.type );
break;
}
return handler;
}
string
MingwModuleHandler::GetWorkingDirectory () const
{
return ".";
}
string
MingwModuleHandler::GetBasename ( const string& filename ) const
{
size_t index = filename.find_last_of ( '.' );
if ( index != string::npos )
return filename.substr ( 0, index );
return "";
}
FileLocation*
MingwModuleHandler::GetActualSourceFilename (
const FileLocation* fileLocation ) const
{
string filename = fileLocation->filename;
string extension = GetExtension ( filename );
if ( extension == ".spec" || extension == ".SPEC" )
{
string basename = GetBasename ( filename );
PassThruCacheDirectory ( NormalizeFilename ( basename + ".stubs.c" ),
backend->intermediateDirectory );
return new FileLocation ( backend->intermediateDirectory, NormalizeFilename ( basename + ".stubs.c" ) );
}
else if ( extension == ".idl" || extension == ".IDL" )
{
string basename = GetBasename ( filename );
string newname;
if ( module.type == RpcServer )
{
newname = basename + "_s.c";
PassThruCacheDirectory ( NormalizeFilename ( newname ),
backend->intermediateDirectory );
return new FileLocation ( backend->intermediateDirectory, NormalizeFilename ( newname ) );
}
else if ( module.type == RpcClient )
{
newname = basename + "_c.c";
PassThruCacheDirectory ( NormalizeFilename ( newname ),
backend->intermediateDirectory );
return new FileLocation ( backend->intermediateDirectory, NormalizeFilename ( newname ) );
}
else if ( module.type == IdlHeader )
{
newname = basename + ".h";
PassThruCacheDirectory ( NormalizeFilename ( newname ),
backend->intermediateDirectory );
return new FileLocation ( fileLocation->directory, filename );
}
else
{
return new FileLocation ( fileLocation->directory, filename );
}
}
else
return new FileLocation ( fileLocation->directory, filename );
}
string
MingwModuleHandler::GetExtraDependencies (
const string& filename ) const
{
string extension = GetExtension ( filename );
if ( extension == ".idl" || extension == ".IDL" )
{
string basename = GetBasename ( filename );
if ( (module.type == RpcServer) || (module.type == RpcClient) )
return GetRpcServerHeaderFilename ( basename ) + " " + GetRpcClientHeaderFilename ( basename );
else if ( module.type == IdlHeader )
return GetIdlHeaderFilename ( basename );
else
return "";
}
else
return "";
}
string
MingwModuleHandler::GetCompilationUnitDependencies (
const CompilationUnit& compilationUnit ) const
{
if ( compilationUnit.files.size () <= 1 )
return "";
vector<string> sourceFiles;
for ( size_t i = 0; i < compilationUnit.files.size (); i++ )
{
File& file = *compilationUnit.files[i];
sourceFiles.push_back ( NormalizeFilename ( file.name ) );
}
return v2s ( sourceFiles, 10 );
}
string
MingwModuleHandler::GetModuleArchiveFilename () const
{
if ( module.type == StaticLibrary )
return GetTargetFilename ( module, NULL );
return PassThruCacheDirectory ( ReplaceExtension (
NormalizeFilename ( module.GetPath () ),
".temp.a" ),
backend->intermediateDirectory );
}
bool
MingwModuleHandler::IsGeneratedFile ( const File& file ) const
{
string extension = GetExtension ( file.name );
return ( extension == ".spec" || extension == ".SPEC" );
}
/*static*/ bool
MingwModuleHandler::ReferenceObjects (
const Module& module )
{
if ( module.type == ObjectLibrary )
return true;
if ( module.type == RpcServer )
return true;
if ( module.type == RpcClient )
return true;
if ( module.type == IdlHeader )
return true;
return false;
}
string
MingwModuleHandler::GetImportLibraryDependency (
const Module& importedModule )
{
string dep;
if ( ReferenceObjects ( importedModule ) )
dep = GetTargetMacro ( importedModule );
else
dep = GetImportLibraryFilename ( importedModule, NULL );
return dep;
}
void
MingwModuleHandler::GetTargets ( const Module& dependencyModule,
string_list& targets )
{
if ( dependencyModule.invocations.size () > 0 )
{
for ( size_t i = 0; i < dependencyModule.invocations.size (); i++ )
{
Invoke& invoke = *dependencyModule.invocations[i];
invoke.GetTargets ( targets );
}
}
else
targets.push_back ( GetImportLibraryDependency ( dependencyModule ) );
}
void
MingwModuleHandler::GetModuleDependencies (
string_list& dependencies )
{
size_t iend = module.dependencies.size ();
if ( iend == 0 )
return;
for ( size_t i = 0; i < iend; i++ )
{
const Dependency& dependency = *module.dependencies[i];
const Module& dependencyModule = *dependency.dependencyModule;
GetTargets ( dependencyModule,
dependencies );
}
GetDefinitionDependencies ( dependencies );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -