(: * IMPORTANT: this file is shared (identical) between the BDB XML and XQilla * projects. It should not be changed independently or in any way that makes * it project-dependent. * * @PROJECT_NAME@ - name of the Visual Studio project * @PROJECT_INPUT@ - input XML document that drives the script. * TBD: * 1. Could drive the remaining variables, including Visual Studio * variables, off of the xml file and provide the XML input * file as an external variable to the query. E.g. some projects * may want to parameterize the optimization and warnings levels * 2. Generate AdditionalIncludeDirectories based on the elements for * projects rather than just including "all" :) declare variable $projectList := "@PROJECT_INPUT@"; declare variable $vsversion := "@VISUAL_STUDIO_VERSION@"; declare variable $sourcePath := doc($projectList)/projects/variable[@name="sourcePath"]; declare variable $outputBase := doc($projectList)/projects/variable[@name="outputBase.@VISUAL_STUDIO_VERSION@"]; (: Visual Studio Variables --relatively static :) declare variable $debugOptLevel := "0"; (: VS -- no optimization :) declare variable $releaseOptLevel := "2"; (: VS -- level 2 opt :) declare variable $warnLevel := "3"; (: VS warning level :) declare variable $appType := "1"; (: VS type 1 is a program :) declare variable $dllType := "2"; (: VS type 2 is a DLL :) declare variable $staticType := "4"; (: VS type 4 is a static lib :) declare variable $debugInfo := "3"; (: VS debug information format :) declare variable $libExtension := ".lib"; (: formatting :) declare function local:indent($n) { concat(" ",string-join(for $i in (1 to $n) return " ", "")) }; (: is it a DLL, Application, or static library? :) declare function local:configurationType($projectType) { if ($projectType eq "dll") then $dllType else if ($projectType eq "app") then $appType else if ($projectType eq "static_lib") then $staticType else if ($projectType eq "static_app") then $appType else error(fn:QName("", "err"), "Unknown project type") }; (: "normalize" Windows file paths :) declare function local:windowsPath($path) as xs:string { translate($path,"/","\\") }; (: debug vs release :) declare function local:isDebug($config) as xs:boolean { contains($config,"Debug") }; declare function local:isRelease($config) as xs:boolean { contains($config,"Release") }; (: machine-target-dependent link options :) declare function local:addLinkOptions($project, $platform, $config) { let $machine := if (contains($platform,"Win32")) then "/machine:x86" else concat("/machine:",$platform) let $opt := string-join(($machine,$project/options/link[contains(@config,$config)])," ") return if (not($opt eq "")) then attribute{"AdditionalOptions"}{$opt} else () }; declare function local:addDebugInformation($config) { attribute{"DebugInformationFormat"}{$debugInfo}, if (local:isDebug($config)) then attribute{"BasicRuntimeChecks"}{"3"} else () }; declare function local:generateCompilerPreprocessorDefs($project, $config) { let $generic := doc($projectList)/projects/preprocessor[@config="all" or contains($config,@config)] let $proj := $project/preprocessor[@config="all" or contains(@config,$config)] let $type := doc($projectList)/projects/preprocessor[@config=$project/type] return string-join(($generic,$proj,$type),";") }; (: declare function local:generateResourcePreprocessorDefs($config) { let $dbg := if (local:isDebug($config)) then "_DEBUG" else "NDEBUG" return concat($dbg,";_CRT_SECURE_NO_DEPRECATE=1") }; :) (: Optimization level :) declare function local:optLevel($config) { if (local:isDebug($config)) then $debugOptLevel else $releaseOptLevel }; (: MDd is 3, MD is 2, MTd is 1, MT is 0 :) declare function local:runtimeLibrary($config,$static as xs:boolean) { if (local:isDebug($config)) then if ($static) then "1" else"3" else if ($static) then "0" else"2" }; declare function local:getLibName($name, $config) { doc($projectList)/projects/library[@name=$name]/libname[@config=$config] }; declare function local:makeStaticOutputFile($project, $config) { attribute{"OutputFile"} {concat("$(OutDir)/", local:getLibName($project/@name, $config),".lib") } }; declare function local:makeImportLibrary($project, $config) { if ($project/type eq "dll") then attribute{"ImportLibrary"}{concat("$(OutDir)/", local:getLibName($project/@name, $config),".lib")} else () }; declare function local:makeModuleDefinition($project, $config) { if (not(empty($project/moddef))) then attribute{"ModuleDefinitionFile"}{local:windowsPath(concat($sourcePath,$project/moddef/@file))} else () }; declare function local:makeOutputPDBFile($project, $config) { attribute{"ProgramDatabaseFile"} { if ($project/type eq "dll") then concat("$(OutDir)/", local:getLibName($project/@name, $config),".pdb") else concat("$(OutDir)/",if (not(empty($project/@output))) then $project/@output else $project/@name,".pdb") } }; declare function local:makeOutputFile($project, $config) { attribute{"OutputFile"} { if ($project/type eq "dll") then concat("$(OutDir)/", local:getLibName($project/@name, $config), ".dll") else concat("$(OutDir)/",if (not(empty($project/@output))) then $project/@output else $project/@name,".exe") } }; (: The simple thing is to add all libraries for all projects :) declare function local:addLibraryDependencies($project,$config) { attribute{"AdditionalDependencies"}{string-join(for $dep in $project/depends return concat(local:getLibName($dep, $config),".lib")," ")} }; declare function local:makeLibraryDirectory($lib,$platform,$config) { for $dir in $lib/platform[contains(@name,$platform)]/config[$config=./@type]/libdir return if (not(empty($lib/libbase[@vsver=$vsversion]))) then concat($lib/libbase[@vsver=$vsversion],"/", $dir) else $dir }; (: The simple thing is to add all libraries for all projects :) declare function local:addLibraryDirectories($project,$platform,$config) { attribute{"AdditionalLibraryDirectories"}{string-join(for $dep in $project/depends return local:makeLibraryDirectory(doc($projectList)/projects/library[@name=$dep],$platform,$config),";")} }; (: The simple thing is to add all libraries for all projects :) declare function local:addIncludeDirectories($project,$config) { let $incref := for $inc in $project/include[@type="ref"] return doc($projectList)/projects/include[@name=$inc] let $increl := $project/include[@type="rel"] return attribute{"AdditionalIncludeDirectories"}{string-join(($incref,$increl),",")} }; (: look for project-specific tool, then a type-specific event :) declare function local:generatePostBuildEvent($project, $config) { local:indent(6), {attribute{"Name"}{"VCPostBuildEventTool"}} {if (not(empty($project/event[@name="postbuild"]))) then (attribute{"CommandLine"}{$project/event[@name="postbuild"]/command[@config=$config]}, attribute{"Description"}{$project/event[@name="postbuild"]/description}) else let $ev := doc($projectList)/projects/event[@name="postbuild" and @type=$project/type] return if (not(empty($ev))) then (attribute{"CommandLine"}{replace($ev/command[@config=$config],"@pname@",if (not(empty($project/@output))) then $project/@output else $project/@name)}, attribute{"Description"}{$ev/description}) else () } }; declare function local:generateCustomBuildTool($project, $config) { local:indent(6), {attribute{"Name"}{"VCCustomBuildTool"}} {if (not(empty($project/event[@name="custom"]))) then (attribute{"CommandLine"}{$project/event[@name="custom"]/command[contains(@config,$config)]}, attribute{"Outputs"}{$project/event[@name="custom"]/output}) else ()} }; (: static build of libraries; at this time it does *not* add additional dependent libraries. This means that applications need to include them for the time being. :) declare function local:generateConfigLibrarian($project, $config) { local:indent(6), {attribute{"Name"}{"VCLibrarianTool"}} {local:makeStaticOutputFile($project,$config)} }; declare function local:generateConfigLinkerAndMidl($project, $platform, $config) { local:indent(6), {attribute{"Name"}{"VCLinkerTool"}} {local:addLinkOptions($project, $platform, $config)} {local:addLibraryDependencies($project,$config)} {local:addLibraryDirectories($project,$platform,$config)} {local:makeOutputFile($project, $config)} {local:makeOutputPDBFile($project, $config)} {attribute{"LinkIncremental"}{"1"}} {attribute{"GenerateDebugInformation"}{"TRUE"}} {attribute{"SuppressStartupBanner"}{"TRUE"}} {attribute{"OptimizeReferences"}{"2"}} {local:makeImportLibrary($project,$config)} {local:makeModuleDefinition($project,$config)} {attribute{"TargetMachine"}{"0"}} }; declare function local:generateConfigCompiler($project, $platform, $config, $static as xs:boolean) { local:indent(6), {attribute{"Name"}{"VCCLCompilerTool"}} {attribute{"Optimization"}{local:optLevel($config)}} {attribute{"MinimalRebuild"}{"TRUE"}} {if (local:isRelease($config)) then attribute{"InlineFunctionExpansion"}{"1"} else ()} {local:addIncludeDirectories($project,$config)} {attribute{"PreprocessorDefinitions"}{local:generateCompilerPreprocessorDefs($project, $config)}} {attribute{"StringPooling"}{"TRUE"}} {if (not(empty($project/options/rtti))) then attribute{"RuntimeTypeInfo"}{"TRUE"} else ()} {attribute{"RuntimeLibrary"}{local:runtimeLibrary($config,$static)}} {if (local:isRelease($config)) then attribute{"EnableFunctionLevelLinking"}{"TRUE"} else ()} {attribute{"UsePrecompiledHeader"}{"0"}} {if ($project/@name eq "dbxml") then attribute{"PrecompiledHeaderThrough"}{"DbXmlInternal.hpp"} else ()} {attribute{"PrecompiledHeaderFile"}{concat("./$(OutDir)/",$project/@name,".pch")}} {attribute{"AssemblerListingLocation"}{"./$(OutDir)/"}} {attribute{"ObjectFile"}{"./$(OutDir)/"}} {attribute{"WarningLevel"}{$warnLevel}} {if (not($vsversion eq "8.00") and not($project/options/nowp64)) then attribute{"Detect64BitPortabilityProblems"}{"TRUE"} else ()} {attribute{"SuppressStartupBanner"}{"TRUE"}} {local:addDebugInformation($config)} {attribute{"CompileAs"}{"0"}} }; declare function local:generateConfigBoilerplate($config) { local:indent(6),, local:indent(6),, local:indent(6),, local:indent(6),, local:indent(6),, local:indent(6), }; (: use "platform/configuration" :) declare function local:generateOutputDirectory($platform,$config,$static) { attribute{"OutputDirectory"}{local:windowsPath(concat($outputBase,"$(PlatformName)","/",string-join(tokenize($config," "),"_"),$static))} }; declare function local:generateConfig($project, $platform, $config) { local:indent(4), {attribute{"Name"}{concat($config,"|",$platform)}} {local:generateOutputDirectory($platform,$config,"")} {attribute{"IntermediateDirectory"}{concat("./$(OutDir)/",$project/@name)}} {attribute{"ConfigurationType"}{local:configurationType($project/type)}} {attribute{"UseOfMFC"}{"0"}} {attribute{"ATLMinimizesCRunTimeLibraryUsage"}{"FALSE"}} {attribute{"CharacterSet"}{"2"}} {local:generateConfigBoilerplate($config)} {local:generateConfigCompiler($project, $platform, $config,xs:boolean("false"))} {local:generateConfigLinkerAndMidl($project, $platform, $config)} {local:generatePostBuildEvent($project,if (local:isDebug($config)) then "Debug" else "Release")} {local:generateCustomBuildTool($project,if (local:isDebug($config)) then "Debug" else "Release")} }; declare function local:generateStaticConfig($project, $platform, $config) { local:indent(4), {attribute{"Name"}{concat($config,"|",$platform)}} {local:generateOutputDirectory($platform,$config,"_static")} {attribute{"IntermediateDirectory"}{concat("./$(OutDir)/",$project/@name)}} {attribute{"ConfigurationType"}{local:configurationType($project/type)}} {attribute{"UseOfMFC"}{"0"}} {attribute{"ATLMinimizesCRunTimeLibraryUsage"}{"FALSE"}} {attribute{"CharacterSet"}{"2"}} {local:generateConfigBoilerplate($config)} {local:generateConfigCompiler($project, $platform, $config,xs:boolean("true"))} {if (contains($project/type,"lib")) then local:generateConfigLibrarian($project, $config) else local:generateConfigLinkerAndMidl($project, $platform, $config) } }; declare function local:generateRcFile($file) { local:indent(4), { for $platform in local:getPlatforms($vsversion) return for $config in ("Debug","Release") return (local:indent(6), {local:indent(6)}) } {local:indent(4)} }; declare function local:generateFilesNoFilter($project) { for $file in $project/files/file return if (ends-with($file/@name,".rc")) then local:generateRcFile($file) else (local:indent(4),) }; declare function local:generateFilesWithFilter($project,$filter) { for $file in $project/files/filter[@name=$filter]/file return if (ends-with($file/@name,".rc")) then local:generateRcFile($file) else (local:indent(6),) }; declare function local:generateFiles($project) { let $filters := $project/files/filter/@name return if (empty($filters)) then local:generateFilesNoFilter($project) else for $filter in $filters return (local:indent(4), {local:generateFilesWithFilter($project,$filter)} {local:indent(4)}) }; declare function local:getGuid($project) { concat("{",$project/@guid,"}") }; declare function local:getPlatforms($version) { if ($version eq "7.10") then ("Win32") else ("Win32", "x64", "IA64") }; declare function local:getProjects() { (: doc($projectList)/projects/project :) doc($projectList)/projects/project[@name="@PROJECT_NAME@"] }; for $project in local:getProjects() let $static := contains($project/@name,"static") let $proj := if ($static) then doc($projectList)/projects/project[@name=substring-before($project/@name,"_static")] else $project return {local:indent(2)} {local:indent(4)} {local:indent(4)} {local:indent(4)} {local:indent(2)} {local:indent(2)} { for $platform in local:getPlatforms($vsversion) return for $config in ("Debug","Release") return if ($static) then local:generateStaticConfig($project, $platform, $config) else local:generateConfig($project, $platform, $config) } {local:indent(2)} {local:indent(2)} {local:indent(2)} {local:generateFiles($proj)} {local:indent(2)} {local:indent(2)} {" "}