Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ PublishScripts/

# NuGet Packages
*.nupkg
/StrawberryPerl.5.28.0.1/
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
Expand Down
Binary file added Build/Local/Nuget/nuget.exe
Binary file not shown.
5 changes: 4 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
Enlistment root is based off of wherever this file is. Be sure not to set this property anywhere else.
-->
<EnlistmentRoot>$(MSBuildThisFileDirectory.TrimEnd('\\'))</EnlistmentRoot>
<NetfxVersion>net472</NetfxVersion>
<!-- Whether we are building on a Windows OS. net472 (the .NET Framework) can only be built/run on Windows,
so builds on other OSes (e.g. Linux) skip it and only produce netstandard2.0/net8.0/net10.0 assemblies. -->
<IsWindowsBuild Condition="'$(IsWindowsBuild)'==''">$([MSBuild]::IsOSPlatform('Windows'))</IsWindowsBuild>
<NetfxVersion Condition="'$(IsWindowsBuild)'=='true'">net472</NetfxVersion>
</PropertyGroup>

<!-- BinSkim BA2004: EnableSecureSourceCodeHashing (C#) -->
Expand Down
22 changes: 13 additions & 9 deletions SmoBuild/DdlEvents.targets
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<SmoCodeGenOutputDir>$(BaseIntermediateOutputPath)$(Configuration)\$(TargetFramework)</SmoCodeGenOutputDir>
<SmoCodeGenOutputDir>$(BaseIntermediateOutputPath)$(Configuration)/$(TargetFramework)</SmoCodeGenOutputDir>
</PropertyGroup>
<ItemGroup>
<DdlEventsGenCompile Include="$(BuildPropsDir)\DdlEvents\*" />
</ItemGroup>
<PropertyGroup>
<Perl Condition="Exists('c:\strawberry\perl\bin\perl.exe')">c:\strawberry\perl\bin\perl.exe</Perl>
<Perl Condition="'$(Perl)' == ''">$(EnlistmentRoot)\packages\StrawberryPerl.5.28.0.1\bin\perl.exe</Perl>
<Perl Condition="'$(Perl)' == '' and '$(IsWindowsBuild)' == 'true' and Exists('c:\strawberry\perl\bin\perl.exe')">c:\strawberry\perl\bin\perl.exe</Perl>
<Perl Condition="'$(Perl)' == '' and '$(IsWindowsBuild)' == 'true' and Exists('$(EnlistmentRoot)\packages\StrawberryPerl.5.28.0.1\bin\perl.exe')">$(EnlistmentRoot)\packages\StrawberryPerl.5.28.0.1\bin\perl.exe</Perl>
<Perl Condition="'$(Perl)' == '' and '$(IsWindowsBuild)' == 'true' and Exists('$(EnlistmentRoot)\StrawberryPerl.5.28.0.1\bin\perl.exe')">$(EnlistmentRoot)\StrawberryPerl.5.28.0.1\bin\perl.exe</Perl>
<Perl Condition="'$(Perl)' == '' and '$(IsWindowsBuild)' == 'true'">$(EnlistmentRoot)\packages\StrawberryPerl.5.28.0.1\bin\perl.exe</Perl>
<!-- On non-Windows OSes perl is expected to be installed and available on PATH (see init.sh) -->
<Perl Condition="'$(Perl)' == ''">perl</Perl>
</PropertyGroup>
<ItemDefinitionGroup>
<!-- the defaults are for sqlenum -->
Expand All @@ -26,12 +30,12 @@
BeforeTargets="ResolveReferences"
Inputs="$(MSBuildThisFileFullPath);@(DdlEventsGenCompile)"
Outputs="@(EventsFileName->'$(SmoCodeGenOutputDir)\%(CodeFile).cs')" >
<Message Importance="high" Text="$(Perl) &quot;$(BuildPropsDir)\DdlEvents\trc2evt.pl&quot; &quot;$(BuildPropsDir)\DdlEvents\trccomn.txt&quot; &quot;$(BuildPropsDir)\DdlEvents\trcdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot; 0 %(EventsFileName.EventTraceBuildType)" />
<Exec Command="$(Perl) &quot;$(BuildPropsDir)\DdlEvents\trc2evt.pl&quot; &quot;$(BuildPropsDir)\DdlEvents\trccomn.txt&quot; &quot;$(BuildPropsDir)\DdlEvents\trcdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot; 0 %(EventsFileName.EventTraceBuildType)" />
<Message Importance="high" Text="$(Perl) &quot;$(BuildPropsDir)\DdlEvents\evtschema.pl&quot; &quot;$(BuildPropsDir)\DdlEvents\eventsdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot;" />
<Exec Command="$(Perl) &quot;$(BuildPropsDir)\DdlEvents\evtschema.pl&quot; &quot;$(BuildPropsDir)\DdlEvents\eventsdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot;" />
<Message Importance="high" Text="$(Perl) &quot;$(BuildPropsDir)\DdlEvents\smoevt.pl&quot; %(EventsFileName.GenType) &quot;$(SmoCodeGenOutputDir)\eventsschema.tmp&quot; &quot;$(BuildPropsDir)\DdlEvents\%(EventsFileName.ClassEnumTemplate).cs&quot; &quot;$(BuildPropsDir)\DdlEvents\%(EventsFileName.EventEnumTemplate).cs&quot; &quot;$(SmoCodeGenOutputDir)\smoevt_gen_template.cs&quot; &gt; &quot;$(SmoCodeGenOutputDir)\%(EventsFileName.CodeFile).cs&quot;" />
<Exec Command="$(Perl) &quot;$(BuildPropsDir)\DdlEvents\smoevt.pl&quot; %(EventsFileName.GenType) &quot;$(SmoCodeGenOutputDir)\eventsschema.tmp&quot; &quot;$(BuildPropsDir)\DdlEvents\%(EventsFileName.ClassEnumTemplate).cs&quot; &quot;$(BuildPropsDir)\DdlEvents\%(EventsFileName.EventEnumTemplate).cs&quot; &quot;$(SmoCodeGenOutputDir)\smoevt_gen_template.cs&quot; &gt; &quot;$(SmoCodeGenOutputDir)\%(EventsFileName.CodeFile).cs&quot;" />
<Message Importance="high" Text="$(Perl) &quot;$(BuildPropsDir)DdlEvents/trc2evt.pl&quot; &quot;$(BuildPropsDir)DdlEvents/trccomn.txt&quot; &quot;$(BuildPropsDir)DdlEvents/trcdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot; 0 %(EventsFileName.EventTraceBuildType)" />
<Exec Command="$(Perl) &quot;$(BuildPropsDir)DdlEvents/trc2evt.pl&quot; &quot;$(BuildPropsDir)DdlEvents/trccomn.txt&quot; &quot;$(BuildPropsDir)DdlEvents/trcdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot; 0 %(EventsFileName.EventTraceBuildType)" />
<Message Importance="high" Text="$(Perl) &quot;$(BuildPropsDir)DdlEvents/evtschema.pl&quot; &quot;$(BuildPropsDir)DdlEvents/eventsdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot;" />
<Exec Command="$(Perl) &quot;$(BuildPropsDir)DdlEvents/evtschema.pl&quot; &quot;$(BuildPropsDir)DdlEvents/eventsdef.txt&quot; &quot;$(SmoCodeGenOutputDir)&quot;" />
<Message Importance="high" Text="$(Perl) &quot;$(BuildPropsDir)DdlEvents/smoevt.pl&quot; %(EventsFileName.GenType) &quot;$(SmoCodeGenOutputDir)/eventsschema.tmp&quot; &quot;$(BuildPropsDir)DdlEvents/%(EventsFileName.ClassEnumTemplate).cs&quot; &quot;$(BuildPropsDir)DdlEvents/%(EventsFileName.EventEnumTemplate).cs&quot; &quot;$(SmoCodeGenOutputDir)/smoevt_gen_template.cs&quot; &gt; &quot;$(SmoCodeGenOutputDir)/%(EventsFileName.CodeFile).cs&quot;" />
<Exec Command="$(Perl) &quot;$(BuildPropsDir)DdlEvents/smoevt.pl&quot; %(EventsFileName.GenType) &quot;$(SmoCodeGenOutputDir)/eventsschema.tmp&quot; &quot;$(BuildPropsDir)DdlEvents/%(EventsFileName.ClassEnumTemplate).cs&quot; &quot;$(BuildPropsDir)DdlEvents/%(EventsFileName.EventEnumTemplate).cs&quot; &quot;$(SmoCodeGenOutputDir)/smoevt_gen_template.cs&quot; &gt; &quot;$(SmoCodeGenOutputDir)/%(EventsFileName.CodeFile).cs&quot;" />
<ItemGroup>
<Compile Include="$(SmoCodeGenOutputDir)\%(EventsFileName.CodeFile).cs" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions SmoBuild/DdlEvents/evtschema.pl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
open(EVTSCHEMACPP, $eventsschema_cpp) || die "Cannot open $eventsschema_cpp\n";

# New destination file
open(OUTF, ">" . $OutputDir . "\\eventsschema.tmp") || die "Cannot write to eventsschema.tmp\n";
open(OUTF, ">" . $OutputDir . "/eventsschema.tmp") || die "Cannot write to eventsschema.tmp\n";

# read and copy
while(<EVTSCHEMACPP>)
Expand All @@ -46,7 +46,7 @@
sub IncludeFile
{
local($IncName) = @_;
open(INCFILE, $OutputDir . "\\" . $IncName) || die "Cannot open " . $IncName . "\n";
open(INCFILE, $OutputDir . "/" . $IncName) || die "Cannot open " . $IncName . "\n";
while(<INCFILE>)
{
print OUTF $_;
Expand Down
20 changes: 10 additions & 10 deletions SmoBuild/DdlEvents/trc2evt.pl
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@
# print event group enumeration
if($option == 0)
{
open(FOUT, ">" . $OutputDir . "\\grpenum.inc") || die "Cannot write to " . $OutputDir . "\\grpenum.inc\n";
open(FOUT, ">" . $OutputDir . "/grpenum.inc") || die "Cannot write to " . $OutputDir . "/grpenum.inc\n";
print FOUT "// Extended Event Group for SQLTrace\n";
print FOUT "enum ETraceEventGroup {\n";
print FOUT "\tEGROUP_TRCAT_START = EGROUP_TRCAT_ALL, // Setting beginning\n";
Expand All @@ -318,7 +318,7 @@

#
# print event group name
open(FOUT, ">" . $OutputDir . "\\grpdefs.inc") || die "Cannot write to " . $OutputDir . "\\grpdefs.inc\n";
open(FOUT, ">" . $OutputDir . "/grpdefs.inc") || die "Cannot write to " . $OutputDir . "/grpdefs.inc\n";
print FOUT "// Extended Event Groups for SQLTrace\n";
for (my $i = 1; $i <= $#rgsCategoryIDs; $i++)
{
Expand All @@ -330,7 +330,7 @@

#
# print paraminfo array
open(FOUT, ">" . $OutputDir . "\\parinfo.inc") || die "Cannot write to " . $OutputDir . "\\parinfo.inc\n";
open(FOUT, ">" . $OutputDir . "/parinfo.inc") || die "Cannot write to " . $OutputDir . "/parinfo.inc\n";
my $ColumnCount = @rgsColumnNames;
print FOUT "//----------------------------------------------------------------\n";
print FOUT "// TraceEventTag Enum\n";
Expand Down Expand Up @@ -400,7 +400,7 @@

#
# print schema array
open(FOUT, ">" . $OutputDir . "\\schema.inc") || die "Cannot write to " . $OutputDir . "\\schema.inc\n";
open(FOUT, ">" . $OutputDir . "/schema.inc") || die "Cannot write to " . $OutputDir . "/schema.inc\n";
print FOUT "// Schema array extended for SQLTrace\n";
for (my $i = $EventClassStart; $i <= $#rgsEventIDs; $i++)
{
Expand Down Expand Up @@ -447,7 +447,7 @@

#
# Generate event hierarchy graph for reference. This file is not used for compilation.
open(FOUT, ">" . $OutputDir . "\\hierarchy.txt") || die "Cannot write to " . $OutputDir . "\\hierarchy.txt.\n";
open(FOUT, ">" . $OutputDir . "/hierarchy.txt") || die "Cannot write to " . $OutputDir . "/hierarchy.txt.\n";
print FOUT "========== SQL Trace event hierarchy ==================\n\n";
print FOUT "ALL_EVENTS\n";
print FOUT "|____ TRC_ALL_EVENTS\n";
Expand Down Expand Up @@ -483,8 +483,8 @@
# Form more information, take a look at:
# http://blogs.msdn.com/brettsh/archive/2006/06/07/620986.aspx
# ----------------------------------------------------------------
open(FOUT, ">:raw:encoding(UTF16-LE):crlf:utf8", $OutputDir . "\\etwcls.mof")
|| die "Cannot write to " . $OutputDir . "\\etwcls.mof\n";
open(FOUT, ">:raw:encoding(UTF16-LE):crlf:utf8", $OutputDir . "/etwcls.mof")
|| die "Cannot write to " . $OutputDir . "/etwcls.mof\n";
print FOUT "\x{FEFF}"; # print BOM (Byte Order Mark) for the unicode file
# ----------------------------------------------------------------

Expand Down Expand Up @@ -548,7 +548,7 @@
#
# GUID include file which lists all ETW event class GUIDs
#
open(FOUT, ">" .$OutputDir . "\\etwguid.inc") || die "Cannot write to " . $OutputDir . "\\etwguid.inc\n";
open(FOUT, ">" .$OutputDir . "/etwguid.inc") || die "Cannot write to " . $OutputDir . "/etwguid.inc\n";
print FOUT "// Array of Event Class Info\n\n";

for (my $i = $EventClassStart; $i <= $#rgsEventIDs; $i++)
Expand All @@ -566,7 +566,7 @@

# Dump All Columns to XML
#
open(FOUT, ">" .$OutputDir . "\\events_trace_template.xst") || die "Cannot write to " . $OutputDir . "\\events_trace_template.xst\n";
open(FOUT, ">" .$OutputDir . "/events_trace_template.xst") || die "Cannot write to " . $OutputDir . "/events_trace_template.xst\n";
for (my $col = 1; $col < $ColumnCount; $col++)
{
#print param defs for active cols except for SPID/EventClass
Expand All @@ -585,7 +585,7 @@
# 2: instance guid (INSTGUID)
if($option == 1)
{
open(FOUT, ">" . $OutputDir . "\\etwsetup.inc") || die "Cannot write to " . $OutputDir . "\\etwsetup.inc\n";
open(FOUT, ">" . $OutputDir . "/etwsetup.inc") || die "Cannot write to " . $OutputDir . "/etwsetup.inc\n";
print FOUT "{NOPARAM, L\"// ************************************************************************\\n\"},\n";
print FOUT "{NOPARAM, L\"// \\tCopyrights (c) Microsoft Corporation\\n//\\n\"},\n";
print FOUT "{NOPARAM, L\"// ************************************************************************\\n\\n\"},\n";
Expand Down
26 changes: 20 additions & 6 deletions init.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ doskey prod=pushd %BASEDIR%src\Microsoft\SqlServer\Management\$*
doskey sfc=pushd %BASEDIR%src\Microsoft\SqlServer\Management\Sdk\sfc
doskey smo=pushd %BASEDIR%src\Microsoft\SqlServer\Management\Smo
doskey smoenum=pushd %BASEDIR%src\Microsoft\SqlServer\Management\SqlEnum\$*
doskey clean=powershell.exe -ExecutionPolicy Unrestricted -File "%BASEDIR%init.ps1" -Clean

doskey tst=pushd %BASEDIR%src\FunctionalTest\Smo\$*
doskey slngen19=slngen -vs "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe" $*

Expand All @@ -44,16 +44,30 @@ doskey netcoretests=pushd %BASEDIR%bin\debug\net8.0$Tvstest.console.exe microsof

title git %BASEDIR%

REM Migration to PowerShell environment
powershell.exe -ExecutionPolicy Unrestricted -File "%BASEDIR%init.ps1" -Initialize
if "%errorlevel%" neq "0" (
echo Failed to setup local dev build environment correctly
REM Read the required SDK version from global.json so this script never drifts from it
for /f "usebackq tokens=2 delims=:, " %%V in (`findstr /r /c:"\"version\"" %BASEDIR%global.json`) do set DOTNET_SDK_VERSION=%%~V
set DOTNET_SDK_VERSION=%DOTNET_SDK_VERSION:"=%
dotnet --list-sdks | findstr /b /c:"%DOTNET_SDK_VERSION% " >nul
IF ERRORLEVEL 1 (
echo .NET SDK %DOTNET_SDK_VERSION% ^(required by global.json^) was not found.
echo Install it from https://dotnet.microsoft.com/download/dotnet/%DOTNET_SDK_VERSION:~0,-4%
)

dotnet tool install --global Microsoft.VisualStudio.SlnGen.Tool
dotnet tool install --global Microsoft.SqlPackage

set NUGET_EXE=%BASEDIR%Build\Local\Nuget\nuget.exe
IF NOT EXIST %NUGET_EXE% (
echo nuget.exe not found, downloading from https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
IF NOT EXIST %BASEDIR%Build\Local\Nuget mkdir %BASEDIR%Build\Local\Nuget
powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri 'https://dist.nuget.org/win-x86-commandline/latest/nuget.exe' -OutFile '%NUGET_EXE%'"
IF NOT EXIST %NUGET_EXE% (
echo Failed to download nuget.exe. Please download it manually from https://dist.nuget.org/win-x86-commandline/latest/nuget.exe and place it at %NUGET_EXE%
goto :EOF
)
)
IF NOT EXIST %BASEDIR%packages\StrawberryPerl.5.28.0.1\bin\perl.exe (
%BASEDIR%Build\Local\Nuget\nuget.exe install StrawberryPerl -Version 5.28.0.1
%NUGET_EXE% install StrawberryPerl -Version 5.28.0.1
)

echo.
Expand Down
98 changes: 98 additions & 0 deletions init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
#
# Setup the developer environment on Linux (e.g. Ubuntu).
# **This script is not run on build machines**
#
# Use this script to idempotently install the tools needed to build dirs.proj on Linux.
#
# Notes:
# - net472 (the .NET Framework) cannot be built or run on Linux, so a Linux build only
# produces the netstandard2.0/net8.0/net10.0 targets. This is handled automatically
# by the MSBuild props (see $(IsWindowsBuild) in Directory.Build.props) - you don't
# need to pass any extra flags.
# - Build with: dotnet build "$BASEDIR/dirs.proj"
# - Run unit tests for a project with: dotnet test <path-to-test.csproj>
#
set -euo pipefail

BASEDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DOTNET_SDK_VERSION="$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$BASEDIR/global.json" | head -1 | sed -E 's/.*"([^"]+)"$/\1/')"
if [ -z "$DOTNET_SDK_VERSION" ]; then
echo "Error: could not read sdk.version from $BASEDIR/global.json" >&2
exit 1
fi
DOTNET_INSTALL_DIR="${DOTNET_INSTALL_DIR:-$HOME/.dotnet}"

echo "Enlistment root: $BASEDIR"

# ---------------------------------------------------------------------------
# perl - required to generate DDL event code (SmoBuild/DdlEvents/*.pl)
# ---------------------------------------------------------------------------
if ! command -v perl >/dev/null 2>&1; then
echo "perl not found, installing..."
if command -v apt-get >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y perl
else
echo "Warning: apt-get not found. Please install perl manually and re-run this script." >&2
fi
else
echo "perl already installed: $(command -v perl)"
fi

# ---------------------------------------------------------------------------
# .NET SDK - required to build and test the repo
# ---------------------------------------------------------------------------
has_required_sdk() {
command -v dotnet >/dev/null 2>&1 && dotnet --list-sdks 2>/dev/null | grep -q "^${DOTNET_SDK_VERSION} "
}

if has_required_sdk; then
echo ".NET SDK $DOTNET_SDK_VERSION already installed: $(command -v dotnet)"
else
echo ".NET SDK $DOTNET_SDK_VERSION not found, installing to $DOTNET_INSTALL_DIR..."
curl -sSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh
bash /tmp/dotnet-install.sh --version "$DOTNET_SDK_VERSION" --install-dir "$DOTNET_INSTALL_DIR"
rm -f /tmp/dotnet-install.sh

export PATH="$DOTNET_INSTALL_DIR:$PATH"
if ! grep -q "$DOTNET_INSTALL_DIR" "$HOME/.bashrc" 2>/dev/null; then
{
echo ""
echo "# Added by init.sh for sqlmanagementobjects"
echo "export DOTNET_ROOT=\"$DOTNET_INSTALL_DIR\""
echo "export PATH=\"$DOTNET_INSTALL_DIR:\$PATH\""
} >> "$HOME/.bashrc"
echo "Added $DOTNET_INSTALL_DIR to PATH in ~/.bashrc (start a new shell, or run 'source ~/.bashrc')."
fi
fi

# ---------------------------------------------------------------------------
# dotnet global tools used by the repo
# ---------------------------------------------------------------------------
install_global_tool_if_missing() {
local tool_name="$1"
if dotnet tool list --global 2>/dev/null | grep -qi "^${tool_name} "; then
echo "$tool_name already installed as a global dotnet tool"
else
dotnet tool install --global "$tool_name"
fi
}

install_global_tool_if_missing "Microsoft.VisualStudio.SlnGen.Tool"
install_global_tool_if_missing "Microsoft.SqlPackage"

echo
echo
echo "To build for SMO development and to run unit tests:"
echo " dotnet build $BASEDIR/dirs.proj"
echo
echo "Note: net472 (the .NET Framework) is skipped on Linux; the build produces"
echo " the netstandard2.0/net8.0/net10.0 targets only."
echo
echo "To run tests for a single test project:"
echo " dotnet test $BASEDIR/src/UnitTest/Smo/Microsoft.SqlServer.Test.SmoUnitTests.csproj"
echo
echo "To run functional tests, see $BASEDIR/src/FunctionalTest/runtests.cmd for the list"
echo "of filters and environment variables (e.g. SqlTestTargetServersFilter) that are"
echo "used to select which tests/backends to run, then invoke with dotnet test."
4 changes: 2 additions & 2 deletions src/Codegen/CodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ public static int Main(string[] args)
string output_dir = "";
if (args.Length == 4)
{
output_dir = args[3] + "\\";
output_dir = args[3];
}

bool bGenerateNewFile = false;
Expand Down Expand Up @@ -724,7 +724,7 @@ static void GenerateClass(XmlNode node, string node_namespace, string output_dir
bool bGenMetadata = Boolean.Parse(GetAttribute("gen_metadata", node, "true"));
string sUrn = GetAttribute("urn", node, null);

string modelOutputDir = output_dir + "model\\";
string modelOutputDir = Path.Combine(output_dir, "model");

if (!String.IsNullOrEmpty(output_dir) && !Directory.Exists(output_dir))
{
Expand Down
Loading