예제 #1
0
 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
예제 #2
0
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
예제 #3
0
    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
예제 #4
0
 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
예제 #5
0
 def GetFilesIndex(self):
     ds = Globals.DirSaver()
     os.chdir(self.dirName)
     return self.GetFilesIndexOfNodes(self.rootNode)
예제 #6
0
    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