sci

最果て風呂

Emacs まだまだぁ〜

Emacs のビルドができなくなってしまいました。

nsmenu.m:1496:70: error: expected a type
- (instancetype)initWithContentRect: (NSRect)contentRect styleMask: (NSWind...
                                                                     ^
nsmenu.m:1520:62: error: use of undeclared identifier
      'NSWindowStyleMaskUtilityWindow'
  aStyle = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyl...
                                                             ^
nsmenu.m:1524:54: warning: incompatible pointer to integer conversion sending
      'id' to parameter of type 'NSUInteger' (aka 'unsigned long')
      [-Wint-conversion]
  [super initWithContentRect: contentRect styleMask: aStyle
                                                     ^~~~~~
/System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:279:79: note: 
      passing argument to parameter 'aStyle' here
  ...styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType de...
                           ^
nsmenu.m:1496:88: warning: conflicting parameter types in implementation of
      'initWithContentRect:styleMask:backing:defer:': 'NSUInteger'
      (aka 'unsigned long') vs 'id' [-Wmismatched-parameter-types]
  ...(NSRect)contentRect styleMask: (NSWindowStyleMask)aStyle
                                                       ^
/System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:279:79: note: 
      previous definition is here
  ...styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType de...
                ~~~~~~~~~~ ^
2 warnings and 2 errors generated.

NSWindowStyleMaskUtilityWindow って何だろう?NSWindow.h には NS_OPTIONS のひとつに書かれているけど。

NSPanel Class の Constants 類は Deprecated になっていて、Style Masks も Deprecated になっています。NSUtilityWindowMask もそうなっているので、変更することにしたらしい?

src/nsmenu.m の変更点

- initWithContentRect: (NSRect)contentRect styleMask: (NSUInteger)aStyle
↓
- (instancetype)initWithContentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)aStyle

...

aStyle = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSUtilityWindowMask;
↓
aStyle = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskUtilityWindow;

ここで、自分の環境の /System/Library/Framework/AppKit.framework/Headers/NSWindow.h には次のように書かれているので、コンパイラに NSUInteger と NSWindowStyleMask は違うよ(競合?)と言われてるみたい。

- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;

でも、違うよと言われる前に、expected a type となっているのがわかりません(>_<)。期待された型って何だろう。Not Found ではないから見つからないということでもないみたいだし……

更新があったので pull をしてから再度ビルドしてみたけれど、やはりダメでした。でもエラーの内容が少し変わっている。

nsmenu.m:1496:70: error: expected a type
- (instancetype)initWithContentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)aStyle
                                                                     ^
nsmenu.m:1520:10: warning: incompatible integer to pointer conversion assigning to 'id' from 'int' [-Wint-conversion]
  aStyle = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskUtilityWindow;
         ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nsmenu.m:1524:54: warning: incompatible pointer to integer conversion sending 'id' to parameter of type 'NSUInteger' (aka 'unsigned long') [-Wint-conversion]
  [super initWithContentRect: contentRect styleMask: aStyle
                                                     ^~~~~~
/System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:279:79: note: passing argument to parameter 'aStyle' here
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
                                                                              ^
nsmenu.m:1496:88: warning: conflicting parameter types in implementation of 'initWithContentRect:styleMask:backing:defer:': 'NSUInteger' (aka 'unsigned long')
      vs 'id' [-Wmismatched-parameter-types]
- (instancetype)initWithContentRect: (NSRect)contentRect styleMask: (NSWindowStyleMask)aStyle
                                                                                       ^
/System/Library/Frameworks/AppKit.framework/Headers/NSWindow.h:279:79: note: previous definition is here
- (instancetype)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
                                                                   ~~~~~~~~~~ ^
3 warnings and 1 error generated.

alanthird さんの真似をして nsterm.h に下記を記述するとビルドができるようになりました。TODO, FIXME, XXX というタグがあるんですね。

/* XXX: NSWindowStyleMask is not defined in OS X El Capitan. */
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
typedef NSUInteger NSWindowStyleMask;
#endif

AvailabilityMacros.h は目にしていたけれど、こういう使い方をするんですね(いや違うかもしれない)。TechnicalNote2064 の日本語訳にまんま「可用性マクロ」と書いてある。

ついでに、前から出ていた次の警告も修正することにしました。調べてみると、rlim.rlim_cur は必ず 0 以上なので、この比較式は意味が無いということになるらしいです。

emacs.c:827:12: warning: comparison of 0 <= unsigned expression is always true
      [-Wtautological-compare]
      && 0 <= rlim.rlim_cur && rlim.rlim_cur <= LONG_MAX)
         ~ ^  ~~~~~~~~~~~~~
emacs.c:861:10: warning: comparison of 0 <= unsigned expression is always true
      [-Wtautological-compare]
          if (0 <= rlim.rlim_max && rlim.rlim_max < newlim)
              ~ ^  ~~~~~~~~~~~~~

ということで、0 <= rlim.rlim_cur を削除。

補遺

NSWindowStyleMask の説明には次のように書かれています。

These constants specify the style of a window, and can be combined using the C bitwise OR operator.

ビット演算子 OR ?

上記のエラー部分にある nsmenu.m の次の個所は | が使われているから OR なのかな?

aStyle = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskUtilityWindow;

また、NSWindowStyleMaskUtilityWindow (変更される前は NSUtilityWindowMask でしたが) は、NSWindowStyleMaskUtilityWindow = 1 << 4 という定義になっていて、この << はシフト演算子

ということは、aStyle = 1 << 0 | 1 << 1 | 1 << 4 ということになる?意味わかんない。

それと、SDK macOS 10.12+ となっているから El Capitan では使えないのかな?AppKit.framework 内の Headers で grep をしてみたけれど、見つかりませんでした。うわっ…私のコンパイラ、バージョン低すぎ…?ひと世代前なのに?

Vim と違ってたくさんのメンテナがコミットをしているので多様化してますね。