Windowsでopensslクレートを使う

opensslクレートをGNU ABIで使おうとして苦労した。

MSVC ABIの場合は、特に苦労せず、すんなりとビルドできて、実行もできた。

MSYS2が必要

choco install msys2で入れた。chocolatey使っていなければ、普通にMSYS2をダウンロードしてインストールすればよいと思う。なお、今回はx86_64を使った。

MINGW64と同じOpenSSLが必要

こちらのサイトからダウンロードした。MSYS2に入っているOpenSSLとバージョンを合わせる必要がある。今回はWin64 OpenSSL v1.0.2pを利用した。v1.1系を入れると次のようなエラーが出てビルドできない。

$ OPENSSL_LIB_DIR=/c/OpenSSL-Win64 OPENSSL_INCLUDE_DIR=/c/OpenSSL-Win64/include /c/Users/Akimasa/.cargo/bin/cargo run
   Compiling openssl-sys v0.9.35
error: failed to run custom build command for `openssl-sys v0.9.35`
process didn't exit successfully: `C:\Users\Akimasa\Documents\src\rust_openssl\target\debug\build\openssl-sys-8515c615cbb8f8fa\build-script-main` (exit code: 101)
--- stdout
cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_LIB_DIR
cargo:rerun-if-env-changed=OPENSSL_LIB_DIR
cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_INCLUDE_DIR
cargo:rerun-if-env-changed=OPENSSL_INCLUDE_DIR
cargo:rustc-link-search=native=C:/OpenSSL-Win64
cargo:include=C:/OpenSSL-Win64/include
OPT_LEVEL = Some("0")
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
TARGET = Some("x86_64-pc-windows-gnu")
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
CC_x86_64-pc-windows-gnu = None
CC_x86_64_pc_windows_gnu = None
HOST_CC = None
CC = None
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
CFLAGS_x86_64-pc-windows-gnu = None
CFLAGS_x86_64_pc_windows_gnu = None
HOST_CFLAGS = None
CFLAGS = None
DEBUG = Some("true")
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
CFLAGS_x86_64-pc-windows-gnu = None
CFLAGS_x86_64_pc_windows_gnu = None
HOST_CFLAGS = None
CFLAGS = None
TARGET = Some("x86_64-pc-windows-gnu")
HOST = Some("x86_64-pc-windows-gnu")
CFLAGS_x86_64-pc-windows-gnu = None
CFLAGS_x86_64_pc_windows_gnu = None
HOST_CFLAGS = None
CFLAGS = None
running: "gcc.exe" "-O0" "-ffunction-sections" "-fdata-sections" "-g" "-fno-omit-frame-pointer" "-m64" "-I" "C:/OpenSSL-Win64/include" "-Wall" "-Wextra" "-E" "C:\\Users\\Akimasa\\Documents\\src\\rust_openssl\\target\\debug\\build\\openssl-sys-e711f0916b783511\\out\\expando.c"
exit code: 0
cargo:rustc-cfg=osslconf="OPENSSL_NO_SSL3_METHOD"
cargo:conf=OPENSSL_NO_SSL3_METHOD
cargo:rustc-cfg=ossl101
cargo:rustc-cfg=ossl102
cargo:rustc-cfg=ossl102h
cargo:rustc-cfg=ossl110
cargo:rustc-cfg=ossl110f
cargo:rustc-cfg=ossl110g
cargo:version_number=1010009f
cargo:version=110
cargo:patch=f
cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_LIBS
cargo:rerun-if-env-changed=OPENSSL_LIBS
cargo:rerun-if-env-changed=X86_64_PC_WINDOWS_GNU_OPENSSL_STATIC
cargo:rerun-if-env-changed=OPENSSL_STATIC

--- stderr
thread 'main' panicked at 'OpenSSL libdir at `C:/OpenSSL-Win64` does not contain the required files to either statically or dynamically link OpenSSL', C:\Users\Akimasa\.cargo\registry\src\github.com-1ecc6299db9ec823\openssl-sys-0.9.35\build/main.rs:595:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.

ビルドする

普通にVisual Studio CodeのPowerShellからcargo buildでビルドしたが…

 Running `target\debug\rust_openssl.exe`
error: process didn't exit successfully: `target\debug\rust_openssl.exe` (exit code: 3221225477)

こんなエラーが出て実行できないバイナリが出てくる。

$ OPENSSL_LIB_DIR=/c/OpenSSL-Win64 OPENSSL_INCLUDE_DIR=/c/OpenSSL-Win64/include /c/Users/Akimasa/.cargo/bin/cargo run

先ほどにも出てきたが、MINGW64を使って上記のコマンドを実行する必要がある。

こちらの投稿が参考になった

念のためもう一度試したら、PowerShellでもビルドが通って、実行もできたので頭を抱えている。

下記のようにOPENSSL_LIB_DIRとOPENSSL_INCLUDE_DIRを指定する必要がある。あと、MINGW64(自分の場合は”C:\tools\msys64\mingw64\bin”だった)へPATHを通す必要もある。

$env:OPENSSL_LIB_DIR="C:\OpenSSL-Win64\"
$env:OPENSSL_INCLUDE_DIR="C:\OpenSSL-Win64\include"
$env:PATH="$env:PATH;C:\tools\msys64\mingw64\bin

 

ThinkPad T480sを入手した

USB-Cポートが怪しげな感じで、サポートも改善するつもりが無いポリシーだという点以外、特に不満は無い。USB-Cが採用されて日が浅いので、仕方がない。(なお、この記事は必要に応じて加筆・修正されている。最終更新:8/22 部品販売について追記)

良かった点

Windows Helloの顔認証

結構早い。開いたら瞬時にログインされる。

高解像度ディスプレイ

Retina Displayみたいな奴。フルHDの通常のモデルよりも発色が良いとレビューサイトに書いてあった。sRGBのほとんどをカバーしていたとか。

NVMe SSD(OPAL対応)

常に暗号化されている。パスワードをかけて安全に使うことができる。普段はパスワードをかけていなくても、常に暗号化されているので、暗号鍵を破棄することで瞬時に全体を消すことができる。これは便利。修理に出すときに全セクタ書き込みとかしなくても瞬時に消去できる。ただ普通のSSDでもSecure Eraseできれば、それで充分ではあるが…

保証期間

到着まで時間がかかるからか、少し保証期間に余裕がある。1年2か月だった。

また、保証期間内なら後からアップグレードできる。1万円ちょい足せば1年保証を3年保証にできたりする。

修理

PC Watchの記事によれば、NEC PC群馬事業所で修理されるとのことだ。到着して1時間半ほどで修理が終わった例もあるようだ。自分の場合は首都圏から出したが、引き取りの翌日の8/15に到着して、8/20に修理完了し発送、8/21には手元に戻ってきた。ちなみに、修理に出したが問題は解決していない。技術サポートではポリシーで周辺機器の相性は保証できないといわれたが、リペアセンターではiPhoneを使った動作確認を行ったようだ。この点は評価したい。非常に良いと思う。が、一貫しないポリシーだとも感じた。

CRU

キーボードなどはパーツを送ってきてもらって自分で修理できるというIBM時代からのCRUの制度が今も続いているはず。キーボードなどはパーツを送ってきてもらって自分で修理できる。参考までに2004年の記事を挙げておく

封印シールが無い

SSD、メモリを増設しても保証が切れない(はず)。裏蓋に封印シールなどは無く、特殊なねじでもなく、普通のドライバーで開けられる。ただ、修理に出すときは増設したパーツは元に戻した方が良さそうだ。それと、ナイロン被覆ねじが使われていて、緩みにくいようになっているらしいので、ねじの再利用は控えた方がよいのかもしれない。

修理用部品販売

パーツを買って自分で修理することもできる。保守マニュアルも公開されていて、簡単にパーツを交換できるようになっている。

2018年8月現在、発送手数料は1部品につき1500円(税抜)かかるようだ。スマートセンターの修理窓口から見積もりの請求をしてもらった。利用する人が多いからか、対応はスムーズだった。見積書は郵送、FAX、メールの3種類から選べる。メールで送ってもらった。家のT450sのキーボードが消耗しているので交換しようと思って見積もってもらったが、部品代が13000円弱(税抜)でこれに加えて発送手数料がかかる。AliExpressや米Amazonのマーケットプレイスみたいな怪しげな所だと30ドルくらいで手に入りそう。米国のIBM部品販売では価格が1500ドルと出ていた。誤植なのか、希少なので値上がりしているのか不明だ。代替品だと60ドル台だった。これに加えて発送手数料は15ドルかかるようだ。スマートセンターから購入すると少し高い印象だが、純正部品を国内から安全に購入できるのでありがたい。

キーボードの打ち心地

ノートPCの新品のキーボードを使うのは久しぶりなので、打った感覚が少し新鮮だった。なんとなく、再生品で即日返品したSurface Bookに近い感じな気がする。非常にいい感じだ。

無線の安定性

以前使っていた、T430と比較して、Bluetoothが安定している気がする。距離が離れてもBluetoothヘッドホンが音飛びしない。

耐久性

MIL規格を通るといわれている頑丈さ。昔のモデルの方が頑丈だとか言う声も聞くが、昔(T430)も今(T480s)も剛性は充分に思える。指で押してみた限りでは、今の方がへこまない気がする。昔のは、表面がプラスチックで中にロールケージがある構造からか、押すと少しへこむ。

ただ、キーボードは排水構造が無くなっているので、もしかすると耐水性が落ちているのかもしれない。YouTubeに実際に水を掛けたら壊れた映像があった。

微妙な点

NEC品質?のサポート

あまりサポートを受けたことがないので、よくあることなのかもしれない。サードパーティのデバイスとの相性については保証外というポリシーだった。以前にもNEC系列のサポートを受けた時に同じような対応だった。

以前、AtermでRaspberry Piとの相性問題が発生したことがあった。再現方法等詳細を送ったが、対応するつもりは無い様だった。

今回はThinkPadとNECのLAVIE Direct NEXT, LAVIE Direct NSでもiPhoneを認識しない問題を確認できた。しかし、NECレノボ以外の多数のメーカー(東芝、富士通、LG、VAIO、ASUS)では何も問題が起こらなかった。このことを伝えたが、他社の周辺機器については保証しないサポートポリシーなので、対応するつもりは無い様だ。

サードパーティの製品についてサポートを行わないのは、ある程度理解できる。中国の聞いたことも無いメーカーが出しているデバイスを認識しないとか言われても困る。しかし、iPhoneという日本では半数近くの人が使っているデバイスで起こる問題すら対応しないというのは、どうかと思う。しかも、NECレノボに限って問題が起こっていて、他社製品では起こらない問題だ。自分の製品がおかしいとは思わないのだろうか。そもそも、今時、相性問題なんて起こして恥ずかしくないんだろうか。もっとも、iPhoneがUSBデバイスとしておかしい可能性も考えられるが…

USB Type-Cポートが相性問題を起こしやすい

USB-Cケーブルで手元にあるEssential Phone PH-1とiPhone SEを接続したが、両方とも充電はされるが、デバイスとして認識されない結果となった。著名ライターがDPケーブルでトラブったという話を聞いたことがある。そのため、USBケーブルが怪しいのではないかと思い、買い足した。しかし、ケーブルを変えても依然、問題は解決せずに電話が認識されない。また、手元にある2台の電話を各種他社製のPCに接続したところ、正常に認識されて、写真のアクセスができる。ThinkPad T480sのUSB-Cポートは充電や純正ドックとの接続くらいしか期待できないものだと考えた方が良さそうだ。

USB-CにはAlternate Modeというのが存在するらしく、ThunderboltやDisplayPort、HDMIの信号も通すことが可能らしいが、これらについてはテストできていない。いずれ、試そうと思う。

納期が長い。そして、変動する

自分の場合は届くまで2週間ちょいかかった。変動することはなかったが、1か月以上待つ人もいるとかいないとか。14日以上出荷されない場合はキャンセルが可能だったはずなので、必要に応じて利用するとよいかもしれない。

ThinkPad T480sとiPhoneの相性問題

Lenovoのフォーラムの記事によれば、iPhone 8とT480sをUSBケーブルで接続した場合、うまく動かない。T480sとiPhone 8のソフトウェア、ファームウェア、BIOS、ドライバを全て最新にしても現象は再現する。複数のT480s、iPhone 8、Lightningケーブルでテストしたが、同じく現象が再現する。PCが起動中に右のUSBポートに接続すると問題無く動作する。USB-Cポートでも同様の現象が起こる。他のPCでは再現しない。との事だった。

自分もiPhone SEで同じような現象が起こった。右側のUSBポートに接続すると接続と切断を繰り返す。ただ、この現象はケーブルによって再現したりしなかったりだ。USB-Cポートでは認識すらしない。

ヨドバシアキバに行って、T480sの展示機でUSB-Cポート試してみたが、やはり現象は再現していた。何なら近くにあったNECのノートPCでも現象は再現した。

しかし、家の近所にあるビックカメラに展示されているPCでは、全く再現しなかった。ヨドバシアキバで異なる2台のPCで認識しない現象が再現したので、あー、これはケーブルの初期不良だな(Essential Phone PH-1の場合、ケーブルに問題があったので、またか…と思った)と思ってケーブルを買ったビックカメラに行って初期不良なので交換してほしいと主張したが、見事に現象が再現せず、ケーブルの問題ではない可能性が高いことが判明した。

NEC PCでも再現したし、NECがレノボの購買を使っているとかいう話を聞くので、NECとレノボは同じルートで部品を仕入れている可能性がある。NECとレノボが共通で使っていて、共同で仕入れている何らかの部品に不良があって問題が起こっているのではないかと推測している。憶測に過ぎないが…。

8/21追記:

T480sが修理から戻ってきたが、OSのリカバリだけされて解決したとの報告だった。しかし、自分の環境では依然iPhone SEがUSB-C – Lightningケーブルで接続しても充電されるが認識されない。Essential Phone PH-1もケーブルが怪しいとのことだったが、追加購入したUSB-Cケーブルで試しても認識されなかった。T480sのUSB Type-Cは怪しいので、あまりあてにしないことにする。

USB Type-Cケーブルが信用できない

8/21追記:

T480sのUSB Type-Cがおかしい疑いが強く、ケーブルを変えても現象は再現するので、撤回させてください。

T480sを入手したのは良いが、USB周りが怪しげな感じだ。果たしてこれは自分のT480sの問題なのか、すべてのT480sで起こる問題なのか、USBケーブルの問題なのか、電話の問題なのか、はっきりとわからないが、いろいろ調べてみた。

どんな問題が起こるかというと、まずはType-Cコネクタに電話を接続しても認識しない。Essential Phone PH-1とiPhone SEを、それぞれ純正のType-Cケーブルで接続した。が、デバイスマネージャーに表示されない。充電はされている。

ああ、これはT480sのUSB Type-Cが壊れているなと思ってLenovoの技術サポートに連絡した。オンラインフォームに入力して、今すぐ電話かけてもらうということにして、営業時間開始の9時過ぎにポチって、2,3分で電話がかかってきた。かなり繋がりやすいようだ。お盆の休み中だというのも関係しているのかもしれない。問題を説明して、技術サポートから得られた回答は、他社の周辺機器については保証されないとのことだった。まあ、これは仕方がない。線引きしないと無限にサポートすることになるだろう。しかし、修理に出して見てみることはできるらしい。修理拠点で問題が再現しなくてすごく時間がかかる可能性があるとのことだった。出張修理してくれるオンサイト修理という選択肢も保証をアップグレードすると可能らしいが、オンサイト修理なら現象を確実に再現できるのでどうだろうかと聞いてみた。そしたら、オンサイト修理は電話で故障個所が特定できて、部品を交換する場合のみ使えるということだった。オンサイト修理というのは出張して問題の特定から修理まですべて行ってくれるものだと思っていたのだが、違ったようだ。結局、引き取り修理を依頼することにした。ちなみに問い合わせはすぐに回答が出たわけではなく、9時過ぎに受付して、昼過ぎに答えが返ってきたという感じだった。

引き取り修理を手配してもらったが、手配した翌日の午前中に佐川急便が引き取りに来てくれた。Appleの修理の時はヤマト運輸が使い捨ての梱包材を持ってきて、引き取られる形だったが、レノボやNECは佐川急便が年季の入っていそうな再利用できる梱包材で引き取られる。

引き取られて、ふと、1つの疑問がわいた。この問題は全てのT480sで共通して起こるのか、それとも自分の手元にある個体固有の問題なのか。他のT480sで問題が起こらなければ、うちのT480sがおかしいと強く主張できる。秋葉原のレノボカスタムショップに行って試してみたが、結局、すべてのT480sで同じく認識されなかった。T480sにすぐに触れなかったので、店員がNECのPCでも試してみればどうかと提案してくれた。試してみたら、iPhoneは認識されず、AndroidのPH-1は認識されたという結果になった。しばらくしたらT480sに触れるようになったので、試したところ、こちらは2台の電話とも認識されないという結果になった。WindowsマシンではUSB-C LightningケーブルでiPhoneは認識されない様だ。

家に帰り、USB-C Lightningケーブルについてふと調べたら、次のような文言が引っかかった。

iPhone、iPad、または iPod touch を Mac または Windows パソコンの USB-C ポートに接続して、デバイスを同期したり写真を読み込んだりする。

どうやらWindows PCでも使えるはずらしい。それでは展示機で認識されなかったのは謎である。ヨドバシアキバのAppleコーナーで保証はないという情報も謎だ。

てことは、USBケーブルが怪しいのではないか?と思えるようになってきた。iPhoneとPH-1の純正ケーブルが2本とも破損していたとすれば、これまでに起きた謎現象は説明が付きそうだ。

早速、Amazonでケーブルを発注した。USB-CケーブルはAmazon Basics製で、Lightningケーブルは聞いたことが無いメーカー製のもので安いものを選んだ。Amazonの事だけあって翌日には受け取れそうだが、T480sは修理に出してしまったので、返ってくるまでテストができない。新しいケーブルで問題が解決できると良いな。

新しいケーブルで解決したら、純正のLightningケーブルを交換に出さないといけない。Apple製品は返品が効くかどうか謎だ。初期不良も含めてAppleのサポートを通すことになっているっぽいし。あと、PH-1純正のUSB-Cケーブルの方は充電専用にでもするか。

PH-1に付属しているケーブルは充電用らしいことが判明した。ケーブルが原因のようなので、タイトルを修正した。

VPNですべての通信が通らないようにする

SoftEther VPNで192.168.1.0/24なネットワークにSecureNATで接続したのは良いが、標準だとインターネットへ向けた通信すべてがVPN経由で行われてしまう。これは、ちょっと速度が遅くなりそうで不都合なので下記のようにしてWindows 10のルーティングテーブルのメトリックを変更してうまいこと行くようにした。

route change 192.168.1.0 mask 255.255.255.0 192.168.30.1 metric 1 if 14
route change 0.0.0.0 mask 0.0.0.0 192.168.30.1 metric 100 if 14

V-USBのhid-dataコマンドラインをmingw32でコンパイル

mingw32でV-USBのサンプルにある、hid-dataのコマンドライン(https://www.obdev.at/products/vusb/download.html のvusb-20121206/examples/hid-data/commandline)をコンパイルしようとしたら、うまくいかなかった。

これをヒントに、”ddk/hidpi.h”->”hidpi.h”に書き換えたらうまくいった。

 

Bash on Windowsのデフォルトディストロを変更する方法

bash -c “redis-server”でredis-serverが起動しなかった。原因は、おそらくDebianとUbuntuの2種類のLinuxが入っているためだが、どうやって解決するかすぐにはわからなかった

wsl-configを使うと良い。これを使うとbash.exeで呼び出されるLinuxを変更することができるらしい。wslconfig /setdefault “Ubuntu”で解決した。

gitであるremoteから異なるremoteにbranchをコピーしたい

git push gcp remotes/origin/panic3:panic3

git push dst remotes/origin/branch:branchとかgit push dst origin/branch:dst/branchとかgit push dst origin/branch:branchとか試したが、うまくいかず、ググったらgit push dst origin/branch:refs/heads/branchだと判明した。

error: unable to push to unqualified destination: branch
The destination refspec neither matches an existing ref on the remote nor
begins with refs/, and we are unable to guess a prefix based on the source ref.

と出ていたが、よくわからなかったので無視していたが、refs/から始まるという重要なヒントを見逃していた。

参考:https://stackoverflow.com/questions/7818927/git-push-branch-from-one-remote-to-another