diff --git a/bin/build.ps1 b/bin/build.ps1 new file mode 100644 index 0000000..1fb61b6 --- /dev/null +++ b/bin/build.ps1 @@ -0,0 +1,15 @@ +# This is meant to be used with build.ps1, and is not a standalone script. +$target_arch = Join-Path $PSScriptRoot 'target_arch.psm1' + +import-module $target_arch + +if ($IsWindows) { + # This HandmadeHero implementation is only designed for 64-bit systems + & $devshell -arch amd64 +} + +if ( $vendor -eq $null ) { + write-host "No vendor specified, assuming clang available" + $vendor = "clang" +} + diff --git a/bin/helpers/devshell.ps1 b/bin/helpers/devshell.ps1 new file mode 100644 index 0000000..33ca0ce --- /dev/null +++ b/bin/helpers/devshell.ps1 @@ -0,0 +1,28 @@ +if ($env:VCINSTALLDIR) { + return +} + +$ErrorActionPreference = "Stop" + +# Use vswhere to find the latest Visual Studio installation +$vswhere_out = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath +if ($null -eq $vswhere_out) { + Write-Host "ERROR: Visual Studio installation not found" + exit 1 +} + +# Find Launch-VsDevShell.ps1 in the Visual Studio installation +$vs_path = $vswhere_out +$vs_devshell = Join-Path $vs_path "\Common7\Tools\Launch-VsDevShell.ps1" + +if ( -not (Test-Path $vs_devshell) ) { + Write-Host "ERROR: Launch-VsDevShell.ps1 not found in Visual Studio installation" + Write-Host Tested path: $vs_devshell + exit 1 +} + +# Launch the Visual Studio Developer Shell +Push-Location +write-host @args +& $vs_devshell @args +Pop-Location diff --git a/bin/helpers/incremental_checks.ps1 b/bin/helpers/incremental_checks.ps1 new file mode 100644 index 0000000..97802ce --- /dev/null +++ b/bin/helpers/incremental_checks.ps1 @@ -0,0 +1,73 @@ +# This is meant to be used with build.ps1, and is not a standalone script. + +function check-FileForChanges +{ + param( + [Parameter(Mandatory=$true)] + [string]$path_file + ) + + if (-not (Test-Path $path_file -PathType Leaf)) { + Write-Error "The provided path is not a valid file: $path_file" + return $false + } + $file_name = Split-Path $path_file -Leaf + $path_csv = Join-Path $path_build ($file_name + "_file_hash.csv") + + $csv_file_hash = $null + if (Test-Path $path_csv) { + $csv_file_hash = Import-Csv $path_csv | Select-Object -ExpandProperty value + } + + $current_hash_info = Get-FileHash -Path $path_file -Algorithm MD5 + $current_file_hash = $current_hash_info.Hash + + # Save the current hash to the CSV + [PSCustomObject]@{ + name = $path_file + value = $current_file_hash + } | Export-Csv $path_csv -NoTypeInformation + + if ($csv_file_hash -and $csv_file_hash -eq $current_file_hash) { + return $false + } else { + return $true + } +} + +# Check to see if the module has changed files since the last build +function check-ModuleForChanges +{ + param( [string]$path_module, [array]$excludes ) + + $module_name = split-path $path_module -leaf + $path_csv = Join-Path $path_build ($module_name + "_module_hashes.csv") + + $csv_file_hashes = $null + if ( test-path $path_csv ) { + $csv_file_hashes = @{} + import-csv $path_csv | foreach-object { + $csv_file_hashes[ $_.name ] = $_.value + } + } + + $file_hashes = @{} + get-childitem -path $path_module -recurse -file -Exclude $excludes | foreach-object { + $id = $_.fullname + $hash_info = get-filehash -path $id -Algorithm MD5 + $file_hashes[ $id ] = $hash_info.Hash + } + + $file_hashes.GetEnumerator() | foreach-object { [PSCustomObject]$_ } | + export-csv $path_csv -NoTypeInformation + + if ( -not $csv_file_hashes ) { return $true } + if ( $csv_file_hashes.Count -ne $file_hashes.Count ) { return $true } + + foreach ( $key in $csv_file_hashes.Keys ) { + if ( $csv_file_hashes[ $key ] -ne $file_hashes[ $key ] ) { + return $true + } + } + return $false +} diff --git a/bin/helpers/misc.psm1 b/bin/helpers/misc.psm1 new file mode 100644 index 0000000..b547ae1 --- /dev/null +++ b/bin/helpers/misc.psm1 @@ -0,0 +1,20 @@ +function Get-ScriptRepoRoot { + $currentPath = $PSScriptRoot + while ($currentPath -ne $null -and $currentPath -ne "") + { + if (Test-Path (Join-Path $currentPath ".git")) { + return $currentPath + } + # Also check for .git file which indicates a submodule + $gitFile = Join-Path $currentPath ".git" + if (Test-Path $gitFile -PathType Leaf) + { + $gitContent = Get-Content $gitFile + if ($gitContent -match "gitdir: (.+)") { + return $currentPath + } + } + $currentPath = Split-Path $currentPath -Parent + } + throw "Unable to find repository root" +} diff --git a/bin/helpers/target_arch.psm1 b/bin/helpers/target_arch.psm1 new file mode 100644 index 0000000..e6d388b --- /dev/null +++ b/bin/helpers/target_arch.psm1 @@ -0,0 +1,25 @@ +# target_arch.psm1 + +function Get-TargetArchClang { + # Get the target architecture by querying clang itself + $output = & clang -v 2>&1 + foreach ($line in $output) { + if ($line -like "*Target:*") { + $clangTarget = ($line -split ':')[1].Trim() + return $clangTarget + } + } + throw "Clang target architecture could not be determined." +} + +function Get-TargetArchMSVC { + # Assuming you've set the Visual Studio environment variables using `vcvarsall.bat` + # This looks for the `VSCMD_ARG_TGT_ARCH` environment variable which Visual Studio sets to indicate the target architecture. + $arch = $env:VSCMD_ARG_TGT_ARCH + if (-not $arch) { + throw "MSVC target architecture could not be determined. Ensure you've initialized the Visual Studio environment." + } + return $arch +} + +Export-ModuleMember -Function Get-TargetArchClang, Get-TargetArchMSVC diff --git a/bin/helpers/vendor_toolchain.ps1 b/bin/helpers/vendor_toolchain.ps1 new file mode 100644 index 0000000..d183b74 --- /dev/null +++ b/bin/helpers/vendor_toolchain.ps1 @@ -0,0 +1,604 @@ +# This is meant to be used with build.ps1, and is not a standalone script. + $target_arch = Join-Path $PSScriptRoot 'target_arch.psm1' + + import-module $target_arch + +if ($IsWindows) { + # This HandmadeHero implementation is only designed for 64-bit systems + & $devshell -arch amd64 +} + +if ( $vendor -eq $null ) { + write-host "No vendor specified, assuming clang available" + $vendor = "clang" +} + +if ( $dev ) { + if ( $debug -eq $null ) { + $debug = $true + } + if ( $optimize -eq $null ) { + $optimize = $false + } +} + +# Add new function for running lib.exe +function run-archiver +{ + param( $archiver, $library, $lib_args ) + + write-host "`Creating library $library" + if ( $verbose ) { + write-host "Lib manager config:" + $lib_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + } + + $time_taken = Measure-Command { + & $archiver $lib_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + if ( $LASTEXITCODE -eq 0 ) { + write-host "$library creation finished in $($time_taken.TotalMilliseconds) ms`n" + return $true + } + else { + write-host "Library creation failed for $library`n" -ForegroundColor Red + return $false + } +} + +function run-compiler +{ + param( $compiler, $unit, $compiler_args ) + + if ( $analysis ) { + $compiler_args += $flag_syntax_only + } + + write-host "`Compiling $unit" + if ( $verbose ) { + write-host "Compiler config:" + $compiler_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + } + + $time_taken = Measure-Command { + & $compiler $compiler_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + if ( $LASTEXITCODE -eq 0 ) { + write-host "$unit compile finished in $($time_taken.TotalMilliseconds) ms`n" + return $true + } + else { + write-host "Compile failed for $unit`n" -ForegroundColor Red + return $false + } +} + +function run-linker +{ + param( $linker, $binary, $linker_args ) + + write-host "`Linking $binary" + if ( $verbose ) { + write-host "Linker config:" + $linker_args | ForEach-Object { + write-host $_ -ForegroundColor Cyan + } + } + + $time_taken = Measure-Command { + & $linker $linker_args 2>&1 | ForEach-Object { + $color = 'White' + switch ($_){ + { $_ -match "error" } { $color = 'Red' ; break } + { $_ -match "warning" } { $color = 'Yellow'; break } + } + write-host `t $_ -ForegroundColor $color + } + } + + if ( $LASTEXITCODE -eq 0 ) { + write-host "$binary linking finished in $($time_taken.TotalMilliseconds) ms`n" + return $true + } + else { + write-host "Linking failed for $binary`n" -ForegroundColor Red + return $false + } +} + +if ( $vendor -match "clang" ) +{ + # https://clang.llvm.org/docs/ClangCommandLineReference.html + $flag_all_c = @('-x', 'c') + $flag_c11 = '-std=c11' + $flag_all_cpp = '-x c++' + $flag_compile = '-c' + $flag_color_diagnostics = '-fcolor-diagnostics' + $flag_no_color_diagnostics = '-fno-color-diagnostics' + $flag_debug = '-g' + $flag_debug_codeview = '-gcodeview' + $flag_define = '-D' + $flag_exceptions_disabled = '-fno-exceptions' + $flag_preprocess = '-E' + $flag_include = '-I' + $flag_section_data = '-fdata-sections' + $flag_section_functions = '-ffunction-sections' + $flag_library = '-l' + $flag_library_path = '-L' + $flag_linker = '-Wl,' + if ( $IsWindows ) { + $flag_link_dll = '/DLL' + $flag_link_mapfile = '/MAP:' + $flag_link_optimize_references = '/OPT:REF' + } + if ( $IsLinux ) { + $flag_link_mapfile = '--Map=' + $flag_link_optimize_references = '--gc-sections' + } + $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' + $flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' + $flag_link_win_machine_32 = '/MACHINE:X86' + $flag_link_win_machine_64 = '/MACHINE:X64' + $flag_link_win_debug = '/DEBUG' + $flag_link_win_pdb = '/PDB:' + $flag_link_win_path_output = '/OUT:' + $flag_no_optimization = '-O0' + $flag_optimize_fast = '-O2' + $flag_optimize_size = '-O1' + $flag_optimize_intrinsics = '-Oi' + $flag_path_output = '-o' + $flag_preprocess_non_intergrated = '-no-integrated-cpp' + $flag_profiling_debug = '-fdebug-info-for-profiling' + $flag_set_stack_size = '-stack=' + $flag_syntax_only = '-fsyntax-only' + $flag_target_arch = '-target' + $flag_time_trace = '-ftime-trace' + $flag_verbose = '-v' + $flag_wall = '-Wall' + $flag_warning = '-W' + $flag_warnings_as_errors = '-Werror' + $flag_win_nologo = '/nologo' + + $ignore_warning_ms_include = 'no-microsoft-include' + $ignore_warning_return_type_c_linkage = 'no-return-type-c-linkage' + + $target_arch = Get-TargetArchClang + + $warning_ignores = @( + $ignore_warning_ms_include, + $ignore_warning_return_type_c_linkage + ) + + # https://learn.microsoft.com/en-us/cpp/c-runtime-library/crt-library-features?view=msvc-170 + if ( $IsWindows ) { + $libraries = @( + 'Kernel32' # For Windows API + # 'msvcrt', # For the C Runtime (Dynamically Linked) + # 'libucrt', + 'libcmt' # For the C Runtime (Static Linkage) + ) + } + + function build + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [array]$units, [string]$binary ) + $result = $false + #Write-Host "build: clang" + + $map = $binary -replace '\.(exe|dll)$', '.map' + $map = join-path $path_output (split-path $map -Leaf) + + # This allows dll reloads at runtime to work (jankily, use below if not interested) + # $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + $pdb = $binary -replace '\.(exe|dll)$', ".pdb" + + $compiler_args += @( + $flag_no_color_diagnostics, + $flag_exceptions_disabled, + $flag_target_arch, $target_arch, + $flag_wall, + $flag_preprocess_non_intergrated + # $flag_section_data, + # $flag_section_functions, + ) + if ( $verbose ) { + # $compiler_args += $flag_verbose + # $compiler_args += $flag_time_trace + } + if ( $optimize ) { + $compiler_args += $flag_optimize_size + } + else { + $compiler_args += $flag_no_optimization + } + if ( $debug ) { + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) + $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug + } + else { + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) + } + + $warning_ignores | ForEach-Object { + $compiler_args += $flag_warning + $_ + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $objects = @() + foreach ( $unit in $units ) + { + $object = $unit -replace '\.(cpp|c)$', '.obj' + $object = join-path $path_output (split-path $object -Leaf) + $objects += $object + + $unit_compiler_args = $compiler_args + $unit_compiler_args += ( $flag_path_output + $object ) + + $unit_compiler_args += $flag_compile, $unit + run-compiler $compiler $unit $unit_compiler_args + } + + $linker_args += @( + $flag_link_win_machine_64, + $( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + + $libraries | ForEach-Object { + $linker_args += $_ + '.lib' + } + + $linker_args += $objects + return run-linker $linker $binary $linker_args + } + + function build-simple + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) + $result = $false + #Write-Host "build-simple: clang" + + $object = $unit -replace '\.(cpp|c)$', '.obj' + $map = $unit -replace '\.(cpp|c)$', '.map' + $object = join-path $path_output (split-path $object -Leaf) + $map = join-path $path_output (split-path $map -Leaf) + + # This allows dll reloads at runtime to work (jankily, use below if not interested) + # $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + $pdb = $binary -replace '\.(exe|dll)$', ".pdb" + + $compiler_args += @( + $flag_no_color_diagnostics, + $flag_exceptions_disabled, + $flag_target_arch, $target_arch, + $flag_wall, + $flag_preprocess_non_intergrated, + # $flag_section_data, + # $flag_section_functions, + ( $flag_path_output + $object ) + ) + if ( $verbose ) { + # $compiler_args += $flag_verbose + # $compiler_args += $flag_time_trace + } + if ( $optimize ) { + $compiler_args += $flag_optimize_size + } + else { + $compiler_args += $flag_no_optimization + } + if ( $debug ) { + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) + $compiler_args += $flag_debug, $flag_debug_codeview, $flag_profiling_debug + } + else { + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) + } + + $warning_ignores | ForEach-Object { + $compiler_args += $flag_warning + $_ + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $compiler_args += $flag_compile, $unit + if ( (run-compiler $compiler $unit $compiler_args) -eq $false ) { + return $false + } + + $linker_args += @( + $flag_link_win_machine_64, + $( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + + $libraries | ForEach-Object { + $linker_args += $_ + '.lib' + } + + # Check if output is a static library + if ( $binary -match '\.lib$' ) + { + $lib_args = @() + # $lib_args += $flag_nologo + # $lib_args += $flag_link_win_machine_64 + # $lib_args += ( $flag_link_win_path_output + $binary ) + # $lib_args += '--format=windows' + # $lib_args += '-X64' + $lib_args += $object + return run-archiver $archiver $binary $lib_args + } + + $linker_args += $object + return run-linker $linker $binary $linker_args + } + + $archiver = 'llvm-ar' + $compiler = 'clang++' + $linker = 'lld-link' +} + +if ( $vendor -match "msvc" ) +{ + # https://learn.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-by-category?view=msvc-170 + $flag_all_c = '/TC' + $flag_c11 = '/std:c11' + $flag_all_cpp = '/TP' + $flag_compile = '/c' + $flag_debug = '/Zi' + $flag_define = '/D' + $flag_exceptions_disabled = '/EHsc-' + $flag_RTTI_disabled = '/GR-' + $flag_include = '/I' + $flag_full_src_path = '/FC' + $flag_nologo = '/nologo' + $flag_dll = '/LD' + $flag_dll_debug = '/LDd' + $flag_linker = '/link' + # $flag_link_lib = '/lib' + $flag_link_dll = '/DLL' + $flag_link_no_incremental = '/INCREMENTAL:NO' + $flag_link_mapfile = '/MAP:' + $flag_link_optimize_references = '/OPT:REF' + $flag_link_win_debug = '/DEBUG' + $flag_link_win_pdb = '/PDB:' + $flag_link_win_machine_32 = '/MACHINE:X86' + $flag_link_win_machine_64 = '/MACHINE:X64' + $flag_link_win_path_output = '/OUT:' + $flag_link_win_rt_dll = '/MD' + $flag_link_win_rt_dll_debug = '/MDd' + $flag_link_win_rt_static = '/MT' + $flag_link_win_rt_static_debug = '/MTd' + $flag_link_win_subsystem_console = '/SUBSYSTEM:CONSOLE' + $flag_link_win_subsystem_windows = '/SUBSYSTEM:WINDOWS' + $flag_no_optimization = '/Od' + $flag_optimize_fast = '/O2' + $flag_optimize_size = '/O1' + $flag_optimize_intrinsics = '/Oi' + $flag_optimized_debug_forceinline = '/d2Obforceinline' + $flag_optimized_debug = '/Zo' + $flag_ + # $flag_out_name = '/OUT:' + $flag_path_interm = '/Fo' + $flag_path_debug = '/Fd' + $flag_path_output = '/Fe' + $flag_preprocess_conform = '/Zc:preprocessor' + $flag_updated_cpp_macro = "/Zc:__cplusplus" + $flag_set_stack_size = '/F' + $flag_syntax_only = '/Zs' + $flag_wall = '/Wall' + $flag_warnings_as_errors = '/WX' + $flag_lib_list = '/LIST' + + function build + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [array]$units, [string]$binary ) + $result = $false + #Write-Host "build-simple: msvc" + + $map = $binary -replace '\.(exe|dll)$', '.map' + $map = join-path $path_output (split-path $map -Leaf) + + # This allows dll reloads at runtime to work (jankily, use below if not interested) + # $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + $pdb = $binary -replace '\.(exe|dll)$', ".pdb" + + $compiler_args += @( + $flag_nologo, + # $flag_all_cpp, + $flag_exceptions_disabled, + ( $flag_define + '_HAS_EXCEPTIONS=0' ), + $flag_RTTI_disabled, + $flag_preprocess_conform, + $flag_full_src_path, + ( $flag_path_interm + $path_output + '\' ), + ( $flag_path_output + $path_output + '\' ) + ) + + if ( $verbose ) { + } + + if ( $optimize ) { + $compiler_args += $flag_optimize_size + } + else { + $compiler_args += $flag_no_optimization + } + + if ( $debug ) + { + $compiler_args += $flag_debug + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) + $compiler_args += ( $flag_path_debug + $path_output + '\' ) + $compiler_args += $flag_link_win_rt_static_debug + + if ( $optimize ) { + $compiler_args += $flag_optimized_debug + $compiler_args += $flag_optimized_debug_forceinline + } + } + else { + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) + $compiler_args += $flag_link_win_rt_static + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $objects = @() + foreach ( $unit in $units ) + { + $object = $unit -replace '\.(cpp|c)$', '.obj' + $object = join-path $path_output (split-path $object -Leaf) + $objects += $object + + $unit_compiler_args = $compiler_args + # $unit_compiler_args += ( $flag_path_output + $object ) + + $unit_compiler_args += $flag_compile, $unit + run-compiler $compiler $unit $unit_compiler_args + } + + $linker_args += @( + $flag_nologo, + $flag_link_win_machine_64, + $flag_link_no_incremental, + ( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + else { + } + + $linker_args += $objects + return run-linker $linker $binary $linker_args + } + + function build-simple + { + param( [string]$path_output, [array]$includes, [array]$compiler_args, [array]$linker_args, [string]$unit, [string]$binary ) + $result = $false + #Write-Host "build-simple: msvc" + + $object = $unit -replace '\.(cpp|c)$', '.obj' + $map = $unit -replace '\.(cpp|c)$', '.map' + $object = join-path $path_output (split-path $object -Leaf) + $map = join-path $path_output (split-path $map -Leaf) + + # This allows dll reloads at runtime to work (jankily, use below if not interested) + # $pdb = $binary -replace '\.(exe|dll)$', "_$(get-random).pdb" + $pdb = $binary -replace '\.(exe|dll)$', ".pdb" + + $compiler_args += @( + $flag_nologo, + # $flag_all_cpp, + $flag_exceptions_disabled, + ( $flag_define + '_HAS_EXCEPTIONS=0' ), + $flag_RTTI_disabled, + $flag_preprocess_conform, + $flag_full_src_path, + ( $flag_path_interm + $path_output + '\' ), + ( $flag_path_output + $path_output + '\' ) + ) + + if ( $verbose ) { + } + + if ( $optimize ) { + $compiler_args += $flag_optimize_size + } + else { + $compiler_args += $flag_no_optimization + } + + if ( $debug ) + { + $compiler_args += $flag_debug + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=1' ) + $compiler_args += ( $flag_path_debug + $path_output + '\' ) + $compiler_args += $flag_link_win_rt_static_debug + + if ( $optimize ) { + $compiler_args += $flag_optimized_debug + } + } + else { + $compiler_args += ( $flag_define + 'GEN_BUILD_DEBUG=0' ) + $compiler_args += $flag_link_win_rt_static + } + $compiler_args += $includes | ForEach-Object { $flag_include + $_ } + + $compiler_args += $flag_compile, $unit + if ( (run-compiler $compiler $unit $compiler_args) -eq $false ) { + return $false; + } + + # Check if output is a static library + if ( $binary -match '\.lib$' ) + { + $lib_args = @() + $lib_args += $flag_nologo + $lib_args += $flag_link_win_machine_64 + $lib_args += ( $flag_link_win_path_output + $binary ) + $lib_args += $object + return run-archiver $archiver $binary $lib_args + } + + $linker_args += @( + $flag_nologo, + $flag_link_win_machine_64, + $flag_link_no_incremental, + ( $flag_link_win_path_output + $binary ) + ) + if ( $debug ) { + $linker_args += $flag_link_win_debug + $linker_args += $flag_link_win_pdb + $pdb + $linker_args += $flag_link_mapfile + $map + } + else { + } + + # Check if output is a dynamic library + if ( $binary -match '\.dll$' ) { + $linker_args += $flag_link_dll + } + $linker_args += $object + # Write-Host "link args:" + # $linker_args | ForEach-Object { + # Write-Host "`t$_" -ForegroundColor Yellow + # } + return run-linker $linker $binary $linker_args + } + + $archiver = 'lib' + $compiler = 'cl' + $linker = 'link' +}