Skip to content

Fix Windows build for cl.exe and clang targeting MSVC - #271

Open
zzyxyz666 wants to merge 1 commit into
tsoding:mainfrom
zzyxyz666:fix-windows-msvc-compile
Open

Fix Windows build for cl.exe and clang targeting MSVC#271
zzyxyz666 wants to merge 1 commit into
tsoding:mainfrom
zzyxyz666:fix-windows-msvc-compile

Conversation

@zzyxyz666

@zzyxyz666 zzyxyz666 commented Aug 19, 2026

Copy link
Copy Markdown

Make the build and tests work on Windows with both MSVC cl.exe and
clang targeting x86_64-pc-windows-msvc, in both C and C++ modes.

  • shared.h: for cl.exe add /utf-8 to the C (/TC) and C++
    (/std:c++20 /TP) flag sets so UTF-8 sources compile correctly on
    Windows. For clang targeting MSVC use clang-style flags (-std=c99 /
    -x c++, -Wall, -Wswitch-enum, ...) instead of the MSVC-only
    flags that its driver rejects.
  • nob.h: make nob_cc_output append .exe when building with clang
    targeting MSVC (-o<path>.exe) so the produced binary matches the
    ../<test>.exe run command. cl.exe already emits <path>.exe
    through /Fe, and non-Windows builds are unchanged.
  • nob.h: include <consoleapi2.h> and undef the private SDK guards
    (_WINUSER_, _WINGDI_, _IMM_, _WINCON_) and
    WIN32_LEAN_AND_MEAN after the system includes so
    SetConsoleOutputCP() is declared even when compiling with
    cl.exe /TP. Also #undef UNICODE so the generic WinAPI names keep
    resolving to the ANSI variants the rest of the code uses. Undefing
    the guards is also required for downstream code that includes
    <windows.h> after nob.h to still get the winuser.h /
    wingdi.h / imm.h / wincon.h declarations (<windows.h> cannot
    be included before nob.h because of the ERROR macro clash).
  • nob.c: remove the extern "C" workaround for SetConsoleOutputCP(),
    no longer needed with the header fix above.

Testing

  • cl.exe /TC and cl.exe /std:c++20 /TP: all tests pass
  • clang -x c and clang -x c++: all tests pass
  • clang-cl /TC and clang-cl /std:c++20 /TP: all tests pass
  • gcc -x c and gcc -x c++: all tests pass
  • compiler versions: clang version 21.1.0 cl version 19.44.35222 gcc.exe (Rev11, Built by MSYS2 project) 15.2.0 ``

Related: #193 (an earlier, partial attempt that only covered the C flag
set and predates the C++ support split).

Make the build and tests work on Windows with both MSVC cl.exe and
clang targeting x86_64-pc-windows-msvc, in both C and C++ modes.

- shared.h: for cl.exe add /utf-8 to the C (/TC) and C++ (/std:c++20
  /TP) flag sets so UTF-8 sources compile correctly on Windows. For
  clang targeting MSVC use clang-style flags (-std=c99 / -x c++,
  -Wall, -Wswitch-enum, ...) instead of the MSVC-only flags that its
  driver rejects.

- nob.h: make nob_cc_output append ".exe" when building with clang
  targeting MSVC (-o<path>.exe) so the produced binary matches the
  "../<test>.exe" run command. cl.exe already emits "<path>.exe"
  through /Fe, and non-Windows builds are unchanged.

- nob.h: include <consoleapi2.h> and undef the private SDK guards
  (_WINUSER_, _WINGDI_, _IMM_, _WINCON_) and WIN32_LEAN_AND_MEAN after
  the system includes so SetConsoleOutputCP() is declared even when
  compiling with cl.exe /TP. Also undef UNICODE so the generic WinAPI
  names keep resolving to the ANSI variants the rest of the code uses.

- nob.c: remove the extern "C" workaround for SetConsoleOutputCP(),
  no longer needed with the header fix above.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant