Skip to content
Merged
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
7 changes: 5 additions & 2 deletions .github/workflows/nob.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ jobs:
${{ matrix.cc }} -x ${{ matrix.lang }} -o nob nob.c
./nob
windows:
strategy:
matrix:
mode: ["/TC", "/std:c++20 /TP"]
runs-on: windows-latest
steps:
- name: Clone GIT repo
Expand All @@ -50,12 +53,12 @@ jobs:
# https://learn.microsoft.com/en-us/cpp/build/building-on-the-command-line?view=msvc-170#create-your-own-command-prompt-shortcut
run: |
call "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Auxiliary\\Build\\vcvars64.bat"
cl.exe /Fe:nob nob.c
cl.exe ${{ matrix.mode }} /Fe:nob nob.c
nob.exe
- name: Build how_to-s
shell: cmd
run: |
call "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Auxiliary\\Build\\vcvars64.bat"
cd how_to/
cl.exe /Fe:nob nob.c
cl.exe ${{ matrix.mode }} /Fe:nob nob.c
nob.exe
3 changes: 2 additions & 1 deletion how_to/001_basic_usage/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
nob
nob.old
build/
build/
*.obj
12 changes: 10 additions & 2 deletions nob.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,16 @@ void print_available_commands(Commands commands)
}
}

#if defined(_WIN32) && defined(_MSC_VER) && defined(__cplusplus)
// TODO: I don't know why, but when you compile nob.c with
// cl.exe /std:c++20 /TP nob.c
// It just can't find the declaration of SetConsoleOutputCP().
// This is probably something about how we include windows.h in nob.h
extern "C" {
WINBASEAPI BOOL WINAPI SetConsoleOutputCP(_In_ UINT wCodePageID);
}
#endif

int main(int argc, char **argv)
{
#ifdef _WIN32
Expand All @@ -172,8 +182,6 @@ int main(int argc, char **argv)

set_log_handler(cancer_log_handler);

Cmd cmd = {0};

const char *program_name = shift(argv, argc);
const char *command_name = "test";
if (argc > 0) command_name = shift(argv, argc);
Expand Down
49 changes: 30 additions & 19 deletions nob.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* nob - v3.7.0 - Public Domain - https://github.com/tsoding/nob.h
/* nob - v3.8.0 - Public Domain - https://github.com/tsoding/nob.h

This library is the next generation of the [NoBuild](https://github.com/tsoding/nobuild) idea.

Expand Down Expand Up @@ -303,7 +303,7 @@ typedef struct {

NOBDEF bool nob_walk_dir_opt(const char *root, Nob_Walk_Func func, Nob_Walk_Dir_Opt);

#define nob_walk_dir(root, func, ...) nob_walk_dir_opt((root), (func), (Nob_Walk_Dir_Opt){__VA_ARGS__})
#define nob_walk_dir(root, func, ...) nob_walk_dir_opt((root), (func), NOB_CLIT(Nob_Walk_Dir_Opt){__VA_ARGS__})

typedef struct {
char *name;
Expand Down Expand Up @@ -585,14 +585,14 @@ typedef struct {
typedef struct {
const char *stdin_path;
} Nob_Chain_Begin_Opt;
#define nob_chain_begin(chain, ...) nob_chain_begin_opt((chain), (Nob_Chain_Begin_Opt) { __VA_ARGS__ })
#define nob_chain_begin(chain, ...) nob_chain_begin_opt((chain), NOB_CLIT(Nob_Chain_Begin_Opt) { __VA_ARGS__ })
NOBDEF bool nob_chain_begin_opt(Nob_Chain *chain, Nob_Chain_Begin_Opt opt);

typedef struct {
bool err2out;
bool dont_reset;
} Nob_Chain_Cmd_Opt;
#define nob_chain_cmd(chain, cmd, ...) nob_chain_cmd_opt((chain), (cmd), (Nob_Chain_Cmd_Opt) { __VA_ARGS__ })
#define nob_chain_cmd(chain, cmd, ...) nob_chain_cmd_opt((chain), (cmd), NOB_CLIT(Nob_Chain_Cmd_Opt) { __VA_ARGS__ })
NOBDEF bool nob_chain_cmd_opt(Nob_Chain *chain, Nob_Cmd *cmd, Nob_Chain_Cmd_Opt opt);

typedef struct {
Expand All @@ -601,7 +601,7 @@ typedef struct {
const char *stdout_path;
const char *stderr_path;
} Nob_Chain_End_Opt;
#define nob_chain_end(chain, ...) nob_chain_end_opt((chain), (Nob_Chain_End_Opt) { __VA_ARGS__ })
#define nob_chain_end(chain, ...) nob_chain_end_opt((chain), NOB_CLIT(Nob_Chain_End_Opt) { __VA_ARGS__ })
NOBDEF bool nob_chain_end_opt(Nob_Chain *chain, Nob_Chain_End_Opt opt);

// Get amount of processors on the machine.
Expand All @@ -614,7 +614,7 @@ NOBDEF uint64_t nob_nanos_since_unspecified_epoch(void);

// Same as nob_cmd_run_opt but using cool variadic macro to set the default options.
// See https://x.com/vkrajacic/status/1749816169736073295 for more info on how to use such macros.
#define nob_cmd_run(cmd, ...) nob_cmd_run_opt((cmd), (Nob_Cmd_Opt){__VA_ARGS__})
#define nob_cmd_run(cmd, ...) nob_cmd_run_opt((cmd), NOB_CLIT(Nob_Cmd_Opt){__VA_ARGS__})

// DEPRECATED:
//
Expand Down Expand Up @@ -651,9 +651,16 @@ typedef struct {
// use it as a C string.
NOBDEF void nob_cmd_render(Nob_Cmd cmd, Nob_String_Builder *render);

NOBDEF void nob__cmd_append(Nob_Cmd *cmd, size_t n, ...);
// Compound Literal
#if defined(__cplusplus)
#define NOB_CLIT(type) type
#else
#define NOB_CLIT(type) (type)
#endif

NOBDEF void nob__cmd_append(Nob_Cmd *cmd, ...);
#define nob_cmd_append(cmd, ...) \
nob__cmd_append(cmd, (sizeof((const char*[]){__VA_ARGS__})/sizeof(const char*)), __VA_ARGS__)
nob__cmd_append(cmd, __VA_ARGS__, (const char*)-1)

// TODO: nob_cmd_extend() evaluates other_cmd twice
// It can be fixed by turning nob_cmd_extend() call into a statement.
Expand Down Expand Up @@ -950,12 +957,13 @@ static Nob_Proc nob__cmd_start_process(Nob_Cmd cmd, Nob_Fd *fdin, Nob_Fd *fdout,
// Any messages with the level below nob_minimal_log_level are going to be suppressed.
Nob_Log_Level nob_minimal_log_level = NOB_INFO;

NOBDEF void nob__cmd_append(Nob_Cmd *cmd, size_t n, ...)
NOBDEF void nob__cmd_append(Nob_Cmd *cmd, ...)
{
va_list args;
va_start(args, n);
for (size_t i = 0; i < n; ++i) {
va_start(args, cmd);
for (;;) {
const char *arg = va_arg(args, const char *);
if (arg == (const char*)-1) break;
nob_da_append(cmd, arg);
}
va_end(args);
Expand Down Expand Up @@ -2020,7 +2028,7 @@ bool nob__walk_dir_opt_impl(Nob_String_Builder *file_path, Nob_Walk_Func func, s

// Pre-order walking
if (!opt.post_order) {
if (!func((Nob_Walk_Entry) {
if (!func(NOB_CLIT(Nob_Walk_Entry) {
.path = file_path->items,
.type = file_type,
.level = level,
Expand Down Expand Up @@ -2067,7 +2075,7 @@ bool nob__walk_dir_opt_impl(Nob_String_Builder *file_path, Nob_Walk_Func func, s

// Post-order walking
if (opt.post_order) {
if (!func((Nob_Walk_Entry) {
if (!func(NOB_CLIT(Nob_Walk_Entry) {
.path = file_path->items,
.type = file_type,
.level = level,
Expand Down Expand Up @@ -2159,7 +2167,7 @@ NOBDEF Nob_File_Type nob_get_file_type(const char *path)
DWORD attr = GetFileAttributesA(path);
if (attr == INVALID_FILE_ATTRIBUTES) {
nob_log(NOB_ERROR, "Could not get file attributes of %s: %s", path, nob_win32_error_message(GetLastError()));
return -1;
return (Nob_File_Type)-1;
}

if (attr & FILE_ATTRIBUTE_DIRECTORY) return NOB_FILE_DIRECTORY;
Expand Down Expand Up @@ -2754,8 +2762,8 @@ NOBDEF char *nob_temp_dir_name(const char *path)
return nob_temp_strndup(path, i + 1);
#else
if (!path) path = ""; // Treating NULL as empty.
char *drive = nob_temp_alloc(_MAX_DRIVE);
char *dir = nob_temp_alloc(_MAX_DIR);
char *drive = (char*) nob_temp_alloc(_MAX_DRIVE);
char *dir = (char*) nob_temp_alloc(_MAX_DIR);
// https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/8e46eyt7(v=vs.100)
errno_t ret = _splitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, NULL, 0, NULL, 0);
NOB_ASSERT(ret == 0);
Expand All @@ -2777,8 +2785,8 @@ NOBDEF char *nob_temp_file_name(const char *path)
return s+i;
#else
if (!path) path = ""; // Treating NULL as empty.
char *fname = nob_temp_alloc(_MAX_FNAME);
char *ext = nob_temp_alloc(_MAX_EXT);
char *fname = (char*)nob_temp_alloc(_MAX_FNAME);
char *ext = (char*)nob_temp_alloc(_MAX_EXT);
// https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/8e46eyt7(v=vs.100)
errno_t ret = _splitpath_s(path, NULL, 0, NULL, 0, fname, _MAX_FNAME, ext, _MAX_EXT);
NOB_ASSERT(ret == 0);
Expand All @@ -2792,7 +2800,7 @@ NOBDEF char *nob_temp_file_ext(const char *path)
return strrchr(nob_temp_file_name(path), '.');
#else
if (!path) path = ""; // Treating NULL as empty.
char *ext = nob_temp_alloc(_MAX_EXT);
char *ext = (char*)nob_temp_alloc(_MAX_EXT);
// https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/8e46eyt7(v=vs.100)
errno_t ret = _splitpath_s(path, NULL, 0, NULL, 0, NULL, 0, ext, _MAX_EXT);
NOB_ASSERT(ret == 0);
Expand Down Expand Up @@ -2946,6 +2954,7 @@ NOBDEF char *nob_temp_running_executable_path(void)
#define procs_wait_and_reset nob_procs_wait_and_reset
#define procs_append_with_flush nob_procs_append_with_flush
#define procs_flush nob_procs_flush
#define CLIT NOB_CLIT
#define Cmd Nob_Cmd
#define Cmd_Redirect Nob_Cmd_Redirect
#define Cmd_Opt Nob_Cmd_Opt
Expand Down Expand Up @@ -3012,6 +3021,8 @@ NOBDEF char *nob_temp_running_executable_path(void)
/*
Revision history:

3.8.0 (2026-03-24) Add NOB_CLIT()
Fix compliation on MSVC with /TP
3.7.0 (2026-03-20) Add nob_sb_append_sv()
3.6.0 (2026-03-16) Add nob_sv_chop_suffix()
Deprecate nob_sv_end_with()
Expand Down
2 changes: 1 addition & 1 deletion shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#if defined(__cplusplus)
#if defined(_MSC_VER)
#define nob_cc_flags(cmd) cmd_append(cmd, "/TP", "/W4", "/nologo", "/D_CRT_SECURE_NO_WARNINGS", "-I.")
#define nob_cc_flags(cmd) cmd_append(cmd, "/std:c++20", "/TP", "/W4", "/nologo", "/D_CRT_SECURE_NO_WARNINGS", "-I.")
#else
#define nob_cc(cmd) cmd_append(cmd, "cc", "-x", "c++")
#define nob_cc_flags(cmd) cmd_append(cmd, "-Wall", "-Wextra", "-Wno-missing-field-initializers", "-Wswitch-enum", "-ggdb", "-I.");
Expand Down
2 changes: 1 addition & 1 deletion tasks/20260317-165339/TASK.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MSVC C++ was never tried

- STATUS: OPEN
- STATUS: CLOSED
- PRIORITY: 100
- TAGS: bug,msvc

Expand Down
Loading