def __GenerateCMakeFile(self, config: Config, package: Package,
                            platformName: str,
                            template: CMakeGeneratorUtil.CodeTemplateCMake,
                            toolProjectContextsDict: Dict[
                                ProjectId, ToolConfigProjectContext],
                            useExtendedProjectHack: bool) -> None:
        if package.Type == PackageType.TopLevel:
            raise Exception("Usage error")
        #if package.IsVirtual:
        #    return
        if package.AbsolutePath is None or package.ResolvedBuildPath is None:
            raise Exception("Invalid package")

        packageName = CMakeGeneratorUtil.GetPackageName(package)

        aliasPackageName = CMakeGeneratorUtil.GetAliasName(
            packageName, package.ProjectContext.ProjectName)

        targetIncludeDirectories = CMakeGeneratorUtil.BuildTargetIncludeDirectories(
            config, package, template.PackageTargetIncludeDirectories,
            template.PackageTargetIncludeDirEntry,
            template.PackageTargetIncludeDirVirtualEntry,
            CMakeGeneratorUtil.CMakePathType.LocalRelative)

        publicIncludeFiles = self.__Join(
            package.ResolvedBuildPublicIncludeFiles)
        privateIncludeFiles = self.__Join(
            package.ResolvedBuildPrivateIncludeFiles)
        includeFiles = self.__Join(package.ResolvedBuildAllIncludeFiles)
        sourceFiles = self.__Join(package.ResolvedBuildSourceFiles)

        linkLibrariesDirectDependencies = CMakeGeneratorUtil.BuildTargetLinkLibrariesForDirectDependencies(
            config, package, template.PackageDependencyTargetLinkLibraries,
            template.PackageDependencyFindPackage)
        directDefinitions = CMakeGeneratorUtil.BuildDirectDefinitions(
            config, package,
            template.PackageDependencyTargetCompileDefinitions)
        findDirectExternalDependencies = CMakeGeneratorUtil.BuildFindDirectExternalDependencies(
            config, package, template.PackageDependencyFindPackage)
        installInstructions = CMakeGeneratorUtil.BuildInstallInstructions(
            config, package, template.PackageInstall,
            template.PackageInstallTargets, template.PackageInstallHeaders,
            template.PackageInstallContent, template.PackageInstallDLL,
            template.PackageInstallAppInfo)
        targetCompileFeatures = CMakeGeneratorUtil.BuildCompileFeatures(
            config, package, template.SnippetTargetCompileFeaturesDefault,
            template.SnippetTargetCompileFeaturesInterface)
        targetCompileOptions = CMakeGeneratorUtil.BuildCompileOptions(
            config, package, template.SnippetTargetCompileOptionsDefault)
        targetFileCopy = CMakeGeneratorUtil.BuildFileCopy(
            config, package, template.PackageTargetCopyFile,
            template.PackageTargetCopyFilePath)

        cacheVariants = CMakeGeneratorUtil.GetCacheVariants(
            package, template.SnippetCacheVariant)

        contentInBinaryDirectory = True

        packageContentBuilder = CMakeGeneratorUtil.GetContentBuilder(
            config, package, platformName, template.PackageContentBuilder,
            contentInBinaryDirectory)
        #packageContentBuilderOutputFiles = CMakeGeneratorUtil.GetContentBuilderOutputFiles(config, package, contentInBinaryDirectory)

        packageContentSection = CMakeGeneratorUtil.GetContentSection(
            config, package, platformName, template.PackageContent,
            template.PackageContentFile, contentInBinaryDirectory)
        #packageContentSectionOutputFiles = CMakeGeneratorUtil.GetContentSectionOutputFiles(config, package, contentInBinaryDirectory)

        packageContentDep = CMakeGeneratorUtil.GetContentDepSection(
            config, package, platformName, template.PackageContentDep,
            contentInBinaryDirectory)
        packageContentDepOutputFiles = CMakeGeneratorUtil.GetContentDepOutputFile(
            config, package, contentInBinaryDirectory)

        packageCompilerSpecificFileDependencies = CMakeGeneratorUtil.CompilerSpecificFileDependencies(
            config, package, template.PackageCompilerConditional,
            template.PackageTargetSourceFiles,
            template.PackageCompilerFileDict)

        packageVariantSettings = CMakeGeneratorUtil.GetVariantSettings(
            config, package, template.PackageVariantSettings,
            template.PackageDependencyTargetCompileDefinitions,
            template.PackageDependencyTargetLinkLibraries)

        buildCMakeFile = template.Master
        buildCMakeFile = buildCMakeFile.replace("##PACKAGE_INCLUDE_FILES##",
                                                includeFiles)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_PUBLIC_INCLUDE_FILES##", publicIncludeFiles)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_PRIVATE_INCLUDE_FILES##", privateIncludeFiles)
        buildCMakeFile = buildCMakeFile.replace("##PACKAGE_SOURCE_FILES##",
                                                sourceFiles)
        buildCMakeFile = buildCMakeFile.replace(
            "##TARGET_INCLUDE_DIRECTORIES##", targetIncludeDirectories)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_DIRECT_DEPENDENCIES_TARGET_LINK_LIBRARIES##",
            linkLibrariesDirectDependencies)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_DIRECT_DEPENDENCIES_TARGET_COMPILE_DEFINITIONS##",
            directDefinitions)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGES_FIND_DIRECT_EXTERNAL_DEPENDENCIES##",
            findDirectExternalDependencies)
        buildCMakeFile = buildCMakeFile.replace(
            "##SNIPPET_DEFAULT_TARGET_COMPILE_OPTIONS##", targetCompileOptions)
        buildCMakeFile = buildCMakeFile.replace(
            "##SNIPPET_DEFAULT_TARGET_COMPILE_FEATURES##",
            targetCompileFeatures)
        buildCMakeFile = buildCMakeFile.replace("##PACKAGE_COPY_FILES##",
                                                targetFileCopy)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_GENERATE_INSTALL_INSTRUCTIONS##", installInstructions)
        buildCMakeFile = buildCMakeFile.replace("##PACKAGE_CONTENTBUILDER##",
                                                packageContentBuilder)
        #buildCMakeFile = buildCMakeFile.replace("##PACKAGE_CONTENTBUILDER_OUTPUT_FILES##", packageContentBuilderOutputFiles)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_CONTENTSECTION_OUTPUT##", packageContentSection)
        #buildCMakeFile = buildCMakeFile.replace("##PACKAGE_CONTENTSECTION_OUTPUT_FILES##", packageContentSectionOutputFiles)
        buildCMakeFile = buildCMakeFile.replace("##PACKAGE_CONTENTDEP##",
                                                packageContentDep)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_CONTENTDEP_OUTPUT_FILES##",
            packageContentDepOutputFiles)
        buildCMakeFile = buildCMakeFile.replace(
            "##PACKAGE_COMPILER_SPECIFIC_FILE_DEPENDENCIES##",
            packageCompilerSpecificFileDependencies)
        buildCMakeFile = buildCMakeFile.replace("##PACKAGE_VARIANT_SETTINGS##",
                                                packageVariantSettings)

        toolProjectContext = toolProjectContextsDict[
            package.ProjectContext.ProjectId]
        sectionDefinePathEnvAsVariables = CMakeGeneratorUtil.CreateDefineRootDirectoryEnvironmentAsVariables(
            config.ToolConfig, toolProjectContext, useExtendedProjectHack,
            template.PathEnvToVariable)
        buildCMakeFile = self.__CommonReplace(
            buildCMakeFile, package.ProjectContext, packageName,
            aliasPackageName, cacheVariants, sectionDefinePathEnvAsVariables,
            config.ToolConfig.CMakeConfiguration.MinimumVersion, template)

        self.__SaveFile(GeneratorCMake._GetPackageBuildFileName(package),
                        buildCMakeFile)
        GitIgnoreHelper.SafeAddEntry(self.GitIgnoreDict, package,
                                     "CMakeLists.txt")
    def __GenerateBuildFile(self, config: Config, generatorName: str,
                            package: Package, template: str,
                            dstMakeFilename: str) -> None:
        if package.ShortName is None or package.Namespace is None or package.ResolvedMakeObjectPath is None or package.AbsolutePath is None:
            raise Exception("Invalid Package")
        name = GeneratorGNUmakefileUtil.GetTargetName(package)
        installPath = package.Namespace
        if package.Type == PackageType.Library:
            name = "lib" + name

        if package.ResolvedBuildSourceFiles is None or package.ResolvedBuildAllIncludeDirs is None or package.ResolvedBuildAllPrivateDefines is None or package.ResolvedBuildAllPublicDefines is None:
            raise Exception("Invalid Package")

        files = MakeFileHelper.CreateList(package.ResolvedBuildSourceFiles)
        includeDirs = MakeFileHelper.CreateList(
            package.ResolvedBuildAllIncludeDirs)

        localDefines = Util.ExtractNames(
            package.ResolvedBuildAllPrivateDefines)
        localDefines += Util.ExtractNames(
            package.ResolvedBuildAllPublicDefines)
        localDefineNames = MakeFileHelper.CreateList(localDefines)

        variantSection = self.__GetVariantSection(package)

        if package.ResolvedMakeVariantNameHint is None:
            raise InternalErrorException(
                "Package '{0}' ResolvedMakeVariantNameHint can not be None".
                format(package.Name))

        variantName = package.ResolvedMakeVariantNameHint
        build = template
        build = build.replace("##PACKAGE_TARGET_NAME##", name)
        build = build.replace("##PACKAGE_TARGET_INSTALL_PATH##", installPath)
        build = build.replace("##PACKAGE_SOURCE_FILES##", files)
        build = build.replace("##PACKAGE_INCLUDE_DIRS##", includeDirs)
        build = build.replace("##PACKAGE_DEFINES##", localDefineNames)
        build = build.replace("##PACKAGE_VARIANT_SECTION##", variantSection)
        build = build.replace("##PACKAGE_OBJECT_PATH##",
                              package.ResolvedMakeObjectPath)
        build = build.replace("##PACKAGE_VARIANT_NAME##", variantName)

        if package.Type == PackageType.Executable:
            libraryDependencies = self.__GetLibraryDependencies(
                config, package)
            strLibraryDependencies = MakeFileHelper.CreateList(
                libraryDependencies)
            build = build.replace("##PACKAGE_LIBRARY_DEPENDENCIES##",
                                  strLibraryDependencies)
            extLibraryDependencies = self.__GetExternalLibraryDependencies(
                package)
            strExtLibraryDependencies = MakeFileHelper.CreateList(
                extLibraryDependencies)
            build = build.replace("##PACKAGE_EXTERNAL_LIBRARY_DEPENDENCIES##",
                                  strExtLibraryDependencies)
            extLibraryPaths = self.__GetExternalLibraryPaths(
                package,
                [ExternalDependencyType.StaticLib, ExternalDependencyType.DLL])
            strExtLibraryPaths = MakeFileHelper.CreateList(extLibraryPaths)
            build = build.replace("##PACKAGE_EXTERNAL_LIBRARY_PATHS##",
                                  strExtLibraryPaths)
            extDllPaths = self.__GetExternalLibraryPaths(
                package, [ExternalDependencyType.DLL])
            strExtDllPaths = MakeFileHelper.CreateList(extDllPaths)
            build = build.replace("##PACKAGE_EXTERNAL_DLL_PATHS##",
                                  strExtDllPaths)
            executableReport = GeneratorGNUmakefileUtil.TryGenerateExecutableReport(
                config, generatorName, package)
            if executableReport is not None:
                variableReport = GeneratorGNUmakefileUtil.GenerateVariableReport(
                    config, generatorName, package, self.ConfigVariantOptions)
                GitIgnoreHelper.AddFromBuildReport(self.GitIgnoreDict, package,
                                                   executableReport,
                                                   variableReport)

        dstFile = IOUtil.Join(package.AbsolutePath, dstMakeFilename)
        if not config.DisableWrite:
            IOUtil.WriteFileIfChanged(dstFile, build)
            GitIgnoreHelper.AddPathIfInPackageRoot(self.GitIgnoreDict, package,
                                                   dstFile)