#include <future>
#include <queue>
#include <condition_variable>
+#include <atomic>
#include <cstdio>
#include <cstring>
#include <cstdlib>
std::mutex lock;
std::vector<std::pair<std::string, std::string>> shader_fnames;
+// Set when any shader subprocess fails (non-zero exit / stderr / launch failure) so the
+// build is stopped instead of silently producing a broken libggml-vulkan. (issue #24393)
+static std::atomic<bool> compile_failed{false};
std::locale c_locale("C");
std::string GLSLC = "glslc";
namespace {
-void execute_command(std::vector<std::string>& command, std::string& stdout_str, std::string& stderr_str) {
+int execute_command(std::vector<std::string>& command, std::string& stdout_str, std::string& stderr_str) {
#ifdef _WIN32
HANDLE stdout_read, stdout_write;
HANDLE stderr_read, stderr_write;
CloseHandle(stdout_read);
CloseHandle(stderr_read);
WaitForSingleObject(pi.hProcess, INFINITE);
+ DWORD exit_code = 1;
+ GetExitCodeProcess(pi.hProcess, &exit_code);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
+ return (int)exit_code;
#else
int stdout_pipe[2];
int stderr_pipe[2];
close(stdout_pipe[0]);
close(stderr_pipe[0]);
- waitpid(pid, nullptr, 0);
+ int status = 0;
+ waitpid(pid, &status, 0);
+ return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
}
#endif
}
// }
// std::cout << std::endl;
- execute_command(cmd, stdout_str, stderr_str);
- if (!stderr_str.empty()) {
- std::cerr << "cannot compile " << name << "\n\n";
+ int exit_code = execute_command(cmd, stdout_str, stderr_str);
+ if (exit_code != 0 || !stderr_str.empty()) {
+ std::cerr << "cannot compile " << name << " (exit code " << exit_code << ")\n\n";
for (const auto& part : cmd) {
std::cerr << part << " ";
}
std::cerr << "\n\n" << stderr_str << std::endl;
+ compile_failed = true;
return;
}
shader_fnames.push_back(std::make_pair(name, out_path));
} catch (const std::exception& e) {
std::cerr << "Error executing command for " << name << ": " << e.what() << std::endl;
+ compile_failed = true;
}
}
process_shaders();
+ if (compile_failed) {
+ std::cerr << "vulkan-shaders-gen: one or more shaders failed to compile" << std::endl;
+ return EXIT_FAILURE;
+ }
+
write_output_files();
return EXIT_SUCCESS;