|
1 |
| -require 'mkmf' |
| 1 | +require "mkmf" |
| 2 | +require "tsort" |
2 | 3 |
|
3 |
| -# need to use c++ compiler flags |
4 |
| -$CXXFLAGS << ' -std=c++17' |
| 4 | +# TODO: options such as CoreML |
5 | 5 |
|
6 |
| -$LDFLAGS << ' -lstdc++' |
| 6 | +cmake = find_executable("cmake") || abort |
7 | 7 |
|
8 |
| -# Set to true when building binary gems |
9 |
| -if enable_config('static-stdlib', false) |
10 |
| - $LDFLAGS << ' -static-libgcc -static-libstdc++' |
11 |
| -end |
12 |
| - |
13 |
| -if enable_config('march-tune-native', false) |
14 |
| - $CFLAGS << ' -march=native -mtune=native' |
15 |
| - $CXXFLAGS << ' -march=native -mtune=native' |
16 |
| -end |
| 8 | +have_library("gomp") rescue nil |
17 | 9 |
|
18 |
| -if ENV['WHISPER_METAL'] |
19 |
| - $GGML_METAL ||= true |
20 |
| - $DEPRECATE_WARNING ||= true |
21 |
| -end |
| 10 | +prefix = File.join("build", "whisper.cpp.dot") |
| 11 | +system cmake, "-S", "sources", "-B", "build", "--graphviz", prefix, "-D", "BUILD_SHARED_LIBS=OFF", exception: true |
22 | 12 |
|
23 |
| -$UNAME_S = `uname -s`.chomp |
24 |
| -$UNAME_P = `uname -p`.chomp |
25 |
| -$UNAME_M = `uname -m`.chomp |
26 |
| - |
27 |
| -if $UNAME_S == 'Darwin' |
28 |
| - unless ENV['GGML_NO_METAL'] |
29 |
| - $GGML_METAL ||= true |
| 13 | +static_lib_shape = nil |
| 14 | +nodes = {} |
| 15 | +depends = {} |
| 16 | +class << depends |
| 17 | + include TSort |
| 18 | + alias tsort_each_node each_key |
| 19 | + def tsort_each_child(node, &block) |
| 20 | + fetch(node, []).each(&block) |
30 | 21 | end
|
31 |
| - $GGML_NO_OPENMP ||= true |
32 |
| -end |
33 |
| - |
34 |
| -if $GGML_METAL |
35 |
| - $GGML_METAL_EMBED_LIBRARY = true |
36 |
| -end |
37 |
| - |
38 |
| -$MK_CPPFLAGS = '-Iggml/include -Iggml/src -Iggml/src/ggml-cpu -Iinclude -Isrc -Iexamples -DGGML_USE_CPU' |
39 |
| -$MK_CFLAGS = '-std=c11 -fPIC' |
40 |
| -$MK_CXXFLAGS = '-std=c++17 -fPIC' |
41 |
| -$MK_NVCCFLAGS = '-std=c++17' |
42 |
| -$MK_LDFLAGS = '' |
43 |
| - |
44 |
| -$OBJ_GGML = [] |
45 |
| -$OBJ_WHISPER = [] |
46 |
| -$OBJ_COMMON = [] |
47 |
| -$OBJ_SDL = [] |
48 |
| - |
49 |
| -$MK_CPPFLAGS << ' -D_XOPEN_SOURCE=600' |
50 |
| - |
51 |
| -if $UNAME_S == 'Linux' |
52 |
| - $MK_CPPFLAGS << ' -D_GNU_SOURCE' |
53 |
| -end |
54 |
| - |
55 |
| -if $UNAME_S == 'Darwin' |
56 |
| - $MK_CPPFLAGS << ' -D_DARWIN_C_SOURCE' |
57 |
| -end |
58 |
| - |
59 |
| -if ENV['WHISPER_DEBUG'] |
60 |
| - $MK_CFLAGS << ' -O0 -g' |
61 |
| - $MK_CXXFLAGS << ' -O0 -g' |
62 |
| - $MK_LDFLAGS << ' -g' |
63 |
| - $MK_NVCCFLAGS << ' -O0 -g' |
64 |
| -else |
65 |
| - $MK_CPPFLAGS << ' -DNDEBUG' |
66 |
| - $MK_CFLAGS << ' -O3' |
67 |
| - $MK_CXXFLAGS << ' -O3' |
68 |
| - $MK_NVCCFLAGS << ' -O3' |
69 |
| -end |
70 |
| - |
71 |
| -$WARN_FLAGS = |
72 |
| - ' -Wall' << |
73 |
| - ' -Wextra' << |
74 |
| - ' -Wpedantic' << |
75 |
| - ' -Wcast-qual' << |
76 |
| - ' -Wno-unused-function' |
77 |
| - |
78 |
| -$MK_CFLAGS << |
79 |
| - $WARN_FLAGS << |
80 |
| - ' -Wshadow' << |
81 |
| - ' -Wstrict-prototypes' << |
82 |
| - ' -Wpointer-arith' << |
83 |
| - ' -Wmissing-prototypes' << |
84 |
| - ' -Werror=implicit-int' << |
85 |
| - ' -Werror=implicit-function-declaration' |
86 |
| - |
87 |
| -$MK_CXXFLAGS << |
88 |
| - $WARN_FLAGS << |
89 |
| - ' -Wmissing-declarations' << |
90 |
| - ' -Wmissing-noreturn' |
91 |
| - |
92 |
| -unless `#{cc_command} #{$LDFLAGS} -Wl,-v 2>&1`.chomp.include? 'dyld-1015.7' |
93 |
| - $MK_CPPFLAGS << ' -DHAVE_BUGGY_APPLE_LINKER' |
94 |
| -end |
95 |
| - |
96 |
| -if %w[Linux Darwin FreeBSD NetBSD OpenBSD Haiku].include? $UNAME_S |
97 |
| - $MK_CFLAGS << ' -pthread' |
98 |
| - $MK_CXXFLAGS << ' -pthread' |
99 |
| -end |
100 |
| - |
101 |
| -unless $_WIN32 |
102 |
| - $DSO_EXT = '.so' |
103 |
| -else |
104 |
| - $DSO_EXT = '.dll' |
105 | 22 | end
|
106 |
| - |
107 |
| -unless ENV['RISCV'] |
108 |
| - if %w[x86_64 i686 amd64].include? $UNAME_M |
109 |
| - $HOST_CXXFLAGS ||= '' |
110 |
| - |
111 |
| - $MK_CFLAGS << ' -march=native -mtune=native' |
112 |
| - $HOST_CXXFLAGS << ' -march=native -mtune=native' |
113 |
| - end |
114 |
| -else |
115 |
| - $MK_CFLAGS << ' -march=rv64gcv -mabi=lp64d' |
116 |
| - $MK_CXXFLAGS << ' -march=rv64gcv -mabi=lp64d' |
117 |
| -end |
118 |
| - |
119 |
| -unless ENV['GGML_NO_ACCELERATE'] |
120 |
| - if $UNAME_S == 'Darwin' |
121 |
| - $MK_CPPFLAGS << ' -DGGML_USE_ACCELERATE -DGGML_USE_BLAS -DGGML_BLAS_USE_ACCELERATE' |
122 |
| - $MK_CPPFLAGS << ' -DACCELERATE_NEW_LAPACK' |
123 |
| - $MK_CPPFLAGS << ' -DACCELERATE_LAPACK_ILP64' |
124 |
| - $MK_LDFLAGS << ' -framework Accelerate' |
125 |
| - $OBJ_GGML << 'ggml/src/ggml-blas/ggml-blas.o' |
126 |
| - end |
127 |
| -end |
128 |
| - |
129 |
| -if ENV['GGML_OPENBLAS'] |
130 |
| - $MK_CPPFLAGS << " -DGGML_USE_BLAS #{`pkg-config --cflags-only-I openblas`.chomp}" |
131 |
| - $MK_CFLAGS << " #{`pkg-config --cflags-only-other openblas)`.chomp}" |
132 |
| - $MK_LDFLAGS << " #{`pkg-config --libs openblas`}" |
133 |
| - $OBJ_GGML << 'ggml/src/ggml-blas/ggml-blas.o' |
134 |
| -end |
135 |
| - |
136 |
| -if ENV['GGML_OPENBLAS64'] |
137 |
| - $MK_CPPFLAGS << " -DGGML_USE_BLAS #{`pkg-config --cflags-only-I openblas64`.chomp}" |
138 |
| - $MK_CFLAGS << " #{`pkg-config --cflags-only-other openblas64)`.chomp}" |
139 |
| - $MK_LDFLAGS << " #{`pkg-config --libs openblas64`}" |
140 |
| - $OBJ_GGML << 'ggml/src/ggml-blas/ggml-blas.o' |
141 |
| -end |
142 |
| - |
143 |
| -if $GGML_METAL |
144 |
| - $MK_CPPFLAGS << ' -DGGML_USE_METAL' |
145 |
| - $MK_LDFLAGS << ' -framework Foundation -framework Metal -framework MetalKit' |
146 |
| - $OBJ_GGML << 'ggml/src/ggml-metal/ggml-metal.o' |
147 |
| - |
148 |
| - if ENV['GGML_METAL_NDEBUG'] |
149 |
| - $MK_CPPFLAGS << ' -DGGML_METAL_NDEBUG' |
150 |
| - end |
151 |
| - |
152 |
| - if $GGML_METAL_EMBED_LIBRARY |
153 |
| - $MK_CPPFLAGS << ' -DGGML_METAL_EMBED_LIBRARY' |
154 |
| - $OBJ_GGML << 'ggml/src/ggml-metal/ggml-metal-embed.o' |
| 23 | +File.open(File.join("build", "whisper.cpp.dot")).each_line do |line| |
| 24 | + case line |
| 25 | + when /\[\s*label\s*=\s*"Static Library"\s*,\s*shape\s*=\s*(?<shape>\w+)\s*\]/ |
| 26 | + static_lib_shape = $~[:shape] |
| 27 | + when /\A\s*"(?<node>\w+)"\s*\[\s*label\s*=\s*"(?<label>\S+)"\s*,\s*shape\s*=\s*(?<shape>\w+)\s*\]\s*;\s*\z/ |
| 28 | + node = $~[:node] |
| 29 | + label = $~[:label] |
| 30 | + shape = $~[:shape] |
| 31 | + nodes[node] = [label, shape] |
| 32 | + when /\A\s*"(?<depender>\w+)"\s*->\s*"(?<dependee>\w+)"/ |
| 33 | + depender = $~[:depender] |
| 34 | + dependee = $~[:dependee] |
| 35 | + depends[depender] ||= [] |
| 36 | + depends[depender] << dependee |
155 | 37 | end
|
156 | 38 | end
|
157 |
| - |
158 |
| -$OBJ_GGML << |
159 |
| - 'ggml/src/ggml.o' << |
160 |
| - 'ggml/src/ggml-alloc.o' << |
161 |
| - 'ggml/src/ggml-backend.o' << |
162 |
| - 'ggml/src/ggml-backend-reg.o' << |
163 |
| - 'ggml/src/ggml-opt.o' << |
164 |
| - 'ggml/src/ggml-quants.o' << |
165 |
| - 'ggml/src/ggml-threading.o' << |
166 |
| - 'ggml/src/ggml-cpu/ggml-cpu.o' << |
167 |
| - 'ggml/src/ggml-cpu/ggml-cpu-cpp.o' << |
168 |
| - 'ggml/src/ggml-cpu/ggml-cpu-aarch64.o' << |
169 |
| - 'ggml/src/ggml-cpu/ggml-cpu-hbm.o' << |
170 |
| - 'ggml/src/ggml-cpu/ggml-cpu-quants.o' << |
171 |
| - 'ggml/src/ggml-cpu/ggml-cpu-traits.o' << |
172 |
| - 'ggml/src/ggml-cpu/unary-ops.o' << |
173 |
| - 'ggml/src/ggml-cpu/binary-ops.o' << |
174 |
| - 'ggml/src/ggml-cpu/vec.o' << |
175 |
| - 'ggml/src/ggml-cpu/ops.o' |
176 |
| - |
177 |
| -$OBJ_WHISPER << |
178 |
| - 'src/whisper.o' << |
179 |
| - 'examples/common.o' << |
180 |
| - 'examples/common-whisper.o' |
181 |
| - |
182 |
| -$objs = $OBJ_GGML + $OBJ_WHISPER + $OBJ_COMMON + $OBJ_SDL |
183 |
| -$objs << |
184 |
| - "ruby_whisper.o" << |
185 |
| - "ruby_whisper_context.o" << |
186 |
| - "ruby_whisper_transcribe.o" << |
187 |
| - "ruby_whisper_params.o" << |
188 |
| - "ruby_whisper_error.o" << |
189 |
| - "ruby_whisper_segment.o" << |
190 |
| - "ruby_whisper_model.o" |
191 |
| - |
192 |
| -$CPPFLAGS = "#{$MK_CPPFLAGS} #{$CPPFLAGS}" |
193 |
| -$CFLAGS = "#{$CPPFLAGS} #{$MK_CFLAGS} #{$GF_CFLAGS} #{$CFLAGS}" |
194 |
| -$BASE_CXXFLAGS = "#{$MK_CXXFLAGS} #{$CXXFLAGS}" |
195 |
| -$CXXFLAGS = "#{$BASE_CXXFLAGS} #{$HOST_CXXFLAGS} #{$GF_CXXFLAGS} #{$CPPFLAGS}" |
196 |
| -$NVCCFLAGS = "#{$MK_NVCCFLAGS} #{$NVCCFLAGS}" |
197 |
| -$LDFLAGS = "#{$MK_LDFLAGS} #{$LDFLAGS}" |
198 |
| - |
199 |
| -create_makefile('whisper') |
200 |
| - |
201 |
| -File.open 'Makefile', 'a' do |file| |
202 |
| - file.puts 'include scripts/get-flags.mk' |
203 |
| - file.puts 'include cpu.mk' |
204 |
| - |
205 |
| - if $GGML_METAL |
206 |
| - file.puts 'include metal.mk' |
207 |
| - |
208 |
| - if $GGML_METAL_EMBED_LIBRARY |
209 |
| - file.puts 'include metal-embed.mk' |
210 |
| - end |
211 |
| - end |
| 39 | +libs = depends.tsort.filter_map {|node| |
| 40 | + label, shape = nodes[node] |
| 41 | + shape == static_lib_shape ? label : nil |
| 42 | +}.collect {|lib| "lib#{lib}.a"} |
| 43 | + .reverse |
| 44 | + .join(" ") |
| 45 | + |
| 46 | +$CFLAGS << " -std=c11 -fPIC" |
| 47 | +$CXXFLAGS << " -std=c++17 -O3 -DNDEBUG" |
| 48 | +$INCFLAGS << " -Isources/include -Isources/ggml/include -Isources/examples" |
| 49 | +$LOCAL_LIBS << " #{libs}" |
| 50 | +$cleanfiles << " build #{libs}" |
| 51 | + |
| 52 | +create_makefile "whisper" do |conf| |
| 53 | + conf << <<~EOF |
| 54 | + $(TARGET_SO): #{libs} |
| 55 | + #{libs}: cmake-targets |
| 56 | + cmake-targets: |
| 57 | + #{"\t"}#{cmake} -S sources -B build -D BUILD_SHARED_LIBS=OFF -D CMAKE_ARCHIVE_OUTPUT_DIRECTORY=#{__dir__} -D CMAKE_POSITION_INDEPENDENT_CODE=ON |
| 58 | + #{"\t"}#{cmake} --build build --config Release --target common whisper |
| 59 | + #{"\t"} |
| 60 | + EOF |
212 | 61 | end
|
0 commit comments