@@ -41,7 +41,7 @@ std::string input_dir = "vulkan-shaders";
4141std::string output_dir = " /tmp" ;
4242std::string target_hpp = " ggml-vulkan-shaders.hpp" ;
4343std::string target_cpp = " ggml-vulkan-shaders.cpp" ;
44- std::string ninja_build_file = " " ;
44+ std::string target_cmake = " " ;
4545bool no_clean = false ;
4646bool no_embed = false ;
4747
@@ -245,41 +245,56 @@ struct compile_command {
245245 std::string name;
246246 std::string input_filepath;
247247 std::string output_filepath;
248- std::string flags;
248+ std::vector<std:: string> flags;
249249};
250250
251- // Code for writing a ninja build file
251+ // Code for writing a CMake build file
252252
253- static std::stringstream ninja_build ;
253+ std::stringstream cmake_lists ;
254254
255- std::string ninja_escape ( const std::string& str) {
256- std::string result;
257- for (char c : str) {
258- if (c == ' ' || c == ' $ ' || c == ' : ' ) {
259- result += ' $ ' ;
255+ struct cmake_escape { const std::string& str; };
256+ std::ostream& operator <<( std::ostream& os, const cmake_escape& to_escape) {
257+ for (char c : to_escape. str ) {
258+ if (c == ' " ' || c == ' \\ ' ) {
259+ os << ' \\ ' ;
260260 }
261- result += c;
261+ os << c;
262262 }
263- return result ;
263+ return os ;
264264}
265265
266- void ninja_init () {
267- ninja_build = make_generic_stringstream ();
268- ninja_build << " ninja_required_version = 1.3\n\n " ;
269- ninja_build << " rule glslc\n " ;
270- ninja_build << " command = " << GLSLC << " $FLAGS -MD -MF $out.d $in -o $out\n " ;
271- ninja_build << " depfile = $out.d\n " ;
272- ninja_build << " deps = gcc\n " ;
273- ninja_build << " description = Building Vulkan shader ${NAME}.spv\n\n " ;
266+ void cmake_add_header () {
267+ cmake_lists = make_generic_stringstream ();
268+ cmake_lists << " cmake_minimum_required(VERSION 3.14)\n " ;
269+ cmake_lists << " project(ggml-vulkan-shaders)\n\n " ;
270+ cmake_lists << " set(GLSLC \" " << GLSLC << " \" )\n\n " ;
271+ cmake_lists << " function(compile_shader name in_file out_file flags)\n " ;
272+ cmake_lists << " add_custom_command(\n " ;
273+ cmake_lists << " OUTPUT ${out_file}\n " ;
274+ cmake_lists << " COMMAND ${GLSLC} ${flags} ${ARGN} -MD -MF ${out_file}.d ${in_file} -o ${out_file}\n " ;
275+ cmake_lists << " DEPENDS ${in_file}\n " ;
276+ cmake_lists << " DEPFILE ${out_file}.d\n " ;
277+ cmake_lists << " COMMENT \" Building Vulkan shader ${name}.spv\"\n " ;
278+ cmake_lists << " )\n " ;
279+ cmake_lists << " endfunction()\n\n " ;
274280}
275281
276- void ninja_add_build_command (const compile_command& cmd) {
277- ninja_build << " build " << ninja_escape (cmd.output_filepath ) << " : glslc " << ninja_escape (cmd.input_filepath ) << " \n " ;
278- ninja_build << " NAME = " << cmd.name << " \n " ;
279- ninja_build << " FLAGS = " << cmd.flags << " \n\n " ;
282+ void cmake_add_build_command (const compile_command& cmd) {
283+ cmake_lists << " compile_shader(" << cmd.name << " \" " << cmd.input_filepath << " \" \" " << cmd.output_filepath << " \" " ;
284+ for (const std::string& flag : cmd.flags ) {
285+ cmake_lists << " \" " << cmake_escape{flag} << " \" " ;
286+ }
287+ cmake_lists << " )\n " ;
280288 shader_fnames.push_back (std::make_pair (cmd.name , cmd.output_filepath ));
281289}
282290
291+ void cmake_add_target () {
292+ cmake_lists << " \n add_custom_target(ggml-vulkan-shaders ALL DEPENDS\n " ;
293+ for (const auto & pair : shader_fnames) {
294+ cmake_lists << " \" " << pair.second << " \"\n " ;
295+ }
296+ cmake_lists << " )\n " ;
297+ }
283298
284299// variables to track number of compiles in progress
285300static uint32_t compile_count = 0 ;
@@ -307,11 +322,7 @@ compile_command create_compile_command(const std::string& _name, const std::stri
307322 flags.push_back (" -D" + define.first + " =" + define.second );
308323 }
309324
310- std::string flags_str;
311- for (const auto & part : flags) {
312- flags_str += part + " " ;
313- }
314- return {std::move (name), std::move (in_path), std::move (out_path), std::move (flags_str)};
325+ return {std::move (name), std::move (in_path), std::move (out_path), std::move (flags)};
315326}
316327
317328void execute_compile_command (compile_command cmd) {
@@ -323,10 +334,15 @@ void execute_compile_command(compile_command cmd) {
323334 // }
324335 // std::cout << std::endl;
325336
337+ std::string flags_str;
338+ for (const auto & part : cmd.flags ) {
339+ flags_str += part + " " ;
340+ }
341+
326342 #ifdef _WIN32
327- std::string command = GLSLC + " " + cmd. flags + " \" " + cmd.input_filepath + " \" -o \" " + cmd.output_filepath + " \" " ;
343+ std::string command = GLSLC + " " + flags_str + " \" " + cmd.input_filepath + " \" -o \" " + cmd.output_filepath + " \" " ;
328344 #else
329- std::string command = GLSLC + " " + cmd. flags + " " + cmd.input_filepath + " -o " + cmd.output_filepath ;
345+ std::string command = GLSLC + " " + flags_str + " " + cmd.input_filepath + " -o " + cmd.output_filepath ;
330346 #endif
331347 execute_command (command, stdout_str, stderr_str);
332348
@@ -358,8 +374,8 @@ static std::vector<std::future<void>> compiles;
358374void string_to_spv (const std::string& _name, const std::string& in_fname, const std::map<std::string, std::string>& defines, bool fp16 = true , bool coopmat = false , bool coopmat2 = false , bool f16acc = false ) {
359375 compile_command cmd = create_compile_command (_name, in_fname, defines, fp16, coopmat, coopmat2, f16acc);
360376
361- if (!ninja_build_file .empty ()) {
362- ninja_add_build_command (cmd);
377+ if (!target_cmake .empty ()) {
378+ cmake_add_build_command (cmd);
363379 return ;
364380 }
365381 {
@@ -1001,8 +1017,9 @@ void write_output_files() {
10011017 } else {
10021018 write_binary_file (target_cpp, src.str ());
10031019 }
1004- if (!ninja_build_file.empty ()) {
1005- write_file_if_changed (ninja_build_file, ninja_build.str ());
1020+ if (!target_cmake.empty ()) {
1021+ cmake_add_target ();
1022+ write_file_if_changed (target_cmake, cmake_lists.str ());
10061023 }
10071024}
10081025
@@ -1043,9 +1060,9 @@ int main(int argc, char** argv) {
10431060 if (args.find (" --no-embed" ) != args.end ()) {
10441061 no_embed = true ; // Do not embed SPIR-V binaries into C++ source files, only write stubs to header
10451062 }
1046- if (args.find (" --ninja " ) != args.end ()) {
1047- ninja_build_file = args[" --ninja " ]; // Write a ninja build file instead of invoking glslc directly
1048- ninja_init ();
1063+ if (args.find (" --cmake " ) != args.end ()) {
1064+ target_cmake = args[" --cmake " ]; // Write a CMakeLists.txt file instead of invoking glslc directly
1065+ cmake_add_header ();
10491066 }
10501067
10511068 if (!directory_exists (input_dir)) {
0 commit comments