Khi làm việc với Ruby trên macOS, việc cài đặt các gem đôi khi gặp phải những lỗi khó hiểu, đặc biệt là khi cài đặt các gem có chứa native extensions. Trong bài viết này, chúng ta sẽ đi sâu vào việc khắc phục một lỗi cụ thể gặp phải khi cài đặt gem mecab
, một công cụ phân tích ngôn ngữ tự nhiên phổ biến.
Lỗi fatal error: 'mecab.h' file not found
Khi cài đặt gem mecab
, người dùng gặp phải lỗi liên quan đến việc xây dựng native extensions. Lỗi này được mô tả như sau:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
sudo gem i mecab
Building native extensions. This could take a while...
ERROR: Error installing mecab:
ERROR: Failed to build gem native extension.
current directory: /Users/yuto/.anyenv/envs/rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mecab-0.996/ext/mecab
/Users/yuto/.anyenv/envs/rbenv/versions/3.3.0/bin/ruby extconf.rb
checking for make... yes
checking for -lstdc++... yes
checking for -lmecab... yes
checking for -lstdc++... yes
checking for mecab.h... yes
creating Makefile
current directory: /Users/yuto/.anyenv/envs/rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mecab-0.996/ext/mecab
make DESTDIR\= sitearchdir\=./.gem.20240104-34338-2nur66 sitelibdir\=./.gem.20240104-34338-2nur66 clean
current directory: /Users/yuto/.anyenv/envs/rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/mecab-0.996/ext/mecab
make DESTDIR\= sitearchdir\=./.gem.20240104-34338-2nur66 sitelibdir\=./.gem.20240104-34338-2nur66
compiling mecab_wrap.cpp
mecab_wrap.cpp:1126:3: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
sprintf( buf, "%d of type ", argn-1 );
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:180:1: note: 'sprintf' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:215:48: note: expanded from macro '__deprecated_msg'
#define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
^
mecab_wrap.cpp:1519:3: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
sprintf(klass_name, "TYPE%s", type->name);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:180:1: note: 'sprintf' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:215:48: note: expanded from macro '__deprecated_msg'
#define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
^
mecab_wrap.cpp:1575:5: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
sprintf(klass_name, "TYPE%s", type->name);
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/stdio.h:180:1: note: 'sprintf' has been explicitly marked deprecated here
__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead.")
^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/cdefs.h:215:48: note: expanded from macro '__deprecated_msg'
#define __deprecated_msg(_msg) __attribute__((__deprecated__(_msg)))
^
mecab_wrap.cpp:1855:10: fatal error: 'mecab.h' file not found
#include "mecab.h"
^~~~~~~~~
3 warnings and 1 error generated.
make: *** [mecab_wrap.o] Error 1
make failed, exit code 2
Nguyên nhân
Lỗi này xảy ra do Ruby không thể tìm thấy header file mecab.h
, cần thiết cho việc biên dịch extension. Điều này thường xảy ra khi mecab đã được cài đặt trước đó nhưng Ruby không thể xác định đúng vị trí của các file header.
Cách khắc phục
Cài đặt gem với tùy chọn chỉ định vị trí header files: Sử dụng lệnh sau để chỉ định cho Ruby biết vị trí của các file header cần thiết:
1
sudo gem i mecab -- --with-cppflags=-I/opt/homebrew/Cellar/mecab/0.996/include
Trong đó, tùy chọn --with-cppflags=-I/opt/homebrew/Cellar/mecab/0.996/include giúp chỉ định đường dẫn đến thư mục chứa mecab.h
.
Kết quả:
1
2
3
4
Building native extensions with: '--with-cppflags=-I/opt/homebrew/Cellar/mecab/0.996/include'
This could take a while...
Successfully installed mecab-0.996
1 gem installed