JavaFX on M1 Mac

以前に(別サイトだが)『M1 Mac に M1(Arm) 対応の JDK をインストールする』という記事を書いた。

そこでは JavaFX に関してはまるで触れなかった。

一応、一般的なことを書いておくと、OpenJDK 11 から、JavaFX は OpenJDK とは切り離され、開発する際には専用の SDK のインストールが必要となった。
ただこれは一般論であって JDK によっては同梱されている場合もある。

上の記事で触れた zulu のやつもその一つで、実際、以下のプログラムを何の苦もなくビルドしてくれた。


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


public class HelloFX extends Application {

    @Override
    public void start(Stage stage) {
        String javaVersion = System.getProperty("java.version");
        String javafxVersion = System.getProperty("javafx.version");
        Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
        Scene scene = new Scene(new StackPane(l), 640, 480);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}

実行させると

とちゃんと動く。

ただ、である。

ハローワールド的なことはできても、もっと複雑な、例えば動画の再生で mediaplayer を使いたいなどと言った時、よほど環境をしっかり整えない限りできそうもない。

そもそも OpenJFX 自体、正式に M1 対応がなされたのは比較的最近のことらしい。(こちらの記事参照)

現時点(2022/5)で凝ったアプリの開発は無理なような。。。

 

で、この現状を見て思い浮かぶのは「Java と JavaScript の立場が逆転した」というよく聞くアレと一時期の「Java 警察」のハジケっぷりだ。

その話はおいおい。

 

猪股弘明

 

Mac で学ぶ Arm アーキテクチャ 1-2

前回、唐突にアセンブラ言語から入ったわけであるが、アセンブラ言語で注意しなければいけない点はなんだろうか?

よく言われていることだが、アセンブラは抽象度が低い。

C++ はいうに及ばず、比較的低レイヤーの操作を得意とする C でも普通にコーディングする際にはハードを意識する必要はほとんどない。

この事情は 1-1 からでも伺えるであろう。
CPU のアーキテクチャが x86-64 であっても arm であっても、(当たり前だが)C のコードは一緒でいい。アーキテクチャの違いをコンパイラーが吸収してしまからだ。

ところが、アセンブラは、命令セットなどは基本的には CPU に依存するため、CPU の仕様が頭に入ってないとまとまったプログラムを組むのは難しい。

つまり、汎用性のあるアセンブリ言語というものは存在せず、
arm に対応したアセンブリ言語
x86_64 に対応したアセンブリ言語
がそれぞれ存在している、というのが実態なのだ。

幸運なことに MacOS に入っている clang はアーキテクチャを指定することで、x86_64 向け・arm 向けのアセンブラを出力できるので、arm 向けのアセンブラ出力から arm のアーキテクチャを探っていくことにする。

なお、一口に arm といっても、型番によって微妙に違いがある。
例えば、v7 までは 32bit CPU だが、v8 は 64bit である
ここでは Mac を前提にしているので、特に断らない限り cortex シリーズを前提に話を進めていく。

 

 air-h-128k-il

 

Mac で学ぶ Arm アーキテクチャ 1-1

実行したら 10 を返す

int main(void){
    return 10;
}

という C プログラムを

・intel Mac 向け

・M1 Mac 向け

にそれぞれアセンブラで「寸止め」コンパイルして出力させてみた。

Intel(x86_64)アーキテクチャ向け
M1(arm64)アーキテクチャ向け

すぐに気がつくのは

・レジスタの名称が全然違う

・M1 向けの方が若干すっきりしている

あたりだろう。

 

ところで、これを某所でネタにしたら「どうやってアセンブラ出力させたんですか?」という質問があった。
じゃあ、これ、クエスチョンにしますか。

Q1.1 C プログラム(ここでは test.c とします)を Mac 上で clang を使って
・x86_64 アーキテクチャ向け
・arm64 アーキテクチャ向け
にそれぞれアセンブラ出力(testx86.s と testarm.s)させるコマンドをそれぞれ作ってください。

ついでにこれも。

Q1.2 どちらのアーキテクチャでも良いが test.c の実行ファイル(test)を作成してください。
このとき実行ファイルを実行させても端末には何も表示されません。
この時の main 関数の返り値 10 を(ソースに手を加えずに)端末上に表示させるにはどのようなコマンドを用いたら良いでしょう?

解答は近いうちにアップします

解答はこちら

 

air-h-128k-il