clangのwarning: overriding the module target triple
この件について処理系Slackで相談したところ、いろいろなことが分かった。
背景
自作言語Shiikaに分割コンパイルを実装して、LLVM bitcode (.bcファイル) を2個作ってclangコマンドでリンクしようとしたところ、以下のような警告が出るようになった。
warning: overriding the module target triple with x86_64-apple-macosx10.15.0 [-Woverride-module]
1 warning generated.
shiikaはRust + inkwellで書かれているので、.bcの生成前に
module.set_triple(&inkwell::targets::TargetMachine::get_default_triple())
としてtarget tripleを指定してやればよい…と思ったのだが、get_default_tripleはなぜか x86_64-apple-darwin19.6.0
を返していて、上記のwarningとは一致しないことが分かった。
調査
とりあえず module.set_triple(&inkwell::targets::TargetTriple::create("x86_64-apple-macosx10.15.0"))
のように手でclangが認識するtripleを書いてやれば警告はでなくなったので、あとは「macosx10.15.0」が取れれば良いことがわかった。
ところが llvm-config --host-target
とか、dsymutil --version
とか、何なら clang --version
でさえも「darwin19.6.0」を表示する。はて?
原因
実はclang内にComputeEffectiveClangTripleという関数があって、target tripleをただの「darwin」からより詳しい「macosx」に直していることがわかった。なるほど他のコマンドでは「darwin」になるわけだ。
プラットフォームの推測は以下の順に行われる。
- -targetオプション
- -m
version-minオプション - 環境変数 "MACOSX_DEPLOYMENT_TARGET"
- SDKのSDKSettings.json
- llvm::sys::getProcessTriple
今回の場合1,2,3はいずれも指定していない。また4は、もし $(xcrun --show-sdk-path)/SDKSettings.json
の Version を見てるのだとしたらmacosx「10.15.4」になると思うんだよねえ。macosx「10.15.0」になっているので、5の可能性がある。
5の場合
という流れになって、ここで
Micro = 0;
Minor = Major - 4;
Major = 10;
という処理があり、darwin「19.6.0」がmacosx「10.15.0」になる現象と合致する。
対策
というわけで「警告をどうやって消すか」については以下の2通りが考えられる。
- どうにかして
"x86_64-apple-macosx19.4.0"
を作り、.bcのtarget tripleに指定する。 - clangに-targetオプションを渡してtarget tripleを明示する。
このうち1は非現実的である。というのはclangがtarget tripleを補正する処理は上で見たとおり非常に複雑でコピーできないからだ。
ということで今回は2の方法で解決した。