def __GetPrpOrObjCmd(self, projName, fileName, wspConfName='', t='prp'): wspIns = VLWorkspaceST.Get() wspConfName = wspConfName \ or wspIns.GetBuildMatrix().GetSelectedConfigurationName() self.Exports(projName, wspConfName) projInst = wspIns.FindProjectByName(projName) projBldConfIns = self.GetProjectBuildConfig(projName, wspConfName) cmplName = projBldConfIns.GetCompilerType() cmpl = BuildSettingsST.Get().GetCompilerByName(cmplName) if projBldConfIns.IsCustomBuild(): return '' if not cmpl: # 编译器实例总会可能是空的 return 'echo "%s is not a valid complier!"' ds = Globals.DirSaver() os.chdir(projInst.dirName) if os.path.isabs(fileName): fileName = os.path.relpath(fileName) mkFile = '%s.mk' % projName bwd = projBldConfIns.GetIntermediateDirectory() or '.' # 展开所有 VimLite 内置变量 bwd = Globals.ExpandAllInterVariables(bwd, wspIns, projName, wspConfName) if t == 'prp': # 预处理目标 fn = os.path.splitext(fileName)[0] + cmpl.prpExt else: # 对象目标,用于编译文件 fn = os.path.splitext(fileName)[0] + cmpl.objExt tgt = '%s/%s' % (bwd, fn) cmd = 'cd %s && make -f %s %s ' % (EscStr4MkSh( projInst.dirName), EscStr4MkSh(mkFile), EscStr4MkSh(tgt)) return cmd
def GetTemplateDict(dir): ds = Globals.DirSaver() try: os.chdir(dir) except: return {} templates = {} for dir in os.listdir(dir): projFile = os.path.join(dir, os.path.basename(dir) + '.project') if os.path.isdir(dir) and os.path.isfile(projFile): tmpProj = VLProject(projFile) internalType = tmpProj.GetProjectInternalType() template = {} template['name'] = tmpProj.GetName() template['file'] = tmpProj.GetFileName() template['desc'] = tmpProj.GetDescription() bldConf = tmpProj.GetSettings().GetBuildConfiguration('Debug') template['cmpType'] = bldConf.GetCompilerType() if internalType: if not templates.has_key(internalType): templates[internalType] = [] templates[internalType].append(template) else: if not templates.has_key('Others'): templates['Others'] = [] templates['Others'].append(template) return templates
def IsFileExists(self, fileName): '''find the file under this node. Convert the file path to be relative to the project path''' ds = Globals.DirSaver() os.chdir(self.dirName) # fileName relative to the project path relFileName = os.path.relpath(fileName, self.dirName) files = self.GetAllFiles() for i in files: if Globals.IsWindowsOS(): if os.path.abspath(i).lower() \ == os.path.abspath(relFileName).lower(): return True else: if os.path.abspath(i) == os.path.abspath(relFileName): return True return False
def GetAllFiles(self, absPath=False, projConfName=''): ''' 如果 projConfName 为空,返回结果会包含被忽略的文件,也就是全部文件 如果 projConfName 非空,排除 projConfName 配置指定忽略的文件 NOTE: 暂时只有在构建的时候才需要排除忽略的文件 ''' ignoredFiles = set() if projConfName: settings = self.GetSettings() bldConf = settings.GetBuildConfiguration(projConfName) if bldConf: ignoredFiles = bldConf.ignoredFiles.copy() if absPath: ds = Globals.DirSaver() os.chdir(self.dirName) files = self.GetFilesOfNode(XmlUtils.GetRoot(self.doc), True, '', ignoredFiles) #WSP_PATH_SEP + self.name) else: files = self.GetFilesOfNode(XmlUtils.GetRoot(self.doc), False, '', ignoredFiles) #WSP_PATH_SEP + self.name) return files
def GetFilesIndex(self): ds = Globals.DirSaver() os.chdir(self.dirName) return self.GetFilesIndexOfNodes(self.rootNode)
def GenerateMakefile(self, projName, projConfName, force=False): '''此函数会跳过不必要的 Makefile 创建行为''' wspIns = VLWorkspaceST.Get() projInst = wspIns.FindProjectByName(projName) if not projInst or not projConfName: return False settings = projInst.GetSettings() projBldConfIns = wspIns.GetProjBuildConf(projName, projConfName) if not settings or not projBldConfIns: return False ds = Globals.DirSaver() os.chdir(projInst.dirName) absProjMakefile = os.path.join(projInst.dirName, projName + '.mk') # 如果已存在 makefile,且非强制,且项目文件没有修改,跳过 if not force and not projInst.IsModified() \ and os.path.exists(absProjMakefile): # 添加判断,比较项目文件与 makefile 的时间戳, # 只有 makefile 比项目文件新才跳过 mkModTime = Globals.GetMTime(absProjMakefile) if mkModTime > Globals.GetMTime(projInst.GetFileName()): return True # 无须重建,直接结束 # 自定义构建的处理是不一样的 isCustomBuild = projBldConfIns.IsCustomBuild() #isCustomBuild = True mkdir = 'gmkdir -p' if Globals.IsWindowsOS() else 'mkdir -p' # 重建流程 text = '' text += '##\n' text += '## Auto generated by Builder "%s" of VimLite\n' % self.name text += '## Do not edit this file, any manual changes will be erased\n' text += '##\n' # 输出环境变量 # 必须首先输出, 因为内部变量可能用到了环境变量 text += '\n' text += '##\n' text += '## User defined environment variables\n' text += '##\n' for envVar in EnvVarSettingsST.Get().GetActiveEnvVars(): #text += '%s := %s\n' % (envVar.GetKey(), envVar.GetValue()) text += '%s\n' % (envVar.GetString().replace('=', ':=', 1)) text += '\n' if isCustomBuild: # 自定义构建的处理 text += '## ===== Available Macros =====\n' text += self.CreateAvailableMacros(projInst, projBldConfIns) text += '\n' buildCmds = projBldConfIns.GetCustomBuildCmd() cleanCmds = projBldConfIns.GetCustomCleanCmd() workDir = projBldConfIns.GetCustomBuildWorkingDir() if not workDir: workDir = '.' cdCmd = 'cd $(WorkDir) && ' text += '''\ ## variables MKDIR := %s WorkDir := %s PHONY := all clean DirSanity Build Clean Rebuild ## builtin targets define BuildCommands %s endef define CleanCommands %s endef all: Build clean: Clean DirSanity: \t@$(MKDIR) $(WorkDir) Build: DirSanity \t$(BuildCommands) Clean: DirSanity \t$(CleanCommands) Rebuild: DirSanity \t$(CleanCommands) \t$(BuildCommands) ''' % (mkdir, EscStr4MkSh(workDir), cdCmd + buildCmds, cdCmd + cleanCmds) customTargets = projBldConfIns.GetCustomTargets() customTargetsText = '' for tgt, cmd in customTargets.iteritems(): customTargetsText += 'PHONY += %s\n' % tgt customTargetsText += '%s: DirSanity\n' % tgt customTargetsText += '\t%s\n' % (cdCmd + cmd, ) customTargetsText += '\n' text += customTargetsText text += '.PHONY: $(PHONY)' #### 自定义构建处理完毕 else: # 非自定义构建时的处理 text += self.CreateConfigsVariables(projInst, projBldConfIns) # 如此实现批量添加包含路径即可 text += '# auto\n' # 添加 CCXXFLAGS #text += 'CFLAGS += $(CCXXFLAGS)\n' #text += 'CXXFLAGS += $(CCXXFLAGS)\n' # CPPFLAGS 为 C 和 C++ 编译器共享 text += 'CPPFLAGS += $(foreach Dir,$(CmpIncPaths) $(IncPaths),$(IncPat))\n' # 预定义的宏 text += 'CPPFLAGS += $(foreach Mac,$(Macros),$(MacPat))\n' # 库文件搜索路径 text += 'LDFLAGS += $(foreach Lip,$(CmpLibPaths) $(LibPaths),$(LipPat))\n' # 链接的库 text += 'LDFLAGS += $(foreach Lib,$(Libraries),$(LibPat))\n' text += '\n' text += '# ###\n' # 源文件 text += 'SourceFile = $<\n' # 对象文件 text += 'ObjectFile = $(OutDir)/$(notdir $(basename $(SourceFile)))$(ObjExt)\n' # 输出的依赖文件 text += 'DependFile = $(OutDir)/$(notdir $(basename $(SourceFile)))$(DepExt)\n' # 输出的预处理文件 text += 'PrePrcFile = $(OutDir)/$(notdir $(basename $(SourceFile)))$(PrpExt)\n' text += '\n' t1, fileRules = self.CreateFileTargets(projInst, projBldConfIns) text += t1 preBldCmd = '' postBldCmd = '' preCmds = [ i for i in projBldConfIns.GetPreBuildCommands() if i.enabled ] if preCmds: preBldCmd += '\t@echo ===== Pre Build Commands Start... =====\n' preBldCmd += '\n'.join(['\t%s' % i.command for i in preCmds]) + '\n' preBldCmd += '\t@echo ===== Pre Build Commands Done. =====\n' postCmds = [ i for i in projBldConfIns.GetPostBuildCommands() if i.enabled ] if postCmds: postBldCmd += '\t@echo ===== Post Build Commands Start... =====\n' postBldCmd += '\n'.join(['\t%s' % i.command for i in postCmds]) + '\n' postBldCmd += '\t@echo ===== Post Build Commands Done. =====\n' text += 'MKDIR = %s\n' % (mkdir, ) # DirSanity -> PreBuild -> $(Objects) -> $(OutputFile) -> PostBuild # DirSanity 放到 all 的依赖列表的第一位,会跑得比较快,测试表明可用 # NOTE: 如果作为 PreBuild 的依赖,则可能 $(Objects): PreBuild 会导致 # 依赖查找,而先于 DirSanity 执行,最终会造成找不到 c 依赖文件而终止 # $(Objects): | PreBuild 的 PreBuild 仅为了顺序, # 不会影响 $(Objects) 的重建 text += '''\ PHONY = all clean PreBuild Building PostBuild DirSanity # ===== Targets ===== all: DirSanity PostBuild PostBuild: Building %s Building: $(OutputFile) $(OutputFile): $(Objects) ifeq ($(ProjectType),app) \t$(LinkCmd) endif ifeq ($(ProjectType),so) \t$(SoGenCmd) endif ifeq ($(ProjectType),ar) \t$(ArGenCmd) endif $(Objects): | PreBuild PreBuild: %s DirSanity: \t@$(MKDIR) $(OutDir) \t@$(MKDIR) $(dir $(OutputFile)) clean: \t$(RM) $(PrePrcs) \t$(RM) $(Depends) \t$(RM) $(Objects) \t$(RM) $(OutputFile) ''' % (postBldCmd, preBldCmd) text += fileRules # NOTE: include 的时候,如果文件不存在,会在本 Makefile 中查找以这个 # 文件名为目标的规则,如果这个规则需要一些中间目录的话,就会出错, # 因为这个查找是先于任何规则的,即使 Makefile 的第一个规则就是创建 # 中间目录也没有用 #text += '#-include $(Depends)\n' #text += '-include $(OutDir)/*$(DepExt)\n' # 用这句才行,真不懂 text += '''\ ifeq ($(shell test -d $(OutDir) && echo yes || echo no),yes) -include $(Depends) endif ''' text += '\n' text += '.PHONY: $(PHONY)\n' #### 内建构建处理完毕 #absProjMakefile = 'test.mk' # 写到文件 tmpf = Globals.TempFile() try: f = open(tmpf, "wb") f.write(text) f.close() shutil.move(tmpf, absProjMakefile) except: os.remove(tmpf) print '%s: save failed!' % absProjMakefile raise projInst.SetModified(False) #return text return True