JUCEプラグイン/アプリケーションのビルドが "cannot bind packed field" で失敗する

2 min読了の目安(約2100字TECH技術記事

これは主にLinux環境で発生する問題ですが、JUCEで作られたオーディオプラグインやアプリケーションをビルドしようとした時に、次のようなエラーが出て失敗することがあります。(この例はADLplugをUbuntu 20.04でビルドした時に発生するエラーです。)

/sources/ADLplug/build-opn$ make
Scanning dependencies of target juce_graphics
[  1%] Building CXX object CMakeFiles/juce_graphics.dir/project/opn/JuceLibraryCode/include_juce_graphics.cpp.o
In file included from /sources/ADLplug/thirdparty/JUCE/modules/juce_graphics/juce_graphics.h:121,
                 from /sources/ADLplug/thirdparty/JUCE/modules/juce_graphics/juce_graphics.cpp:42,
                 from /sources/ADLplug/project/opn/JuceLibraryCode/include_juce_graphics.cpp:9:
/sources/ADLplug/thirdparty/JUCE/modules/juce_graphics/colour/juce_PixelFormats.h: In member function ‘juce::uint8& juce::PixelARGB::getAlpha()’:
/sources/ADLplug/thirdparty/JUCE/modules/juce_graphics/colour/juce_PixelFormats.h:116:77: error: cannot bind packed field ‘((juce::PixelARGB*)this)->juce::PixelARGB::<anonymous>.juce::PixelARGB::<unnamed union>::comps[3]’ to ‘juce::uint8&’ {aka ‘unsigned char&’}
  116 | e uint8& getAlpha() noexcept           { return comps [indexA]; }
      |                                                 ~~~~~~~~~~~~~^

/sources/ADLplug/thirdparty/JUCE/modules/juce_graphics/colour/juce_PixelFormats.h: In member function ‘juce::uint8& juce::PixelARGB::getRed()’:
/sources/ADLplug/thirdparty/JUCE/modules/juce_graphics/colour/juce_PixelFormats.h:117:77: error: cannot bind packed field ‘((juce::PixelARGB*)this)->juce::PixelARGB::<anonymous>.juce::PixelARGB::<unnamed union>::comps[2]’ to ‘juce::uint8&’ {aka ‘unsigned char&’}
  117 | e uint8& getRed() noexcept             { return comps [indexR]; }

これが発生する条件はいくつか考えられますが、JUCE6系列では発生しない問題だと思います。JUCEはsubmoduleからビルドされることがよくあるので、参照されるリビジョンによってはこの問題が発生します。ADLplugの場合はJUCE 5.4.1系列です。

これはg++でコンパイルすると発生するビルドエラーで、clang++を使っていると発生しない問題です。JUCE本家の問題ですが、Mac環境やLinuxでもCLionなどでビルドしている開発者はおそらくこれを目にすることが無い(無かった)のでしょう。

解決策というよりは回避策ですが、clang++を使うとビルドできることが多いでしょう。LinuxMakefileからビルドするのであれば、make CC=clang CXX=clang++でいけると思います。ADLplugの場合はcmakeを使っているので(独自スクリプトでありJUCE6のCMakeサポートとは無関係)、cmake -DCMAKE_CXX_COMPILER=clang++ [path]でビルドできるようになるでしょう。