Example #1
0
// PopulateStringHelper
//------------------------------------------------------------------------------
bool Function::PopulateStringHelper( const BFFIterator & iter, const Meta_Path * pathMD, const Meta_File * fileMD, const BFFVariable * variable, const AString & string, Array< AString > & outStrings ) const
{
	// Full paths to files can support aliases
	if ( fileMD && ( !fileMD->IsRelative() ) )
	{
		// Is it an Alias?
		Node * node = FBuild::Get().GetDependencyGraph().FindNode( string );
		if ( node && ( node->GetType() == Node::ALIAS_NODE ) )
		{
			AliasNode * aliasNode = node->CastTo< AliasNode >();
			for ( const auto& aliasedNode : aliasNode->GetAliasedNodes() )
			{
				if ( !PopulateStringHelper( iter, pathMD, fileMD, variable, aliasedNode.GetNode()->GetName(), outStrings ) )
				{
					return false; // PopulateStringHelper will have emitted an error
				}
			}
			return true;
		}

		// Not an alias - fall through to normal handling
	}

	AStackString<> stringToFix( string );
	if ( !PopulatePathAndFileHelper( iter, pathMD, fileMD, variable->GetName(), stringToFix ) )
	{
		return false; // PopulatePathAndFileHelper will have emitted an error
	}
	outStrings.Append( stringToFix );
	return true;
}
// GetCompilerNode
//------------------------------------------------------------------------------
bool FunctionObjectList::GetCompilerNode( const BFFIterator & iter, const AString & compiler, CompilerNode * & compilerNode ) const
{
	NodeGraph & ng = FBuild::Get().GetDependencyGraph();
	Node * cn = ng.FindNode( compiler );
	compilerNode = nullptr;
	if ( cn != nullptr )
	{
		if ( cn->GetType() == Node::ALIAS_NODE )
		{
			AliasNode * an = cn->CastTo< AliasNode >();
			cn = an->GetAliasedNodes()[ 0 ].GetNode();
		}
		if ( cn->GetType() != Node::COMPILER_NODE )
		{
			Error::Error_1102_UnexpectedType( iter, this, "Compiler", cn->GetName(), cn->GetType(), Node::COMPILER_NODE );
			return false;
		}
		compilerNode = cn->CastTo< CompilerNode >();
	}
	else
	{
		// create a compiler node - don't allow distribution
		// (only explicitly defined compiler nodes can be distributed)
#ifdef USE_NODE_REFLECTION
		compilerNode = ng.CreateCompilerNode( compiler );
        VERIFY( compilerNode->GetReflectionInfoV()->SetProperty( compilerNode, "AllowDistribution", false ) );
#else
		const bool allowDistribution = false;
		compilerNode = ng.CreateCompilerNode( compiler, Dependencies( 0, false ), allowDistribution );
#endif
	}

	return true;
}
Example #3
0
// GetSourceNodes
//------------------------------------------------------------------------------
bool FunctionCopy::GetSourceNodes( const BFFIterator & iter, Node * node, Array< Node * > & nodes ) const
{
    if ( node->GetType() == Node::ALIAS_NODE )
    {
        // resolve aliases to real nodes
        AliasNode * aliasNode = node->CastTo< AliasNode >();
        const Dependencies & aliasedNodes = aliasNode->GetAliasedNodes();
        const Dependency * const end = aliasedNodes.End();
        for ( const Dependency * it = aliasedNodes.Begin(); it != end; ++it )
        {
            if ( !GetSourceNodes( iter, it->GetNode(), nodes ) )
            {
                return false;
            }
        }
        return true;
    }
    else if ( node->IsAFile() )
    {
        // anything that results in a file is ok
        nodes.Append( node );
        return true;
    }

    // something we don't know how to handle
    Error::Error_1005_UnsupportedNodeType( iter, this, ".Source", node->GetName(), node->GetType() );
    return false;
}
Example #4
0
// GetCompilerNode
//------------------------------------------------------------------------------
bool FunctionObjectList::GetCompilerNode( NodeGraph & nodeGraph, const BFFIterator & iter, const AString & compiler, CompilerNode * & compilerNode ) const
{
    Node * cn = nodeGraph.FindNode( compiler );
    compilerNode = nullptr;
    if ( cn != nullptr )
    {
        if ( cn->GetType() == Node::ALIAS_NODE )
        {
            AliasNode * an = cn->CastTo< AliasNode >();
            cn = an->GetAliasedNodes()[ 0 ].GetNode();
        }
        if ( cn->GetType() != Node::COMPILER_NODE )
        {
            Error::Error_1102_UnexpectedType( iter, this, "Compiler", cn->GetName(), cn->GetType(), Node::COMPILER_NODE );
            return false;
        }
        compilerNode = cn->CastTo< CompilerNode >();
    }
    else
    {
        // create a compiler node - don't allow distribution
        // (only explicitly defined compiler nodes can be distributed)
        AStackString<> compilerClean;
        NodeGraph::CleanPath( compiler, compilerClean );
        compilerNode = nodeGraph.CreateCompilerNode( compilerClean );
        VERIFY( compilerNode->GetReflectionInfoV()->SetProperty( compilerNode, "AllowDistribution", false ) );
    }

    return true;
}
Example #5
0
// Commit
//------------------------------------------------------------------------------
/*virtual*/ bool FunctionAlias::Commit( NodeGraph & nodeGraph, const BFFIterator & funcStartIter ) const
{
    if ( nodeGraph.FindNode( m_AliasForFunction ) )
    {
        Error::Error_1100_AlreadyDefined( funcStartIter, this, m_AliasForFunction );
        return false;
    }
    AliasNode * aliasNode = nodeGraph.CreateAliasNode( m_AliasForFunction );

    if ( !PopulateProperties( nodeGraph, funcStartIter, aliasNode ) )
    {
        return false;
    }

    return aliasNode->Initialize( nodeGraph, funcStartIter, this );
}
Example #6
0
// Commit
//------------------------------------------------------------------------------
/*virtual*/ bool FunctionAlias::Commit( const BFFIterator & funcStartIter ) const
{
	NodeGraph & ng = FBuild::Get().GetDependencyGraph();
	if ( ng.FindNode( m_AliasForFunction ) )
	{
		Error::Error_1100_AlreadyDefined( funcStartIter, this, m_AliasForFunction );
		return false;
	}
	AliasNode * aliasNode = ng.CreateAliasNode( m_AliasForFunction );

	if ( !PopulateProperties( funcStartIter, aliasNode ) )
	{
		return false;
	}

	return aliasNode->Initialize( funcStartIter, this );
}
Example #7
0
// Load
//------------------------------------------------------------------------------
/*static*/ Node * AliasNode::Load( IOStream & stream )
{
#ifdef USE_NODE_REFLECTION
	NODE_LOAD( AStackString<>, name );

	NodeGraph & ng = FBuild::Get().GetDependencyGraph();
	AliasNode * an = ng.CreateAliasNode( name );

	if ( an->Deserialize( stream ) == false )
    {
		return nullptr;
	}
	return an;
#else
	NODE_LOAD( AStackString<>, name );
	NODE_LOAD_DEPS( 0, targets );

	NodeGraph & ng = FBuild::Get().GetDependencyGraph();
	return ng.CreateAliasNode( name, targets );
#endif
}
Example #8
0
// GetNodeListRecurse
//------------------------------------------------------------------------------
bool Function::GetNodeListRecurse( const BFFIterator & iter, const char * name, Dependencies & nodes, const AString & nodeName,
								   bool allowCopyDirNodes, bool allowUnityNodes, bool allowRemoveDirNodes ) const
{
	NodeGraph & ng = FBuild::Get().GetDependencyGraph();

	// get node
	Node * n = ng.FindNode( nodeName );
	if ( n == nullptr )
	{
		// not found - create a new file node
		n = ng.CreateFileNode( nodeName );
		nodes.Append( Dependency( n ) );
		return true;
	}

	// found - is it a file?
	if ( n->IsAFile() )
	{
		// found file - just use as is
		nodes.Append( Dependency( n ) );
		return true;
	}

	// found - is it an ObjectList?
	if ( n->GetType() == Node::OBJECT_LIST_NODE )
	{
		// use as-is
		nodes.Append( Dependency( n ) );
		return true;
	}

	// extra types
	if ( allowCopyDirNodes )
	{
		// found - is it an ObjectList?
		if ( n->GetType() == Node::COPY_DIR_NODE )
		{
			// use as-is
			nodes.Append( Dependency( n ) );
			return true;
		}
	}
	if ( allowRemoveDirNodes )
	{
		// found - is it a RemoveDirNode?
		if ( n->GetType() == Node::REMOVE_DIR_NODE )
		{
			// use as-is
			nodes.Append( Dependency( n ) );
			return true;
		}
	}
	if ( allowUnityNodes )
	{
		// found - is it an ObjectList?
		if ( n->GetType() == Node::UNITY_NODE )
		{
			// use as-is
			nodes.Append( Dependency( n ) );
			return true;
		}
	}

	// found - is it a group?
	if ( n->GetType() == Node::ALIAS_NODE )
	{
		AliasNode * an = n->CastTo< AliasNode >();
		const Dependencies & aNodes = an->GetAliasedNodes();
		for ( const Dependency * it = aNodes.Begin(); it != aNodes.End(); ++it )
		{
			// TODO:C by passing as string we'll be looking up again for no reason
			const AString & subName = it->GetNode()->GetName();

			if ( !GetNodeListRecurse( iter, name, nodes, subName, allowCopyDirNodes, allowUnityNodes, allowRemoveDirNodes ) )
			{
				return false;
			}
		}
		return true;
	}

	// don't know how to handle this type of node
	Error::Error_1005_UnsupportedNodeType( iter, this, name, n->GetName(), n->GetType() );
	return false;
}
Example #9
0
// DependOnNode
//------------------------------------------------------------------------------
/*static*/ bool LinkerNode::DependOnNode( const BFFIterator & iter,
                                          const Function * function,
                                          Node * node,
                                          Dependencies & nodes )
{
    ASSERT( node );

    // a previously declared library?
    if ( node->GetType() == Node::LIBRARY_NODE )
    {
        // can link directly to it
        nodes.Append( Dependency( node ) );
        return true;
    }

    // a previously declared object list?
    if ( node->GetType() == Node::OBJECT_LIST_NODE )
    {
        // can link directly to it
        nodes.Append( Dependency( node ) );
        return true;
    }

    // a dll?
    if ( node->GetType() == Node::DLL_NODE )
    {
        // TODO:B Depend on import lib
        nodes.Append( Dependency( node, true ) ); // NOTE: Weak dependency
        return true;
    }

    // a previously declared external file?
    if ( node->GetType() == Node::FILE_NODE )
    {
        // can link directy against it
        nodes.Append( Dependency( node ) );
        return true;
    }

    // a file copy?
    if ( node->GetType() == Node::COPY_FILE_NODE )
    {
        // depend on copy - will use input at build time
        nodes.Append( Dependency( node ) );
        return true;
    }

    // an external executable?
    if ( node->GetType() == Node::EXEC_NODE )
    {
        // depend on ndoe - will use exe output at build time
        nodes.Append( Dependency( node ) );
        return true;
    }

    // a group (alias)?
    if ( node->GetType() == Node::ALIAS_NODE )
    {
        // handle all targets in alias
        AliasNode * an = node->CastTo< AliasNode >();
        const Dependencies & aliasNodeList = an->GetAliasedNodes();
        const Dependencies::Iter end = aliasNodeList.End();
        for ( Dependencies::Iter it = aliasNodeList.Begin();
              it != end;
              ++it )
        {
            if ( DependOnNode( iter, function, it->GetNode(), nodes ) == false )
            {
                return false; // something went wrong lower down
            }
        }
        return true; // all nodes in group handled ok
    }

    // don't know how to handle this type of node
    Error::Error_1005_UnsupportedNodeType( iter, function, "Libraries", node->GetName(), node->GetType() );
    return false;
}