以前Cocos2d-xをビルドして(2017年6月30日の日記参照)、Linuxで動くサンプルプログラムをビルドしました。あの時は結局、ゲームは作らずじまいでした。懲りずに、今回はAndroid向けにビルドします。
その前にまずLinux向けにビルドします。簡単かと思ったら、めちゃくちゃハマりました……。
公式ドキュメント(リンク)に載っている通りの手順を試すと、下記のようなエラーが出ます。
$ git clone https://github.com/cocos2d/cocos2d-x $ cd cocos2d-x/ $ git submodule update --init Submodule path 'tests/cpp-tests/Resources/ccs-res': checked out '5d65db4c5f18c0df1305ff32b076425ab228cc4a' Submodule path 'tools/bindings-generator': checked out '2aa9b21f11bf514ca80f243b21750e8c7c28f05e' Submodule path 'tools/cocos2d-console': checked out '643f423415c62a1b610549323c4bf5499683baab' Submodule path 'web': checked out 'e79acd062363818af809c51804083a5989a9aedc' $ ./download-deps.py ======================================================= ==> Prepare to download external libraries! ==> version file doesn't exist ==> Ready to download 'v3-deps-156.zip' from 'https://github.com/cocos2d/cocos2d-x-3rd-party-libs-bin/archive/v3-deps-156.zip' (...snip...) ==> Would you like to save 'v3-deps-156.zip'? So you don't have to download it later. [Yes/no]: Yes $ cd build/ $ mkdir linux-build $ cd linux-build/ $ cmake ../../ -- The C compiler identification is GNU 8.2.0 -- The CXX compiler identification is GNU 8.2.0 -- Check for working C compiler: /usr/lib/ccache/cc -- Check for working C compiler: /usr/lib/ccache/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features (...snip...) -- Found Threads: TRUE -- Configuring done -- Generating done -- Build files have been written to: /home/katsuhiro/share/projects/oss/cocos2d-x/build/linux-build $ make [ 0%] Building CXX object engine/external/unzip/CMakeFiles/ext_unzip.dir/ioapi.cpp.o [ 0%] Building CXX object engine/external/unzip/CMakeFiles/ext_unzip.dir/unzip.cpp.o [ 0%] Building CXX object engine/external/unzip/CMakeFiles/ext_unzip.dir/ioapi_mem.cpp.o [ 1%] Linking CXX static library ../../../lib/libext_unzip.a (...snip...) [ 84%] Built target jscocos2d [ 84%] Building CXX object engine/tests/cpp-empty-test/CMakeFiles/cpp-empty-test.dir/Classes/AppDelegate.cpp.o [ 84%] Building CXX object engine/tests/cpp-empty-test/CMakeFiles/cpp-empty-test.dir/Classes/HelloWorldScene.cpp.o [ 84%] Building CXX object engine/tests/cpp-empty-test/CMakeFiles/cpp-empty-test.dir/proj.linux/main.cpp.o [ 84%] Linking CXX executable ../../../bin/Debug/cpp-empty-test/cpp-empty-test /usr/bin/ld: ../../../../../external/freetype2/prebuilt/linux/64-bit/libfreetype.a(ftbase.linux64.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC (...snip...) /usr/bin/ld: ../../../../../external/freetype2/prebuilt/linux/64-bit/libfreetype.a(ftbitmap.linux64.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIC /usr/bin/ld: final link failed: nonrepresentable section on output collect2: error: ld returned 1 exit status make[2]: *** [engine/tests/cpp-empty-test/CMakeFiles/cpp-empty-test.dir/build.make:153: bin/Debug/cpp-empty-test/cpp-empty-test] Error 1 make[1]: *** [CMakeFiles/Makefile2:1362: engine/tests/cpp-empty-test/CMakeFiles/cpp-empty-test.dir/all] Error 2 make: *** [Makefile:84: all] Error 2
エラーで指摘されているfreetype2/prebuilt/linux/64-bit/libfreetype.aは、download-deps.pyがダウンロードしてきたv3-deps-156.zipに含まれているスタティックライブラリです。recompile with -fPICと言われても、自分でビルドしたものではないので、何もできません。そんなこと言われても困る。
困った挙句にCocos2d-xのissue list(リンク)に辿りつきました。議論を見るとcocos2d-x-3rd-party-libs-srcリポジトリのbuild.shでライブラリが作れるみたいです。うえ〜、そんなの知らんがな。
$ git clone https://github.com/cocos2d/cocos2d-x-3rd-party-libs-src $ cd cocos2d-x-3rd-party-libs-src/build/ $ ./build.sh -p=linux --libs=freetype --arch=x86_64 --mode=release $ cp linux/freetype/prebuilt/x86_64/libfreetype.a ../../cocos2d-x/external/freetype2/prebuilt/linux/64-bit/libfreetype.a
依存ライブラリを自前でビルドして置き換えることで、無事にCocos2d-xのコンパイルが通りました。
心配だったゲームプロジェクトの作り方は以前と同じ(2017年7月2日の日記参照)でした。こちらはハマらなくて本当に良かったです。
生成されたゲームプロジェクトの中にproj.androidという名前のディレクトリが作成されます。Android Studioでproj.androidを開けば後は勝手にGradleがビルドしてくれるはずです。
$ ls CMakeLists.txt Resources proj.android proj.linux Classes cocos2d proj.ios_mac proj.win32
Linux向けにビルドしたいときは、以前と同じ手順でOKです。同じコードでAndroidもLinuxも対応できて便利ですよね。
昔(2017年5月2日の日記参照)作った我が家のPCのPassmarkスコア表に、Ryzen 7デスクトップ(2018年12月1日の日記参照)も加えました。
用途 | CPU | シングル | マルチ | コア、スレッド数 | TDP |
---|---|---|---|---|---|
デスクトップ | AMD Ryzen7 2700 | 2005 | 14985 | 8C16T | 65W |
旧デスクトップ | AMD A10-7800 | 1537 | 5069 | 4C4T | 65W |
ノート | Intel Core i5 2450M | 1404 | 3404 | 2C4T | 35W |
サーバ | Intel Pentium J4205 | 899 | 2394 | 4C4T | 10W |
旧サーバ | Intel Atom D2700 | 349 | 840 | 2C4T | 10W |
サブマシン | Intel Atom D525 | 284 | 701 | 2C4T | 13W |
2年前はRyzen 7の8コアを欲しいなと思いつつも、何に使うか疑問に思っていましたが、Linuxのビルドに最適だということがわかって、とても役に立っております。買って良かった。
目次: ROCK64/ROCKPro64
完全に自分のためのメモですが、ROCK64とTinker Boardで使用しているU-Bootのdistro bootの設定ファイル(extlinux.conf)を貼っておきます。
オリジナルのファイルにlinux-nextの起動用設定(label kernel-nextの部分)を追加しました。
menu title select kernel
label kernel-4.4.132-1075-rockchip-ayufan-ga83beded8524
kernel /boot/vmlinuz-4.4.132-1075-rockchip-ayufan-ga83beded8524
initrd /boot/initrd.img-4.4.132-1075-rockchip-ayufan-ga83beded8524
devicetreedir /boot/dtbs/4.4.132-1075-rockchip-ayufan-ga83beded8524
append rw panic=10 init=/sbin/init coherent_pool=1M ethaddr=${ethaddr} eth1addr=${eth1addr} serial=${serial#} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 root=LABEL=linux-root rootwait rootfstype=ext4
label kernel-next
kernel /boot/Image
initrd /boot/initrd.img-4.4.132-1075-rockchip-ayufan-ga83beded8524
fdt /boot/rk3328-rock64.dtb
append rw panic=10 init=/sbin/init coherent_pool=1M ethaddr=${ethaddr} eth1addr=${eth1addr} serial=${serial#} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 root=LABEL=linux-root rootwait rootfstype=ext4
label kernel-4.4.132-1075-rockchip-ayufan-ga83beded8524-memtest
kernel /boot/vmlinuz-4.4.132-1075-rockchip-ayufan-ga83beded8524
initrd /boot/initrd.img-4.4.132-1075-rockchip-ayufan-ga83beded8524
devicetreedir /boot/dtbs/4.4.132-1075-rockchip-ayufan-ga83beded8524
append rw panic=10 init=/sbin/init coherent_pool=1M ethaddr=${ethaddr} eth1addr=${eth1addr} serial=${serial#} cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 root=LABEL=linux-root rootwait rootfstype=ext4 memtest
クロスコンパイル用マシンにて実行 $ cd linux-next $ scp arch/arm64/boot/Image arch/arm64/boot/dts/rockchip/rk3328-rock64.dtb 192.168.1.xxx:~/ ROCK64にて実行 $ sudo cp Image /boot/ ; sudo cp rk3328-rock64.dtb /boot/ ; sync ; sudo reboot
CPUがAArch64なので生成されるイメージファイルはImageです。デバイスツリーはrk3328-rock64.dtbです。ネットワーク経由でROCK64のユーザ(なんでもよいですが)のホームディレクトリにコピーし、ボード側で /bootにコピーして使っています。またinitrdはオリジナルのものを拝借しています。
1行目のmenu title select kernelが結構大事で、この行を書いておくとU-Bootがカーネルを起動する際に下記のような選択肢が表示されます。
Found /boot/extlinux/extlinux.conf Retrieving file: /boot/extlinux/extlinux.conf 1433 bytes read in 28 ms (49.8 KiB/s) select kernel 1: kernel-4.4.132-1075-rockchip-ayufan-ga83beded8524 2: kernel-next 3: kernel-4.4.132-1075-rockchip-ayufan-ga83beded8524-memtest Enter choice:
この設定はとにかくボードからSDカードの抜き差しをやりたくない一心でできています。
普段はbootメニューで2番を選びlinux-nextカーネルを起動します。もし起動しないカーネルを書き込んでしまったり、ネットワークが死んでいるカーネルを書き込んでしまい、カーネルの更新ができなくなったときは、リブートし1番を選び元々書かれていたカーネルを起動して復旧させます。
何も選択せず放置すると1番が勝手に選ばれますので、おかしくなったら電源をON/OFFして放置すれば、必ずオリジナルのカーネルが起動します。ボードが少し遠くに置いてあって、AC電源ON/OFFからU-Bootの選択肢タイムアウトまでの間にキー入力ができないので、このような設定にしています……。
Tinker Boardの設定も同じ思想で作っています。
# cat /boot/extlinux/extlinux.conf
menu title select kernel
label kernel-4.4
kernel /zImage
fdt /rk3288-miniarm.dtb
append earlyprintk console=ttyS1,115200n8 root=/dev/mmcblk0p2 rw init=/sbin/init
label kernel-next
kernel /linux-next
fdt /rk3288-tinker.dtb
append earlyprintk console=ttyS1,115200n8 root=/dev/mmcblk0p2 rw init=/sbin/init
クロスコンパイル用マシンにて実行 $ linux-next $ scp arch/arm/boot/zImage arch/arm/boot/dts/rk3288-tinker.dtb 192.168.1.xxx:~/ Tinker Boardにて実行 # cp /home/katsuhiro/zImage /boot/linux-next; cp /home/katsuhiro/rk3288-tinker.dtb /boot/; sync; reboot
ROCK64との違いはCPUがAArch32なので生成されるイメージファイルはzImageであることと、デバイスツリーはrk3288-tinker.dtbであることでしょうか。
カーネルをネットワーク経由で更新する点は同じですが、zImageというファイル名だと元々存在するカーネルと被っているので、リネームしています。
目次: Zephyr
海外で最近話題らしいZephyr OSを動かしてみました。
Linuxに似ている、という説明をどこかで見ましたが、ビルドシステムに関して言えば全く似ていません……。コードは似ているのかもしれませんが、見ていません。
動かし方は Zephyr OSのGetting Started にあります。
Zephyr OSをビルドするためには、いくつかPythonのパッケージをインストールする必要があります。pipを実行しても良いという方はpip3 install --user -r zephyr/scripts/requirements.txt で、依存するモジュールをインストールしてくれるそうです。
私は以前pipでPython環境が壊れて嫌な思いをしたので、apt-getで頑張りました。参考までに下記のパッケージをインストールしています。環境はDebian Testing amd64版です。
python3-colorama python3-yaml python3-pyelftools python3-sphinx-rtd-theme sphinx-rtd-theme-common python3-breathe ninja-build sphinx-common
パッケージが足りない場合の探し方ですけども、パッケージが足りないときはPythonのエラーメッセージにModuleNotFoundError: No module named 'aaaa' こんなメッセージが出ることが多いです。apt-file search aaaaを実行すると、パッケージ名がずらーっと出てきますので、その中からpython3- で始まるパッケージを探してください(Python3モジュールのパッケージはpython3-xxxxという名前が多い)。
Getting Startedの通り
git clone https://github.com/zephyrproject-rtos/zephyr
です。
Getting StartedにはZephyr SDKとやらをインストールせよと書いてありますが、色々大切な部分が全部ぶっ飛んでいてわからなくなっている感じがします。幸いcrosstool-NGにも対応していると書いてあったので、crosstool-NGを使ってみました。
基本的には以前紹介した(2018年7月15日の日記参照)、AArch64 Linux用の環境と同じ手順ですが、./ct-ng menuconfigで設定する項目が多少違います。
$ ./ct-ng menuconfig Target options ---> Target Architecture ---> armにする Bitness: ---> 32-bitにする Toolchain options ---> Tuple's vendor string zephyrにする Operating System ---> Target OS ---> bare-metalにする $ ./ct-ng build [00:34] /
しばらく待つとarm-zephyr-eabiというプレフィクスを持つクロスコンパイラが生成されるはずです。
Zephyr OSのビルドに使用するクロスコンパイラを、~/.zephyrrcに環境変数を定義して指定します。変な作りだなあ……。
export ZEPHYR_TOOLCHAIN_VARIANT=xtools
export XTOOLS_TOOLCHAIN_PATH=/home/katsuhiro/x-tools
注意点としてはXTOOLS_TOOLCHAIN_PATHのx-toolsの後のパスは勝手にarm-zephyr-eabiが使われ、自由に指定できないことです。この点についてはLinuxのCROSS_COMPILE環境変数とは異なるうえ、Zephyrの方が後発にも関わらず退化しています。どうしてこうなった……。
ビルドする前に2手ほど準備が必要です。1手目は環境変数のセットアップです。
cd zephyr source zephyr-env.sh
2手目はcmakeの実行です。
$ cd sample/hello_world $ mkdir build $ cd build $ cmake -GNinja -DBOARD=qemu_cortex_m3 ../ Zephyr version: 1.13.99 -- Found PythonInterp: /usr/bin/python3 (found suitable version "3.7.2", minimum required is "3.4") -- Selected BOARD qemu_cortex_m3 Parsing Kconfig tree in /home/katsuhiro/share/projects/oss/zephyr/Kconfig Loading /home/katsuhiro/share/projects/oss/zephyr/boards/arm/qemu_cortex_m3/qemu_cortex_m3_defconfig as base Merging /home/katsuhiro/share/projects/oss/zephyr/samples/hello_world/prj.conf Configuration written to '/home/katsuhiro/share/projects/oss/zephyr/samples/hello_world/build/zephyr/.config' -- Loading /home/katsuhiro/share/projects/oss/zephyr/boards/arm/qemu_cortex_m3/qemu_cortex_m3.dts as base -- Overlaying /home/katsuhiro/share/projects/oss/zephyr/dts/common/common.dts -- Cache files will be written to: /home/katsuhiro/.cache/zephyr -- The C compiler identification is GNU 8.2.0 -- The CXX compiler identification is GNU 8.2.0 -- The ASM compiler identification is GNU -- Found assembler: /home/katsuhiro/x-tools/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc -- Performing Test toolchain_is_ok -- Performing Test toolchain_is_ok - Success -- Configuring done -- Generating done -- Build files have been written to: /home/katsuhiro/share/projects/oss/zephyr/samples/hello_world/build
CMakeを採用しているプロジェクトは大抵、ソースコードのトップディレクトリにあるCMakeLists.txtを指定しますが、Zephyr OSの場合、sample/* の下にあるCMakeLists.txtを使わなければなりません。わからんわ、そんなの。変な作りだな……。
間違ってZephyr OSのトップディレクトリにあるCMakeLists.txtを指定すると、こんなエラーメッセージで怒られます。
$ cmake -GNinja -DBOARD=qemu_cortex_m3 ../ CMake Error at CMakeLists.txt:13 (message): A user error has occured. cmake was invoked with '/home/katsuhiro/share/projects/oss/zephyr' specified as the source directory, but it must be invoked with an application source directory, such as '/home/katsuhiro/share/projects/oss/zephyr/samples/hello_world'. Debug variables: CMAKE_CACHEFILE_DIR: CMake Warning (dev) in CMakeLists.txt: No cmake_minimum_required command is present. A line of code such as cmake_minimum_required(VERSION 3.13) should be added at the top of the file. The version specified may be lower if you wish to support older CMake versions for this project. For more information run "cmake --help-policy CMP0000". This warning is for project developers. Use -Wno-dev to suppress it. -- Configuring incomplete, errors occurred!
エラーメッセージからは、何が悪いのか全く分かりません……。
ビルドと実行は難しくありません。どちらかというとここまでたどり着くのがかなり面倒くさいです。
$ cd sample/hello_world/build $ ninja [1/103] Preparing syscall dependency handling [98/103] Linking C executable zephyr/zephyr_prebuilt.elf Memory region Used Size Region Size %age Used FLASH: 8604 B 256 KB 3.28% SRAM: 4160 B 64 KB 6.35% IDT_LIST: 120 B 2 KB 5.86% [103/103] Linking C executable zephyr/zephyr.elf $ ninja run [0/1] To exit from QEMU enter: 'CTRL+a, x'[QEMU] CPU: cortex-m3 qemu-system-arm: warning: nic stellaris_enet.0 has no peer ***** Booting Zephyr OS zephyr-v1.13.0-3162-g73956a398e ***** Hello World! qemu_cortex_m3
何をしているのか全然わかりません。仕方ないのでbuild.ninjaファイルからqemuを実行しているところを発掘してみたら、下記のコマンドを実行しているようです。
$ /usr/bin/qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -vga none -net none -pidfile qemu.pid -serial mon:stdio -kernel /home/katsuhiro/share/projects/oss/zephyr/samples/hello_world/build/zephyr/zephyr.elf qemu-system-arm: warning: nic stellaris_enet.0 has no peer ***** Booting Zephyr OS zephyr-v1.13.0-3162-g73956a398e ***** Hello World! qemu_cortex_m3
期待される結果が良くわからないんですが、これで動いたと言って良いんだろうか…??
TP-Linkのスマートプラグを利用するにはKASA Smartというアプリをスマホに入れないと微塵も動きません。このアプリの利用規約には同意不可能な条項があって、
法的資格
(中略)お客様は利用にあたりお客様に適用するすべての法律を遵守しなければなりません。準拠法が利用を禁ずる場合はお客様は本サービスを利用することはできません。
ユーザーのコンテンツ
(中略)
2. 世界のあらゆる場所で享受できるユーザーコンテンツに対する全ての人格権を放棄し、そのような権利の主張ができないことを確認する。
と書いてあります。TP-Linkは、ユーザーがフォーラムに投稿した質問、レビュー、回答などを勝手に使うけど、文句言わないでね?と言いたいみたいです。
その主張については同意しますけど、、、
日本では著作者人格権は譲渡できません(著作権法59条)、放棄規定はありませんが、包括的に放棄はできないと考えられており、日本においてTP-Linkの利用規約にYesと答えることはできません。
規約内で矛盾がある場合に、利用者が同意してしまうと、この契約はどうなるんでしょう、無効になるの…?
TP-Linkは中国の会社ですから、この利用規約は中国でもほぼ同じなのではないかと思うんですが、中国って著作者人格権の放棄はできるんですかね?
規約のことは忘れて、スマートプラグを使ってみました。
スマホから電源ON/OFFの指示を送ると、スマートプラグから「カッ!!」というかなり大きめのリレー音がしてうるさいです。今日も元気なことがわかって安心……?
使って初めて知ったのですが、スマホからスマートプラグへの電源ON/OFFの指示は必ずTP-Linkのサーバーに飛んで行くんですね。インターネット接続のできない場所ではスマホのアプリが起動しないため、電源ON/OFF指示ができません。
インターネット接続がなくても、スマートプラグ本体の電源ボタンを押せば電源ON/OFFできますが、そこまで行けるならTinker Boardを直接リセットした方が遥かに早いです。
昔から、ネットワーク対応のACタップは売られていましたが(Pingを打つと電源が落ちる、WebインタフェースでON/OFFできるなど)、いずれも1万円〜数万円の製品です。
従来製品と比較して、サーバーの維持費も追加で必要なはずなのに、大抵のスマートプラグは2,000円〜5,000円で販売されています。機能の割に破格の値段だと思います。
単純に考えると、外出中(=インターネット側から)に、宅内の電源をON/OFFするため、何らかのサーバーを経由しているのでしょう。
嫌らしく考えると、スマートプラグはサーバーを経由させることで、ユーザーの生活情報を強制的に奪えますから、将来に情報が何かに使えることを見込んで、破格の値付けでばら撒いているのでしょう。
Tinker Board上でlinux-nextを実行するとreboot時にハングしてしまい、その後ウンともスンとも言わなくなるので、外部からボードの電源ON/OFFする方法を探していました。考え付いた方法は3つです。
1番目は下手なハンダ付けをして、失敗するとボードが壊れることと、制御用にもう1つボードが要るのは何だかダサいのでやりたくありません。
2番目の線で探していたのですが、USBの給電をON/OFFできる製品って、意外とないですね……。
仕方なく3番目の線で、TP-LinkのスマートプラグHS105を購入しました(メーカーの製品サイト)。Amazonで2,600円です。Wi-Fiが内蔵されている割に、ずいぶん値段が安いですね。
メモ: 技術系の話はFacebookから転記しておくことにした。少し加筆した。
< | 2019 | > | ||||
<< | < | 01 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | 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 | - | - |
合計:
本日: