Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get MSVC builds working on x86_64; add MSVC build targets that link the dynamic MSVC runtime #12

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
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
23 changes: 17 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,20 @@ jobs:
# 'aarch64-windows-msvc',
]
optimize: [Debug, ReleaseFast]
link-mode: ['Static', 'Dynamic']
include:
- target: 'x86_64-windows-msvc'
link-mode: 'Static'
cpu: '-Dcpu=x86_64_v2'
link-flags: ''
post-build: 'install dxc'
target-postfix: ''
- target: 'x86_64-windows-msvc'
link-mode: 'Dynamic'
cpu: '-Dcpu=x86_64_v2'
link-flags: '-Dmsvcrt_dynamic -Dskip_executables'
post-build: ''
target-postfix: '_Dynamic'
runs-on: windows-latest
steps:
- name: Checkout
Expand All @@ -97,22 +108,22 @@ jobs:
7z x zig.zip
Add-Content $env:GITHUB_PATH "C:\zig-windows-x86_64-0.14.0-dev.1911+3bf89f55c\"
- name: build
run: zig build -Dfrom_source -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }} ${{ matrix.cpu }} install dxc
run: zig build -Dfrom_source -Dtarget=${{ matrix.target }} -Doptimize=${{ matrix.optimize }} ${{ matrix.cpu }} ${{ matrix.link-flags }} ${{ matrix.post-build }}
- name: upload
run: |
ZSTD_CLEVEL=19 tar -acf "${TARGET_OPT}_lib.tar.zst" -C zig-out/lib .
ZSTD_CLEVEL=19 tar -acf "${TARGET_OPT}_bin.tar.zst" -C zig-out/bin .
if [[ "${{ matrix.link-mode }}" == "Static" ]]; then ZSTD_CLEVEL=19 tar -acf "${TARGET_OPT}_bin.tar.zst" -C zig-out/bin . ; fi
ZSTD_CLEVEL=19 tar -acf "${TARGET_OPT}_lib.tar.gz" -C zig-out/lib .
ZSTD_CLEVEL=19 tar -acf "${TARGET_OPT}_bin.tar.gz" -C zig-out/bin .
if [[ "${{ matrix.link-mode }}" == "Static" ]]; then ZSTD_CLEVEL=19 tar -acf "${TARGET_OPT}_bin.tar.gz" -C zig-out/bin . ; fi
export RELEASE="$(date -u +%Y.%m.%d)+$(git rev-parse --short HEAD).${{ github.run_attempt }}"
gh release upload "$RELEASE" "${TARGET_OPT}_lib.tar.zst"
gh release upload "$RELEASE" "${TARGET_OPT}_bin.tar.zst"
if [[ "${{ matrix.link-mode }}" == "Static" ]]; then gh release upload "$RELEASE" "${TARGET_OPT}_bin.tar.zst"; fi
gh release upload "$RELEASE" "${TARGET_OPT}_lib.tar.gz"
gh release upload "$RELEASE" "${TARGET_OPT}_bin.tar.gz"
if [[ "${{ matrix.link-mode }}" == "Static" ]]; then gh release upload "$RELEASE" "${TARGET_OPT}_bin.tar.gz"; fi
shell: bash
env:
WINDOWS: true
TARGET_OPT: ${{ matrix.target }}_${{ matrix.optimize }}
TARGET_OPT: ${{ matrix.target }}_${{ matrix.optimize }}${{ matrix.target-postfix }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish:
# TODO: re-enable required MSVC builds
Expand Down
13 changes: 11 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub fn build(b: *Build) !void {
const debug_symbols = b.option(bool, "debug_symbols", "Whether to produce detailed debug symbols (g0) or not. These increase binary size considerably.") orelse false;
const build_shared = b.option(bool, "shared", "Build dxcompiler shared libraries") orelse false;
const build_spirv = b.option(bool, "spirv", "Build spir-v compilation support") orelse false;
const msvcrt_dynamic = b.option(bool, "msvcrt_dynamic", "Link with the dynamic MSVC runtime") orelse false;
const skip_executables = b.option(bool, "skip_executables", "Skip building executables") orelse false;
const skip_tests = b.option(bool, "skip_tests", "Skip building tests") orelse false;

Expand Down Expand Up @@ -64,7 +65,10 @@ pub fn build(b: *Build) !void {

lib.addCSourceFile(.{
.file = b.path("src/mach_dxc.cpp"),
.flags = &.{
.flags = if (msvcrt_dynamic) &.{
"-fms-extensions", // __uuidof and friends (on non-windows targets)
"-fms-runtime-lib=dll",
} else &.{
"-fms-extensions", // __uuidof and friends (on non-windows targets)
},
});
Expand Down Expand Up @@ -96,6 +100,11 @@ pub fn build(b: *Build) !void {
try cflags.appendSlice(base_flags);
try cppflags.appendSlice(base_flags);

if (msvcrt_dynamic) {
try cflags.append("-fms-runtime-lib=dll");
try cppflags.append("-fms-runtime-lib=dll");
}

addConfigHeaders(b, lib);
addIncludes(b, lib);

Expand Down Expand Up @@ -254,7 +263,7 @@ pub fn build(b: *Build) !void {

// For some reason, msvc target needs atls.lib to be in the 'zig build' working directory.
// Addomg tp the library path like this has no effect:
dxc_exe.addLibraryPath(b.path(lib_dir_path));
dxc_exe.addLibraryPath(.{ .cwd_relative = lib_dir_path });
// So instead we must copy the lib into this directory:
try std.fs.cwd().copyFile(lib_path, std.fs.cwd(), "atls.lib", .{});
try std.fs.cwd().copyFile(pdb_path, std.fs.cwd(), pdb_name, .{});
Expand Down
16 changes: 8 additions & 8 deletions msvc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const RegistryUtf8 = struct {
const value_utf16le = try registry_utf16le.getString(allocator, subkey_utf16le, value_name_utf16le);
defer allocator.free(value_utf16le);

const value_utf8: []u8 = std.unicode.utf16leToUtf8Alloc(allocator, value_utf16le) catch |err| switch (err) {
const value_utf8: []u8 = std.unicode.utf16LeToUtf8Alloc(allocator, value_utf16le) catch |err| switch (err) {
error.OutOfMemory => return error.OutOfMemory,
else => return error.StringNotFound,
};
Expand Down Expand Up @@ -368,7 +368,7 @@ pub const Windows10Sdk = struct {
error.OutOfMemory => return error.OutOfMemory,
};

if (path_maybe_with_trailing_slash.len > std.fs.MAX_PATH_BYTES or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
if (path_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
allocator.free(path_maybe_with_trailing_slash);
return error.PathTooLong;
}
Expand Down Expand Up @@ -414,7 +414,7 @@ pub const Windows10Sdk = struct {

/// Check whether this version is enumerated in registry.
fn isValidVersion(windows10sdk: *const Windows10Sdk) bool {
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var buf: [std.fs.max_path_bytes]u8 = undefined;
const reg_query_as_utf8 = std.fmt.bufPrint(buf[0..], "{s}\\{s}\\Installed Options", .{ WINDOWS_KIT_REG_KEY, windows10sdk.version }) catch |err| switch (err) {
error.NoSpaceLeft => return false,
};
Expand Down Expand Up @@ -458,7 +458,7 @@ pub const Windows81Sdk = struct {

error.OutOfMemory => return error.OutOfMemory,
};
if (path_maybe_with_trailing_slash.len > std.fs.MAX_PATH_BYTES or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
if (path_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
allocator.free(path_maybe_with_trailing_slash);
return error.PathTooLong;
}
Expand All @@ -475,7 +475,7 @@ pub const Windows81Sdk = struct {
errdefer allocator.free(path);

const version: []const u8 = version81: {
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
var buf: [std.fs.max_path_bytes]u8 = undefined;
const sdk_lib_dir_path = std.fmt.bufPrint(buf[0..], "{s}\\Lib\\", .{path}) catch |err| switch (err) {
error.NoSpaceLeft => return error.PathTooLong,
};
Expand Down Expand Up @@ -822,7 +822,7 @@ pub const MsvcLibDir = struct {
error.OutOfMemory => return error.OutOfMemory,
else => continue,
};
if (source_directories_value.len > (std.fs.MAX_PATH_BYTES * 30)) { // note(bratishkaerik): guessing from the fact that on my computer it has 15 pathes and at least some of them are not of max length
if (source_directories_value.len > (std.fs.max_path_bytes * 30)) { // note(bratishkaerik): guessing from the fact that on my computer it has 15 pathes and at least some of them are not of max length
allocator.free(source_directories_value);
continue;
}
Expand All @@ -836,7 +836,7 @@ pub const MsvcLibDir = struct {
const msvc_dir: []const u8 = msvc_dir: {
const msvc_include_dir_maybe_with_trailing_slash = try allocator.dupe(u8, source_directories_splitted.first());

if (msvc_include_dir_maybe_with_trailing_slash.len > std.fs.MAX_PATH_BYTES or !std.fs.path.isAbsolute(msvc_include_dir_maybe_with_trailing_slash)) {
if (msvc_include_dir_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(msvc_include_dir_maybe_with_trailing_slash)) {
allocator.free(msvc_include_dir_maybe_with_trailing_slash);
return error.PathNotFound;
}
Expand Down Expand Up @@ -904,7 +904,7 @@ pub const MsvcLibDir = struct {
else => break :try_vs7_key,
};

if (path_maybe_with_trailing_slash.len > std.fs.MAX_PATH_BYTES or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
if (path_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
allocator.free(path_maybe_with_trailing_slash);
break :try_vs7_key;
}
Expand Down
2 changes: 1 addition & 1 deletion msvc/wrl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace Microsoft {

typedef int BoolStruct::* BoolType;

inline void DECLSPEC_NORETURN RaiseException(HRESULT hr, DWORD flags = EXCEPTION_NONCONTINUABLE) throw() {
inline void RaiseException(HRESULT hr, DWORD flags = EXCEPTION_NONCONTINUABLE) throw() {
::RaiseException(static_cast<DWORD>(hr), flags, 0, NULL);
}

Expand Down
31 changes: 15 additions & 16 deletions src/mach_dxc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
#ifdef _MSC_VER
#define __C89_NAMELESS
#define __C89_NAMELESSUNIONNAME
#define WIN32_LEAN_AND_MEAN
#include <atlbase.h>
#include <locale.h>
#include <windows.h>
#include <wrl/client.h>
#define CComPtr Microsoft::WRL::ComPtr
#else // _MSC_VER
#include <windows.h>
#include <wrl/client.h>
Expand Down Expand Up @@ -35,7 +34,7 @@ char* wcstombsAlloc(const wchar_t* inval)

auto buf = (char*)std::malloc(outsz);
std::memset(buf, 0, outsz);
std::setlocale(LC_CTYPE,"");
setlocale(LC_CTYPE,"");
size = std::wcstombs(buf, inval, size * sizeof(wchar_t));

if (size == (size_t)(-1)) {
Expand Down Expand Up @@ -79,7 +78,7 @@ class MachDxcIncludeHandler : public IDxcIncludeHandler
char* filename_utf8 = wcstombsAlloc(filename);

if (filename_utf8 == nullptr)
filename_utf8 = strdup(u8"");
filename_utf8 = _strdup(u8"");

MachDxcIncludeResult* include_result = callbacks->include_func(callbacks->include_ctx, filename_utf8);

Expand Down Expand Up @@ -117,7 +116,7 @@ MACH_EXPORT MachDxcCompiler machDxcInit() {
}

MACH_EXPORT void machDxcDeinit(MachDxcCompiler compiler) {
CComPtr<IDxcCompiler3> dxcInstance = CComPtr(reinterpret_cast<IDxcCompiler3*>(compiler));
CComPtr<IDxcCompiler3> dxcInstance = CComPtr<IDxcCompiler3>(reinterpret_cast<IDxcCompiler3*>(compiler));
dxcInstance.Release();
MachDxcompilerInvokeDllShutdown();
}
Expand All @@ -130,7 +129,7 @@ MACH_EXPORT MachDxcCompileResult machDxcCompile(
MachDxcCompiler compiler,
MachDxcCompileOptions* options
) {
CComPtr<IDxcCompiler3> dxcInstance = CComPtr(reinterpret_cast<IDxcCompiler3*>(compiler));
CComPtr<IDxcCompiler3> dxcInstance = CComPtr<IDxcCompiler3>(reinterpret_cast<IDxcCompiler3*>(compiler));

CComPtr<IDxcUtils> pUtils;
DxcCreateInstance(CLSID_DxcUtils, IID_PPV_ARGS(&pUtils));
Expand Down Expand Up @@ -180,7 +179,7 @@ MACH_EXPORT MachDxcCompileResult machDxcCompile(
}

MACH_EXPORT MachDxcCompileError machDxcCompileResultGetError(MachDxcCompileResult err) {
CComPtr<IDxcResult> pCompileResult = CComPtr(reinterpret_cast<IDxcResult*>(err));
CComPtr<IDxcResult> pCompileResult = CComPtr<IDxcResult>(reinterpret_cast<IDxcResult*>(err));

CComPtr<IDxcBlobEncoding> pErrors = nullptr;
HRESULT hr = pCompileResult->GetErrorBuffer(&pErrors);
Expand All @@ -193,7 +192,7 @@ MACH_EXPORT MachDxcCompileError machDxcCompileResultGetError(MachDxcCompileResul
}

MACH_EXPORT MachDxcCompileObject machDxcCompileResultGetObject(MachDxcCompileResult err) {
CComPtr<IDxcResult> pCompileResult = CComPtr(reinterpret_cast<IDxcResult*>(err));
CComPtr<IDxcResult> pCompileResult = CComPtr<IDxcResult>(reinterpret_cast<IDxcResult*>(err));

CComPtr<IDxcBlob> pObject = nullptr;
HRESULT hr = pCompileResult->GetResult(&pObject);
Expand All @@ -206,43 +205,43 @@ MACH_EXPORT MachDxcCompileObject machDxcCompileResultGetObject(MachDxcCompileRes
}

MACH_EXPORT void machDxcCompileResultDeinit(MachDxcCompileResult err) {
CComPtr<IDxcResult> pCompileResult = CComPtr(reinterpret_cast<IDxcResult*>(err));
CComPtr<IDxcResult> pCompileResult = CComPtr<IDxcResult>(reinterpret_cast<IDxcResult*>(err));
pCompileResult.Release();
}

//---------------------
// MachDxcCompileObject
//---------------------
MACH_EXPORT char const* machDxcCompileObjectGetBytes(MachDxcCompileObject err) {
CComPtr<IDxcBlob> pObject = CComPtr(reinterpret_cast<IDxcBlob*>(err));
CComPtr<IDxcBlob> pObject = CComPtr<IDxcBlob>(reinterpret_cast<IDxcBlob*>(err));
return (char const*)(pObject->GetBufferPointer());
}

MACH_EXPORT size_t machDxcCompileObjectGetBytesLength(MachDxcCompileObject err) {
CComPtr<IDxcBlob> pObject = CComPtr(reinterpret_cast<IDxcBlob*>(err));
CComPtr<IDxcBlob> pObject = CComPtr<IDxcBlob>(reinterpret_cast<IDxcBlob*>(err));
return pObject->GetBufferSize();
}

MACH_EXPORT void machDxcCompileObjectDeinit(MachDxcCompileObject err) {
CComPtr<IDxcBlob> pObject = CComPtr(reinterpret_cast<IDxcBlob*>(err));
CComPtr<IDxcBlob> pObject = CComPtr<IDxcBlob>(reinterpret_cast<IDxcBlob*>(err));
pObject.Release();
}

//--------------------
// MachDxcCompileError
//--------------------
MACH_EXPORT char const* machDxcCompileErrorGetString(MachDxcCompileError err) {
CComPtr<IDxcBlobUtf8> pErrors = CComPtr(reinterpret_cast<IDxcBlobUtf8*>(err));
CComPtr<IDxcBlobUtf8> pErrors = CComPtr<IDxcBlobUtf8>(reinterpret_cast<IDxcBlobUtf8*>(err));
return (char const*)(pErrors->GetBufferPointer());
}

MACH_EXPORT size_t machDxcCompileErrorGetStringLength(MachDxcCompileError err) {
CComPtr<IDxcBlobUtf8> pErrors = CComPtr(reinterpret_cast<IDxcBlobUtf8*>(err));
CComPtr<IDxcBlobUtf8> pErrors = CComPtr<IDxcBlobUtf8>(reinterpret_cast<IDxcBlobUtf8*>(err));
return pErrors->GetStringLength();
}

MACH_EXPORT void machDxcCompileErrorDeinit(MachDxcCompileError err) {
CComPtr<IDxcBlobUtf8> pErrors = CComPtr(reinterpret_cast<IDxcBlobUtf8*>(err));
CComPtr<IDxcBlobUtf8> pErrors = CComPtr<IDxcBlobUtf8>(reinterpret_cast<IDxcBlobUtf8*>(err));
pErrors.Release();
}

Expand Down