def __init__(self, log: Log, sdkConfigTemplatePath: str) -> None:
     super().__init__()
     self.TemplateStartBat = IOUtil.TryReadFile(IOUtil.Join(sdkConfigTemplatePath, "Template_WinStartProject.txt"))
     self.TemplateBuildBat = IOUtil.TryReadFile(IOUtil.Join(sdkConfigTemplatePath, "Template_WinBuildProject.txt"))
     self.TemplateRunBat = IOUtil.TryReadFile(IOUtil.Join(sdkConfigTemplatePath, "Template_WinRunProject.txt"))
     templateSnippetErrorCheck = IOUtil.TryReadFile(IOUtil.Join(sdkConfigTemplatePath, "TemplateSnippet_WinBatErrorCheck.txt"))
     self.TemplateSnippetErrorCheck = "" if templateSnippetErrorCheck is None else templateSnippetErrorCheck
    def __init__(self, config: Config, packages: List[Package],
                 platformName: str, activeGenerator: GeneratorBase) -> None:
        super(GeneratorGitIgnore, self).__init__()

        headerLibTemplate = IOUtil.TryReadFile(
            IOUtil.Join(config.SDKConfigTemplatePath,
                        "Template_gitignore_headerlib.txt"))
        libTemplate = IOUtil.TryReadFile(
            IOUtil.Join(config.SDKConfigTemplatePath,
                        "Template_gitignore_lib.txt"))
        exeTemplate = IOUtil.TryReadFile(
            IOUtil.Join(config.SDKConfigTemplatePath,
                        "Template_gitignore_exe.txt"))

        generatorIgnoreDict = activeGenerator.GetPackageGitIgnoreDict()

        for package in packages:
            if package.Type == PackageType.Library:
                self.__GenerateLibraryBuildFile(config, package, platformName,
                                                libTemplate,
                                                generatorIgnoreDict)
            elif package.Type == PackageType.Executable:
                self.__GenerateLibraryBuildFile(config, package, platformName,
                                                exeTemplate,
                                                generatorIgnoreDict)
            elif package.Type == PackageType.HeaderLibrary:
                self.__GenerateLibraryBuildFile(config, package, platformName,
                                                headerLibTemplate,
                                                generatorIgnoreDict)
Beispiel #3
0
 def __TryDoReadFile(self, absoluteTemplatePath: str, overrideDirName: str, filename: str) -> Optional[str]:
     """
     Try to read a file from the override path, if its not found there try to read it from the base path,
     return None if not found
     """
     templateFilename = IOUtil.Join(absoluteTemplatePath, "{0}/{1}".format(overrideDirName, filename))
     res = IOUtil.TryReadFile(templateFilename)
     if res is None:
         templateFilename = IOUtil.Join(absoluteTemplatePath, filename)
         res = IOUtil.TryReadFile(templateFilename)
     return res
Beispiel #4
0
 def __DoReadFile(self, absoluteTemplatePath: str, overrideDirName: str, filename: str) -> str:
     templateFilename = IOUtil.Join(absoluteTemplatePath, "{0}/{1}".format(overrideDirName, filename))
     res = IOUtil.TryReadFile(templateFilename)
     if res is None:
         templateFilename = IOUtil.Join(absoluteTemplatePath, filename)
         res = IOUtil.ReadFile(templateFilename)
     return res
Beispiel #5
0
    def TryLoad(log: Log,
                cacheFilename: str) -> Optional['BuildConfigureCache']:
        try:
            strJson = IOUtil.TryReadFile(cacheFilename)
            if strJson is None:
                return None
            jsonDict = json.loads(strJson)
            if jsonDict["Version"] != 1:
                raise Exception("Unsupported version")

            jsonFileHashDict = jsonDict["FileHashDict"]
            finalDict = {}  # type: Dict[str,str]
            for key, value in jsonFileHashDict.items():
                if not isinstance(key, str) or not isinstance(value, str):
                    raise Exception("json decode failed")
                finalDict[key] = value

            finalCommandList = []  # type: List[str]
            jsonCommandList = jsonDict["CommandList"]
            for value in jsonCommandList:
                if not isinstance(value, str):
                    raise Exception("json decode failed")
                finalCommandList.append(value)

            return BuildConfigureCache(finalDict, finalCommandList)
        except:
            log.DoPrintWarning(
                "Failed to decode cache file '{0}'".format(cacheFilename))
            return None
Beispiel #6
0
    def ProcessInstallDirClaim(log: Log,
                               targetPath: str,
                               sdkPath: str,
                               forceClaimInstallArea: bool, 
                               installAreaInfoPath: str) -> None:
        filePath = IOUtil.Join(targetPath, installAreaInfoPath)

        # Beware that this method to claim a area is in no way secure
        # It will basically only be useful after the claim file has been created
        # So we start with a possible race condition, but any future attempts to use the directory
        # will catch that multiple repos are trying to reuse the same install area
        fileContent = IOUtil.TryReadFile(filePath)
        if fileContent is None:
            log.LogPrint("Install area '{0}' is unclaimed, claiming it".format(targetPath))
            BuildAreaInfoFileUtil.ClaimInstallDirNow(log, targetPath, filePath, sdkPath, forceClaimInstallArea)
            return

        jsonBuildInfoDict = json.loads(fileContent)
        if not BuildAreaInfoFile.IsDictValid(jsonBuildInfoDict):
            if not forceClaimInstallArea:
                raise Exception("Install area '{0}' contained an invalid file '{1}', did you try to run concurrent builds using the same install directory or did it get corrupted? Delete the file to allow the build to continue or use --ForceClaimInstallArea to do so automatically. You could also set up a readonly cache area to reuse between repos see the documentation for more info.".format(targetPath, filePath))
            log.DoPrintWarning("Install area '{0}' contained an invalid file '{1}', as --ForceClaimInstallArea was specified it was overwritten and '{2}' now controls it".format(targetPath, filePath, sdkPath))
            jsonBuildInfoDict = BuildAreaInfoFileUtil.ClaimInstallDirNow(log, targetPath, filePath, sdkPath, forceClaimInstallArea, logWarning=False)

        buildAreaInfoFile = BuildAreaInfoFile(jsonBuildInfoDict)
        if buildAreaInfoFile.SDKPath != sdkPath:
            if not forceClaimInstallArea:
                raise Exception("The Install area at '{0}' is already claimed by the sdk at '{1}' so the sdk at '{2}' can not reuse it as it could give concurrency issues if multiple builds execute at the same time. If you are sure that you are not doing concurrent builds and you just want to use the area for a new SDK you can force claim it with --ForceClaimInstallArea. You could also set up a readonly cache area to reuse between repos see the documentation for more info.".format(targetPath, buildAreaInfoFile.SDKPath, sdkPath))
            log.DoPrintWarning("The Install area at '{0}' was already claimed by the sdk at '{1}' but '{2}' took control of it as --ForceClaimInstallArea was specified.".format(targetPath, buildAreaInfoFile.SDKPath, sdkPath))
            jsonBuildInfoDict = BuildAreaInfoFileUtil.ClaimInstallDirNow(log, targetPath, filePath, sdkPath, forceClaimInstallArea, logWarning=False)
Beispiel #7
0
    def TryPatch(jsonFilePath: str, buildPlatformType: BuildPlatformType,
                 executable: str, currentWorkingDirectory: str) -> bool:
        strJson = IOUtil.TryReadFile(jsonFilePath)
        if strJson is not None:
            strJson = VSCodeLaunchJsonUtil.__StripComments(strJson)
            jsonDict = json.loads(strJson)
        else:
            jsonDict = {}
            jsonDict[LocalStrings.Version] = LocalStrings.VersionStr

        if LocalStrings.Version not in jsonDict or jsonDict[
                LocalStrings.Version] != LocalStrings.VersionStr:
            return False

        configurationDictList = jsonDict[
            LocalStrings.
            Configurations] if LocalStrings.Configurations in jsonDict else []

        # Patch/Create windows configuration
        launchWindowsFound = buildPlatformType != BuildPlatformType.Windows  # this basically ensures we only generate the windows launch on windows
        launchUbuntuFound = buildPlatformType == BuildPlatformType.Windows  # this basically ensures we only generate the ubuntu launch on non windows platforms
        for configDict in configurationDictList:
            if configDict[LocalStrings.
                          ConfigKeyName] == LocalStrings.WindowsLaunchName:
                VSCodeLaunchJsonUtil.__PacthConfigurationDict(
                    configDict, executable, currentWorkingDirectory, False)
                launchWindowsFound = True
            elif configDict[LocalStrings.
                            ConfigKeyName] == LocalStrings.UbuntuLaunchName:
                VSCodeLaunchJsonUtil.__PacthConfigurationDict(
                    configDict, executable, currentWorkingDirectory, True)
                launchUbuntuFound = True
        if not launchWindowsFound:
            configDict = VSCodeLaunchJsonUtil.__CreateWindowsLaunchConfigurationDict(
            )
            VSCodeLaunchJsonUtil.__PacthConfigurationDict(
                configDict, executable, currentWorkingDirectory, False)
            configurationDictList.append(configDict)
        if not launchUbuntuFound:
            configDict = VSCodeLaunchJsonUtil.__CreateUbuntuLaunchConfigurationDict(
            )
            VSCodeLaunchJsonUtil.__PacthConfigurationDict(
                configDict, executable, currentWorkingDirectory, True)
            configurationDictList.append(configDict)

        jsonDict[LocalStrings.Configurations] = configurationDictList

        jsonText = json.dumps(jsonDict,
                              ensure_ascii=False,
                              sort_keys=True,
                              indent=4)
        IOUtil.WriteFileIfChanged(jsonFilePath, jsonText)
        return True
    def __GenerateLibraryBuildFile(
            self, config: Config, package: Package, platformName: str,
            template: Optional[str],
            generatorIgnoreDict: Dict[str, Set[str]]) -> None:
        if template is None or package.AbsolutePath is None:
            return
        template = template.replace("##PROJECT_NAME##", package.Name)
        targetFilePath = IOUtil.Join(package.AbsolutePath, ".gitignore")

        targetContent = IOUtil.TryReadFile(targetFilePath)

        targetArray = self.__ToArray(targetContent)
        templateArray = self.__ToArray(template)

        targetArray = [_f for _f in targetArray if _f]
        templateArray = [_f for _f in templateArray if _f]

        # Add the missing dependencies
        for entry in templateArray:
            if not entry in targetArray:
                targetArray.append(entry)

        # Allow each generator to add things that should be ignored
        if package.Name in generatorIgnoreDict:
            ignoreList = generatorIgnoreDict[package.Name]
            for entry in ignoreList:
                if not entry in targetArray:
                    targetArray.append(entry)

        # Remove stuff
        #remove = []
        #legacyName = package.ShortName + '.'
        #for entry in targetArray:
        #    if entry.startswith(legacyName) or entry == package.ShortName:
        #        remove.append(entry)
        #for entry in remove:
        #    targetArray.remove(entry)

        #if 'GNUmakefile_yocto' in targetArray:
        #    targetArray.remove('GNUmakefile_yocto')

        # sort the content to ensure that there are minimal changes
        targetArray.sort()

        finalContent = "\n".join(targetArray) + '\n'

        if not config.DisableWrite:
            IOUtil.WriteFileIfChanged(targetFilePath, finalContent)
def TryLoad(log: Log, path: str) -> Optional[AppInfo]:
    content = IOUtil.TryReadFile(path)
    if content is None:
        return None

    try:
        jsonDict = json.loads(content)

        platformName = jsonDict[JsonRootKey.PlatformName]  # type: str
        resolvedPackageList = __ParseResolvedPackageList(
            log, jsonDict[JsonRootKey.ResolvedPackageList])
        return AppInfo(platformName, resolvedPackageList)
    except Exception:
        log.LogPrintWarning(
            "Failed to parse json content in file: '{0}'".format(path))
        raise
    def TryLoadBuildInformation(log: Log, sourcePackage: Package,
                                path: str) -> Optional[JsonDictType]:
        try:
            if not PackageRecipeUtil.HasBuildPipeline(sourcePackage):
                return None

            sourceRecipe = sourcePackage.ResolvedDirectExperimentalRecipe
            if sourceRecipe is None or sourceRecipe.ResolvedInstallLocation is None:
                raise Exception("Invalid recipe")

            # Generally this should not be called if there is no pipeline

            srcFilePath = IOUtil.Join(
                sourceRecipe.ResolvedInstallLocation.ResolvedPath, path)

            fileContent = IOUtil.TryReadFile(srcFilePath)
            if fileContent is None:
                log.LogPrint(
                    "Package build information for package {0} not found in the expected file '{1}'"
                    .format(sourcePackage.Name, srcFilePath))
                return None

            jsonBuildInfoDict = json.loads(fileContent)
            if not BuildInfoFile.IsDictValid(jsonBuildInfoDict):
                log.LogPrint(
                    "Package build information for package {0} found in file '{1}' is invalid"
                    .format(sourcePackage.Name, srcFilePath))
                return None

            # Decode the complex element to a object of the right type
            jsonBuildInfoDict[
                BuildInfoFileElements.
                ContentState] = BuildInfoComplexJsonDecoder.DecodeJson(
                    jsonBuildInfoDict[BuildInfoFileElements.ContentState])
            if BuildInfoFileElements.SourceState in jsonBuildInfoDict:
                jsonBuildInfoDict[
                    BuildInfoFileElements.
                    SourceState] = BuildInfoComplexJsonDecoder.DecodeJson(
                        jsonBuildInfoDict[BuildInfoFileElements.SourceState])

            return cast(JsonDictType, jsonBuildInfoDict)
        except Exception as ex:
            log.LogPrintWarning(
                "TryLoadBuildInformation failed for package '{0}' with {1}".
                format(sourcePackage.Name, ex))
            return None
Beispiel #11
0
    def __init__(self, log: Log, sourceFilename: str,
                 pathVariables: PathVariables) -> None:
        super(ContentBuildCommandFile, self).__init__()

        self.__RootElement = "ContentBuilder"
        self.__VersionElement = "Version"
        self.__CurrentVersion = "1"
        self.Commands = []  # type: List[Command]

        fileContent = IOUtil.TryReadFile(sourceFilename)
        if fileContent is not None:
            log.LogPrint("Parsing command file '{0}'".format(sourceFilename))
            jsonContent = self.__ParseJsonFile(fileContent)
            self.__ValidateJsonContent(jsonContent, sourceFilename)
            self.Commands = self.__ParseContent(
                log, jsonContent[self.__RootElement], sourceFilename,
                pathVariables)
Beispiel #12
0
    def TryLoad(log: Log,
                cacheFilename: str) -> Optional['BuildConfigureCache']:
        try:
            strJson = IOUtil.TryReadFile(cacheFilename)
            if strJson is None:
                return None
            jsonDict = json.loads(strJson)
            if jsonDict["Version"] != BuildConfigureCache.CURRENT_VERSION:
                raise Exception("Unsupported version")

            jsonEnvironmentDict = jsonDict["EnvironmentDict"]
            finalEnvironmentDict = {}  # type: Dict[str,str]
            for key, value in jsonEnvironmentDict.items():
                if not isinstance(key, str) or not isinstance(value, str):
                    raise Exception("json decode failed")
                finalEnvironmentDict[key] = value

            jsonFileHashDict = jsonDict["FileHashDict"]
            finalDict = {}  # type: Dict[str,str]
            for key, value in jsonFileHashDict.items():
                if not isinstance(key, str) or not isinstance(value, str):
                    raise Exception("json decode failed")
                finalDict[key] = value

            finalCommandList = []  # type: List[str]
            jsonCommandList = jsonDict["CommandList"]
            for value in jsonCommandList:
                if not isinstance(value, str):
                    raise Exception("json decode failed")
                finalCommandList.append(value)

            platformName = jsonDict["PlatformName"]  # type: str
            fslBuildVersion = jsonDict["FslBuildVersion"]  # type: str
            allowFindPackage = jsonDict["AllowFindPackage"]  # type: str
            return BuildConfigureCache(finalEnvironmentDict, finalDict,
                                       finalCommandList, platformName,
                                       fslBuildVersion, allowFindPackage)
        except:
            log.DoPrintWarning(
                "Failed to decode cache file '{0}'".format(cacheFilename))
            return None
Beispiel #13
0
    def TryLoad(log: Log,
                cacheFilename: str) -> Optional['JsonProjectIdCache']:
        try:
            strJson = IOUtil.TryReadFile(cacheFilename)
            if strJson is None:
                return None
            jsonDict = json.loads(strJson)
            if jsonDict["Version"] != JsonProjectIdCache.CURRENT_VERSION:
                raise Exception("Unsupported version")

            jsonProjectIdDict = jsonDict["ProjectIdDict"]
            finalDict = {}  # type: Dict[str,str]

            for key, value in jsonProjectIdDict.items():
                if not isinstance(key, str) or not isinstance(value, str):
                    raise Exception("json decode failed")
                finalDict[key] = value

            return JsonProjectIdCache(finalDict)
        except:
            log.DoPrintWarning(
                "Failed to decode cache file '{0}'".format(cacheFilename))
            return None
Beispiel #14
0
    def Patch(log: Log, jsonFilePath: str,
              cmakeInfo: OpenProjectCMakeInfo) -> None:
        strJson = IOUtil.TryReadFile(jsonFilePath)
        if strJson is not None:
            jsonDict = json.loads(strJson)
        else:
            jsonDict = {}

        if log.Verbosity >= 1:
            log.LogPrint("- cmake.buildDirectory: '{0}' ".format(
                cmakeInfo.BuildDirectory))
            log.LogPrint("- cmake.configureArgs: '{0}' ".format(
                cmakeInfo.ConfigureArgs))
            log.LogPrint("- cmake.sourceDirectory: '{0}' ".format(
                cmakeInfo.SourceDirectory))
            log.LogPrint("- cmake.generator: '{0}' ".format(
                cmakeInfo.Generator))
            log.LogPrint("- cmake.installPrefix: '{0}' ".format(
                cmakeInfo.InstallPrefix))
            if cmakeInfo.BuildThreads is not None:
                log.LogPrint("- cmake.parallelJobs: '{0}' ".format(
                    cmakeInfo.BuildThreads))

        # Running build config command
        # cmake
        # -DCODE_COVERAGE=OFF
        # -DCMAKE_PREFIX_PATH=E:/Work/DFLibs/Windows/VS2019_X64_3_1/glm-0.9.8.5
        # -G "Visual Studio 16 2019"
        # -A x64
        # E:/Work/DemoFramework/build/Windows/VS2019_X64/_fsl_cmake/DF'

        # Specify the build directory (The root directory where CMakeCache.txt will be generated).
        jsonDict["cmake.buildDirectory"] = cmakeInfo.BuildDirectory

        # Directory where the root CMakeLists.txt will be found.
        jsonDict["cmake.sourceDirectory"] = cmakeInfo.SourceDirectory

        # Set to a string to override CMake Tools preferred generator logic. If this is set, CMake will unconditionally use it as the -G CMake generator command line argument.
        jsonDict["cmake.generator"] = cmakeInfo.Generator

        # By specifying a number, you can define how many jobs are run in parallel during the build.
        if cmakeInfo.BuildThreads is not None:
            jsonDict["cmake.parallelJobs"] = cmakeInfo.BuildThreads

        #If specified, sets a value for CMAKE_INSTALL_PREFIX when running CMake configure. If not, no value will be passed
        if len(cmakeInfo.InstallPrefix) > 0:
            jsonDict["cmake.installPrefix"] = cmakeInfo.InstallPrefix

        # Arguments to CMake that will be passed during the configure process.
        # WARNING: Always prefer to use cmake.configureSettings or CMake Variants. Never pass -D arguments using this setting.
        if len(cmakeInfo.ConfigureArgs) > 0:
            jsonDict["cmake.configureArgs"] = cmakeInfo.ConfigureArgs

        # cmake.configureSettings
        # An object containing key : value pairs, which will be passed onto CMake when configuring. It does the same thing as passing -DVAR_NAME=ON via cmake.configureArgs.
        if len(cmakeInfo.ConfigureSettingsDict) > 0:
            jsonDict[
                "cmake.configureSettings"] = cmakeInfo.ConfigureSettingsDict

        # cmake.buildArgs
        # An array of additional arguments to pass to cmake --build.

        # cmake.buildToolArg
        # An array of additional arguments to pass to the underlying build tool.

        jsonText = json.dumps(jsonDict,
                              ensure_ascii=False,
                              sort_keys=True,
                              indent=4)
        IOUtil.WriteFileIfChanged(jsonFilePath, jsonText)
Beispiel #15
0
def TryLoadTextFileAsLines(path: str) -> Optional[List[str]]:
    result = IOUtil.TryReadFile(path)
    if result is None:
        return None
    lines = result.split('\n')
    return lines
    def __init__(self, log: Log, template: XmlNewVSProjectTemplateFile,
                subDirectory: str, vsVersion: int, useLinuxTools: bool,
                customization: XmlNewVSProjectTemplateCustomizationFile) -> None:
        super().__init__()
        strVSPath = template.Path

        strTemplatePath = IOUtil.Join(strVSPath, subDirectory)
        strTemplateSolutionPath = IOUtil.Join(strTemplatePath, "Template_sln")
        strTemplateProjectPath = IOUtil.Join(strTemplatePath, "Template_{0}".format(template.Template.ProjectExtension))
        strTemplateFilterPath = IOUtil.Join(strTemplatePath, "Template_filters")

        strTemplateNuGetPackageConfigPath = IOUtil.Join(strTemplatePath, "Template_packages_config")

        self.BuildOutputLocation = customization.BuildOutput.Location
        self.FilterExtension = "vcxproj.filters"
        self.SolutionExtension = "sln"
        self.ProjectExtension = template.Template.ProjectExtension

        self.TemplateFileRecordManager = TemplateFileRecordManager(strTemplatePath)

        nuGetPackageConfig = IOUtil.TryReadFile(IOUtil.Join(strTemplateNuGetPackageConfigPath, "Master.txt"))
        self.NuGetPackageConfig = NuGetPackageConfigSnippets(log, strTemplateNuGetPackageConfigPath, nuGetPackageConfig) if nuGetPackageConfig is not None else None

        self.TemplateSLN = IOUtil.ReadFile(IOUtil.Join(strTemplateSolutionPath, "Master.txt"))
        self.SLNAddProject = IOUtil.ReadFile(IOUtil.Join(strTemplateSolutionPath, "AddProject.txt"))
        self.SLNSnippet1 = IOUtil.ReadFile(IOUtil.Join(strTemplateSolutionPath, "Snippet1.txt"))
        self.SLNSnippet2 = IOUtil.ReadFile(IOUtil.Join(strTemplateSolutionPath, "Snippet2.txt"))
        self.Master = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "Master.txt"))
        self.VariantProjectConfiguration = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantProjectConfiguration.txt"))
        self.ProjectReferences = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "ProjectReferences.txt"))
        self.ProjectReferences_1 = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "ProjectReferences_1.txt"))
        self.PackageReferences = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "PackageReferences.txt"))
        self.PackageReferences_1 = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "PackageReferences_1.txt"))
        self.AssemblyReferenceSimple = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "AssemblyReferenceSimple.txt"))
        self.AssemblyReferenceComplex = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "AssemblyReferenceComplex.txt"))
        self.AssemblyReferenceComplex_Private = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "AssemblyReferenceComplex_Private.txt"))
        self.AddHeaderFile = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "AddHeaderFile.txt"))
        self.AddSourceFile = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "AddSourceFile.txt"))
        self.AddNatvisFile = self.SafeReadFile(IOUtil.Join(strTemplateProjectPath, "AddNatvisFile.txt"), "")
        self.VariantConfiguration = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantConfiguration.txt"))
        self.VariantPropertySheets = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantPropertySheets.txt"))
        self.VariantPropertyGroups = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantPropertyGroups.txt"))
        self.VariantCompilerSettings = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantCompilerSettings.txt"))
        self.VariantCompilerSettings_1 = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantCompilerSettings_1.txt"))
        self.VariantCompilerSettings_2 = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "VariantCompilerSettings_2.txt"))
        self.WindowsTargetPlatformVersion = self.SafeReadFile(IOUtil.Join(strTemplateProjectPath, "WindowsTargetPlatformVersion.txt"), "")
        externalFileToOutput = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "ExternalFileToOutput.txt"))
        self.ExternalFileToOutput = "" if externalFileToOutput is None else externalFileToOutput
        copyFileToFolders = IOUtil.TryReadFile(IOUtil.Join(strTemplateProjectPath, "CopyFileToFolders.txt"))
        self.CopyFileToFolders = ""
        self.CopyFileToFoldersCopyConditions = ""
        if copyFileToFolders is not None:
            self.CopyFileToFolders = copyFileToFolders
            self.CopyFileToFoldersCopyConditions = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "CopyFileToFolders_CopyConditions.txt"))
        self.Snippet9 = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "CustomBuildFiles.txt"))
        self.Snippet9_1 = IOUtil.ReadFile(IOUtil.Join(strTemplateProjectPath, "CustomBuildFiles_1.txt"))

        # Filter master file
        self.FilterMaster = IOUtil.TryReadFile(IOUtil.Join(strTemplateFilterPath, "master.txt"))
        self.FilterItemGroup = self.SafeReadFile(IOUtil.Join(strTemplateFilterPath, "itemgroup.txt"), "")
        self.FilterItemGroupNatvis = self.SafeReadFile(IOUtil.Join(strTemplateFilterPath, "itemgroup_natvis.txt"), "")
        self.FilterItemHeader = self.SafeReadFile(IOUtil.Join(strTemplateFilterPath, "item_header.txt"), "")
        self.FilterItemShader = self.SafeReadFile(IOUtil.Join(strTemplateFilterPath, "item_shader.txt"), "")
        self.FilterItemSource = self.SafeReadFile(IOUtil.Join(strTemplateFilterPath, "item_source.txt"), "")

        self.DebugOptimizations = {}  # type: Dict[int, TemplateOptimizationSetting]
        self.__LoadOptimization(self.DebugOptimizations, OptimizationType.Disabled, strVSPath, "DEBUG", "disabled")
        self.__LoadOptimization(self.DebugOptimizations, OptimizationType.Default, strVSPath, "DEBUG", "disabled")
        self.__LoadOptimization(self.DebugOptimizations, OptimizationType.Full, strVSPath, "DEBUG", "full")

        snippet3FileName = IOUtil.Join(strTemplateSolutionPath, "Snippet3.txt")
        if IOUtil.IsFile(snippet3FileName):
            self.SLNSnippet3 = IOUtil.ReadFile(snippet3FileName)
            self.SLNSnippet4 = IOUtil.ReadFile(IOUtil.Join(strTemplateSolutionPath, "Snippet4.txt"))
            self.SLNSnippet4_1 = IOUtil.ReadFile(IOUtil.Join(strTemplateSolutionPath, "Snippet4_1.txt"))
        else:
            self.SLNSnippet3 = ""
            self.SLNSnippet4 = ""
            self.SLNSnippet4_1 = ""
 def SafeReadFile(self, filename: str, defaultContent: str) -> str:
     content = IOUtil.TryReadFile(filename)
     return content if content is not None else defaultContent