Model::Node* Project::navigateTo(Model::Node* source, QString path) { QString symbol = extractFrontSymbol(path); Model::Node* found = nullptr; // Is the target symbol name the module's name if (isAncestorOf(source) && symbol == symbolName()) found = this; if (!found) found = projects()->findFirstSymbolDefinition(symbol); if (!found) found = libraries()->findFirstSymbolDefinition(symbol); if (!found) found = modules()->findFirstSymbolDefinition(symbol); if (!found) found = classes()->findFirstSymbolDefinition(symbol); if (!found) return ExtendableNode::navigateTo(source, path); QString rest = extractSecondaryPath(path); if (!rest.isEmpty()) return found->navigateTo(this, rest); else return found; }
// Initialize //------------------------------------------------------------------------------ bool LinkerNode::Initialize( NodeGraph & nodeGraph, const BFFIterator & iter, const Function * function ) { // .PreBuildDependencies if ( !InitializePreBuildDependencies( nodeGraph, iter, function, m_PreBuildDependencyNames ) ) { return false; // InitializePreBuildDependencies will have emitted an error } // Get linker exe Node * linkerExeNode = nullptr; if ( !function->GetFileNode( nodeGraph, iter, linkerExeNode, ".Linker" ) ) // TODO:B Use m_Linker property { return false; // GetFileNode will have emitted an error } m_Flags = DetermineFlags( m_LinkerType, m_Linker, m_LinkerOptions ); // Check for Import Library override if ( ( m_Flags & LinkerNode::LINK_FLAG_MSVC ) != 0 ) { GetImportLibName( m_LinkerOptions, m_ImportLibName ); } // Check input/output args for Linker { bool hasInputToken = ( m_LinkerOptions.Find( "%1" ) || m_LinkerOptions.Find( "\"%1\"" ) ); if ( hasInputToken == false ) { Error::Error_1106_MissingRequiredToken( iter, function, ".LinkerOptions", "%1" ); return false; } bool hasOutputToken = ( m_LinkerOptions.Find( "%2" ) || m_LinkerOptions.Find( "\"%2\"" ) ); if ( hasOutputToken == false ) { Error::Error_1106_MissingRequiredToken( iter, function, ".LinkerOptions", "%2" ); return false; } } // Standard library dependencies Dependencies libraries( 64, true ); for ( const AString & library : m_Libraries ) { if ( DependOnNode( nodeGraph, iter, function, library, libraries ) == false ) { return false; // DependOnNode will have emitted an error } } // Assembly Resources Dependencies assemblyResources( 32, true ); if ( !function->GetNodeList( nodeGraph, iter, ".LinkerAssemblyResources", assemblyResources, false ) ) // TODO:B Use m_LinkerAssemblyResources directly { return false; // GetNodeList will have emitted error } // get inputs not passed through 'LibraryNodes' (i.e. directly specified on the cmd line) Dependencies otherLibraryNodes( 64, true ); if ( ( m_Flags & ( LinkerNode::LINK_FLAG_MSVC | LinkerNode::LINK_FLAG_GCC | LinkerNode::LINK_FLAG_SNC | LinkerNode::LINK_FLAG_ORBIS_LD | LinkerNode::LINK_FLAG_GREENHILLS_ELXR | LinkerNode::LINK_FLAG_CODEWARRIOR_LD ) ) != 0 ) { const bool msvcStyle = ( ( m_Flags & LinkerNode::LINK_FLAG_MSVC ) == LinkerNode::LINK_FLAG_MSVC ); if ( !GetOtherLibraries( nodeGraph, iter, function, m_LinkerOptions, otherLibraryNodes, msvcStyle ) ) { return false; // will have emitted error } } // Handle LinkerStampExe Node * linkerStampExeNode = nullptr; if ( m_LinkerStampExe.IsEmpty() == false ) { if ( !function->GetFileNode( nodeGraph, iter, linkerStampExeNode, ".LinkerStampExe" ) ) // TODO: Use m_LinkerStampExe property { return false; // GetFileNode will have emitted an error } } // Store all dependencies m_StaticDependencies.SetCapacity( 1 + // for .Linker libraries.GetSize() + assemblyResources.GetSize() + otherLibraryNodes.GetSize() + ( linkerStampExeNode ? 1 : 0 ) ); m_StaticDependencies.Append( Dependency( linkerExeNode ) ); m_StaticDependencies.Append( libraries ); m_AssemblyResourcesStartIndex = (uint32_t)m_StaticDependencies.GetSize(); m_StaticDependencies.Append( assemblyResources ); m_AssemblyResourcesNum = (uint32_t)assemblyResources.GetSize(); m_StaticDependencies.Append( otherLibraryNodes ); if ( linkerStampExeNode ) { m_StaticDependencies.Append( Dependency( linkerStampExeNode ) ); } return true; }
// 在developMode 目录下创建Makefile文件 bool CBuilder::buildMakefile() { QByteArray block; // 编译器设置 block += "CC := " + cprojectObject->cc() + "\n"; block += "CCC := " + cprojectObject->ccc() + "\n"; block += "STD := " + cprojectObject->std() + "\n"; block += "PLATFORM := " + cprojectObject->platform() + "\n"; block += "MAIN_SOURCES :=\n"; block += "C_SOURCES :=\n"; block += "CPP_SOURCES :=\n"; block += "CC_SOURCES :=\n"; block += "CXX_SOURCES :=\n"; block += "C++_SOURCES :=\n"; block += "MAIN_OBJECTS :=\n"; block += "OBJECTS :=\n"; block += "DEPENDS :=\n"; block += "RM := rm -rf\n"; // FLAGS block += "FLAGS := "; if (developMode == "Debug") block += " -g"; block += " " + cprojectObject->warnings(); block += " $(STD) $(PLATFROM)"; if (!cprojectObject->otherFlag().isEmpty()) block += " " + cprojectObject->otherFlag(); block += "\n"; // Includes block += "INCLUDES :=" + includes() + "\n"; // Libraries block += "LIBS :=" + libraries() + "\n"; // include subdir.mk if (!subdirs.isEmpty()) { QStringList::const_iterator constIterator = subdirs.constBegin(); QStringList::const_iterator endIterator = subdirs.constEnd(); while (constIterator != endIterator) { if ((*constIterator).isEmpty()) block += "-include ./subdir.mk\n"; else block += "-include ./" + *constIterator + "/subdir.mk\n"; ++constIterator; } block += "\n"; } // TARGET block += "TARGETS := "; QStringList executeFiles = cprojectObject->executeFiles(); block += executeFiles.join(" ") + "\n\n"; // 这里加入了../project.small使得当用户没有修改程序但是修改了项目配置时, 也会重新编译, 以下的../project.small同理 block += "all: $(TARGETS) ../project.small\n\n"; QString compiler = QString(); if (cprojectObject->type() == "C") compiler = "$(CC)"; else compiler = "$(CCC)"; QStringList::const_iterator constIterator = executeFiles.constBegin(); QStringList::const_iterator endIterator = executeFiles.constEnd(); while (constIterator != endIterator) { block += (*constIterator) + ": "; QStringList dependObjects = cprojectObject->executeFileDepend(*constIterator); QString mode = dependObjects.at(0); dependObjects.removeFirst(); if (mode == "only") { block += dependObjects.at(0) + " ../project.small\n"; block += "\t" + compiler + " " + dependObjects.at(0) + " $(FLAGS) $(LIBS) $(INCLUDES) -o $@\n"; } else if (mode == "part") { block += dependObjects.join(" ") + " ../project.small\n"; block += "\t" + compiler + " " + dependObjects.join(" ") + " $(FLAGS) $(LIBS) $(INCLUDES) -o $@\n"; } else if (mode == "all" && dependObjects.count() > 0) { block += dependObjects.at(0) + " $(OBJECTS) ../project.small\n"; block += "\t" + compiler + " " + dependObjects.at(0) + " $(FLAGS) $(LIBS) $(INCLUDES) -o $@\n"; } else if (mode == "all" && dependObjects.count() <= 0) { block += " $(OBJECTS) ../project.small\n"; block += "\t" + compiler + " $(OBJECTS) $(FLAGS) $(LIBS) $(INCLUDES) -o $@\n"; } ++constIterator; } block += "\n\n"; // clean block += "clean:\n"; block += "\t-$(RM) $(MAIN_OBJECTS) $(OBJECTS) $(DEPENDS) $(TARGETS)\n"; block += "\t-@echo ' '\n\n"; // .PHONY block += ".PHONY: clean\n\n"; QFile file(rootPath + "/" + developMode + "/Makefile"); if (!file.open(QFile::WriteOnly | QFile::Text)) { buildErrorStr += "无法写入\"" + rootPath + "/" + developMode + "/Makefile" + "\"\n"; buildErrorStr += file.errorString() + "\n"; return false; } file.write(block); file.close(); return true; } // buildMakefile