// GetInputFiles //------------------------------------------------------------------------------ void ObjectListNode::GetInputFiles( Args & fullArgs, const AString & pre, const AString & post ) const { for ( Dependencies::Iter i = m_DynamicDependencies.Begin(); i != m_DynamicDependencies.End(); i++ ) { const Node * n = i->GetNode(); // handle pch files - get path to object if ( n->GetType() == Node::OBJECT_NODE ) { // handle pch files - get path to matching object const ObjectNode * on = n->CastTo< ObjectNode >(); if ( on->IsCreatingPCH() ) { if ( on->IsMSVC() ) { fullArgs += pre; fullArgs += on->GetName(); fullArgs += on->GetObjExtension(); fullArgs += post; fullArgs.AddDelimiter(); continue; } else { // Clang/GCC/SNC don't have an object to link for a pch continue; } } } // extract objects from additional lists if ( n->GetType() == Node::OBJECT_LIST_NODE ) { ASSERT( GetType() == Node::LIBRARY_NODE ); // should only be possible for a LibraryNode // insert all the objects in the object list ObjectListNode * oln = n->CastTo< ObjectListNode >(); oln->GetInputFiles( fullArgs, pre, post ); continue; } // normal object fullArgs += pre; fullArgs += n->GetName(); fullArgs += post; fullArgs.AddDelimiter(); } }
// GetAssemblyResourceFiles //------------------------------------------------------------------------------ void LinkerNode::GetAssemblyResourceFiles( Args & fullArgs, const AString & pre, const AString & post ) const { const Dependency * start = m_StaticDependencies.Begin() + m_AssemblyResourcesStartIndex; const Dependency * end = start + m_AssemblyResourcesNum; for ( const Dependency * i = start; i != end; ++i ) { Node * n( i->GetNode() ); if ( n->GetType() == Node::OBJECT_LIST_NODE ) { ObjectListNode * oln = n->CastTo< ObjectListNode >(); oln->GetInputFiles( fullArgs, pre, post, false ); continue; } if ( n->GetType() == Node::LIBRARY_NODE ) { LibraryNode * ln = n->CastTo< LibraryNode >(); ln->GetInputFiles( fullArgs, pre, post, false ); continue; } fullArgs += pre; fullArgs += n->GetName(); fullArgs += post; fullArgs.AddDelimiter(); } }
// GetAssemblyResourceFiles //------------------------------------------------------------------------------ void LinkerNode::GetAssemblyResourceFiles( Args & fullArgs, const AString & pre, const AString & post ) const { const Dependency * const end = m_AssemblyResources.End(); for ( Dependencies::Iter i = m_AssemblyResources.Begin(); i != end; i++ ) { Node * n( i->GetNode() ); if ( n->GetType() == Node::OBJECT_LIST_NODE ) { ObjectListNode * oln = n->CastTo< ObjectListNode >(); oln->GetInputFiles( fullArgs, pre, post ); continue; } if ( n->GetType() == Node::LIBRARY_NODE ) { LibraryNode * ln = n->CastTo< LibraryNode >(); ln->GetInputFiles( fullArgs, pre, post ); continue; } fullArgs += pre; fullArgs += n->GetName(); fullArgs += post; fullArgs.AddDelimiter(); } }
// GetInputFiles //------------------------------------------------------------------------------ void LinkerNode::GetInputFiles( Node * n, Args & fullArgs, const AString & pre, const AString & post ) const { if ( n->GetType() == Node::LIBRARY_NODE ) { const bool linkObjectsInsteadOfLibs = m_LinkerLinkObjects; if ( linkObjectsInsteadOfLibs ) { LibraryNode * ln = n->CastTo< LibraryNode >(); ln->GetInputFiles( fullArgs, pre, post, linkObjectsInsteadOfLibs ); } else { // not building a DLL, so link the lib directly fullArgs += pre; fullArgs += n->GetName(); fullArgs += post; } } else if ( n->GetType() == Node::OBJECT_LIST_NODE ) { const bool linkObjectsInsteadOfLibs = m_LinkerLinkObjects; ObjectListNode * ol = n->CastTo< ObjectListNode >(); ol->GetInputFiles( fullArgs, pre, post, linkObjectsInsteadOfLibs ); } else if ( n->GetType() == Node::DLL_NODE ) { // for a DLL, link to the import library DLLNode * dllNode = n->CastTo< DLLNode >(); AStackString<> importLibName; dllNode->GetImportLibName( importLibName ); fullArgs += pre; fullArgs += importLibName; fullArgs += post; } else if ( n->GetType() == Node::COPY_FILE_NODE ) { CopyFileNode * copyNode = n->CastTo< CopyFileNode >(); Node * srcNode = copyNode->GetSourceNode(); GetInputFiles( srcNode, fullArgs, pre, post ); } else { // link anything else directly fullArgs += pre; fullArgs += n->GetName(); fullArgs += post; } fullArgs.AddDelimiter(); }
// GetInputFiles //------------------------------------------------------------------------------ void CSNode::GetInputFiles( Args & fullArgs, const AString & pre, const AString & post ) const { bool first = true; const Dependency * const end = m_DynamicDependencies.End(); for ( const Dependency * it = m_DynamicDependencies.Begin(); it != end; ++it ) { if ( !first ) { fullArgs.AddDelimiter(); } fullArgs += pre; fullArgs += it->GetNode()->GetName(); fullArgs += post; first = false; } }
// BuildArgs //------------------------------------------------------------------------------ bool LibraryNode::BuildArgs( Args & fullArgs ) const { Array< AString > tokens( 1024, true ); m_LibrarianArgs.Tokenize( tokens ); const AString * const end = tokens.End(); for ( const AString * it = tokens.Begin(); it!=end; ++it ) { const AString & token = *it; if ( token.EndsWith( "%1" ) ) { // handle /Option:%1 -> /Option:A /Option:B /Option:C AStackString<> pre; if ( token.GetLength() > 2 ) { pre.Assign( token.Get(), token.GetEnd() - 2 ); } // concatenate files, unquoted GetInputFiles( fullArgs, pre, AString::GetEmpty() ); } else if ( token.EndsWith( "\"%1\"" ) ) { // handle /Option:"%1" -> /Option:"A" /Option:"B" /Option:"C" AStackString<> pre( token.Get(), token.GetEnd() - 3 ); // 3 instead of 4 to include quote AStackString<> post( "\"" ); // concatenate files, quoted GetInputFiles( fullArgs, pre, post ); } else if ( token.EndsWith( "%2" ) ) { // handle /Option:%2 -> /Option:A if ( token.GetLength() > 2 ) { fullArgs += AStackString<>( token.Get(), token.GetEnd() - 2 ); } fullArgs += m_Name; } else if ( token.EndsWith( "\"%2\"" ) ) { // handle /Option:"%2" -> /Option:"A" AStackString<> pre( token.Get(), token.GetEnd() - 3 ); // 3 instead of 4 to include quote fullArgs += pre; fullArgs += m_Name; fullArgs += '"'; // post } else { fullArgs += token; } fullArgs.AddDelimiter(); } // orbis-ar.exe requires escaped slashes inside response file if ( GetFlag( LIB_FLAG_ORBIS_AR ) ) { fullArgs.SetEscapeSlashesInResponseFile(); } // Handle all the special needs of args if ( fullArgs.Finalize( m_LibrarianPath, GetName(), CanUseResponseFile() ) == false ) { return false; // Finalize will have emitted an error } return true; }
// BuildArgs //------------------------------------------------------------------------------ bool LinkerNode::BuildArgs( Args & fullArgs ) const { PROFILE_FUNCTION // split into tokens Array< AString > tokens( 1024, true ); m_LinkerOptions.Tokenize( tokens ); const AString * const end = tokens.End(); for ( const AString * it = tokens.Begin(); it!=end; ++it ) { const AString & token = *it; // %1 -> InputFiles const char * found = token.Find( "%1" ); if ( found ) { AStackString<> pre( token.Get(), found ); AStackString<> post( found + 2, token.GetEnd() ); GetInputFiles( fullArgs, pre, post ); fullArgs.AddDelimiter(); continue; } // %2 -> OutputFile found = token.Find( "%2" ); if ( found ) { fullArgs += AStackString<>( token.Get(), found ); fullArgs += m_Name; fullArgs += AStackString<>( found + 2, token.GetEnd() ); fullArgs.AddDelimiter(); continue; } // %3 -> AssemblyResources if ( GetFlag( LINK_FLAG_MSVC ) ) { found = token.Find( "%3" ); if ( found ) { AStackString<> pre( token.Get(), found ); AStackString<> post( found + 2, token.GetEnd() ); GetAssemblyResourceFiles( fullArgs, pre, post ); fullArgs.AddDelimiter(); continue; } } // untouched token fullArgs += token; fullArgs.AddDelimiter(); } // orbis-ld.exe requires escaped slashes inside response file if ( GetFlag( LINK_FLAG_ORBIS_LD ) ) { fullArgs.SetEscapeSlashesInResponseFile(); } // Handle all the special needs of args if ( fullArgs.Finalize( m_Linker, GetName(), CanUseResponseFile() ) == false ) { return false; // Finalize will have emitted an error } return true; }
// BuildArgs //------------------------------------------------------------------------------ bool CSNode::BuildArgs( Args & fullArgs ) const { // split into tokens Array< AString > tokens( 1024, true ); m_CompilerArgs.Tokenize( tokens ); AStackString<> quote( "\"" ); const AString * const end = tokens.End(); for ( const AString * it = tokens.Begin(); it!=end; ++it ) { const AString & token = *it; if ( token.EndsWith( "%1" ) ) { // handle /Option:%1 -> /Option:A /Option:B /Option:C AStackString<> pre; if ( token.GetLength() > 2 ) { pre.Assign( token.Get(), token.GetEnd() - 2 ); } // concatenate files, unquoted GetInputFiles( fullArgs, pre, AString::GetEmpty() ); } else if ( token.EndsWith( "\"%1\"" ) ) { // handle /Option:"%1" -> /Option:"A" /Option:"B" /Option:"C" AStackString<> pre( token.Get(), token.GetEnd() - 3 ); // 3 instead of 4 to include quote // concatenate files, quoted GetInputFiles( fullArgs, pre, quote ); } else if ( token.EndsWith( "%2" ) ) { // handle /Option:%2 -> /Option:A if ( token.GetLength() > 2 ) { fullArgs += AStackString<>( token.Get(), token.GetEnd() - 2 ); } fullArgs += m_Name; } else if ( token.EndsWith( "\"%2\"" ) ) { // handle /Option:"%2" -> /Option:"A" AStackString<> pre( token.Get(), token.GetEnd() - 3 ); // 3 instead of 4 to include quote fullArgs += pre; fullArgs += m_Name; fullArgs += '"'; // post } else if ( token.EndsWith( "%3" ) ) { // handle /Option:%3 -> /Option:A,B,C AStackString<> pre( token.Get(), token.GetEnd() - 2 ); fullArgs += pre; // concatenate files, unquoted GetExtraRefs( fullArgs, AString::GetEmpty(), AString::GetEmpty() ); } else if ( token.EndsWith( "\"%3\"" ) ) { // handle /Option:"%3" -> /Option:"A","B","C" AStackString<> pre( token.Get(), token.GetEnd() - 4 ); fullArgs += pre; // concatenate files, quoted GetExtraRefs( fullArgs, quote, quote ); } else { fullArgs += token; } fullArgs.AddDelimiter(); } // Handle all the special needs of args const bool canUseResponseFile( true ); if ( fullArgs.Finalize( m_CompilerPath, GetName(), canUseResponseFile ) == false ) { return false; // Finalize will have emitted an error } return true; }