0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

古いバージョンのglibcを用いる実行モジュールのビルド環境をlxdでサクッと構築する手順

Last updated at Posted at 2024-04-04

はじめに

Steam で Linux に対応したゲームを配信しているのですが、ユーザーさんから 「glibc のバージョンを下げてくれないか?」 と依頼されました。

Linux 版のゲームを自分の PC (Ubuntu 22.04.4 LTS) でローカルビルドしたものをリリースしていたのですが、その環境の glibc は 2.35、実行モジュールの glibc バージョンは 2.34 となっています。

(glibc のバージョン確認)

$ ldd --version
ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

(ゲームモジュールの依存 glibc バージョンの確認方法)

$ readelf -W -a '~/.local/share/Steam/steamapps/common/Battle Marine/bmarine' | grep libc_start_main
0000000000285fb0  0000002100000006 R_X86_64_GLOB_DAT      0000000000000000 __libc_start_main@GLIBC_2.34 + 0
    33: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34 (4)
  1082: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34

ビルド環境の Linux はもっと低いバージョンの Linux にする必要がありそうです。

コンテナでビルド環境を構築

もちろん、自分の PC の Linux バージョンは下げたくないので、ビルド用に古い Linux のコンテナを作ります。

コンテナといえば Docker がよく使われるかもしれませんが、今回のケースなら lxd の方が軽くて良い感じでしたので、私が実施した構築手順を共有します。

lxd を準備

sudo snap install lxd
sudo lxd init

lxd init の設定項目は全部デフォルト(enter)

コンテナ作成

lxc launch ubuntu:18.04 steam-build

当初、なるべく古いバージョンが良いかと思い ubuntu は 16.04 をインストールしてみたのですが、ネットワークが繋がらないなど色々と不便だったので 18.04 を使うようにしました。(多分、古いバージョンを使うには色々と面倒な設定が必要なはず)

コンテナへのログイン

lxc exec steam-build bash

コンテナにビルド環境を構築

sudo apt update
sudo apt install build-essential

あとは github の環境設定なりをしてビルドするだけです。

なお、コンテナから外部ホストへの通信がタイムアウトする場合は iptables の変更などが必要になるかもしれません。

この環境でビルドしたモジュールの GLIBC バージョンは 2.2.5 になりました。

$ readelf -W -a bmarine | grep start_main
000000000047cfd0  0000005a00000006 R_X86_64_GLOB_DAT      0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
    90: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (3)
  2567: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_2.2.5

コンテナの起動・停止・削除

# 起動
lxc start steam-build

# 停止
lxc stop steam-build

# インスタンス削除
lxc delete steam-build

もっと美しい対処

今回、GLIBC のバージョンを下げる対応をしましたが、GLIBC のバージョンを下げなくてもコンパイルとリンク時に次のオプションを指定することで GLIBC バージョン依存の問題を解消できるようです。

-static-libgcc -static-libstdc++ -ftls-model=global-dynamic
  • -static-libgcc will dodge libgcc ABI issues (which are common)
  • -static-libstdc++ will dodge c++ ABI issues (which are legions and happening all the time)
  • -ftls-model=global-dynamic will spare ELF static TLS slots for system libs (because they are somewhat rare)

私はビルド環境の CI 化のためにコンテナを用いる方式も別途検討していて、その方式の方が色々とリスクが少ないかなということでコンテナ方式を採用しましたが、こちらの対処方法の方が良いと思います。

今回はこのオプションを付与しつつ古いバージョンのGLIBCを使う安全策を取っておいたので、今後GLIBCのアップデートが必要になっても同じ問題を回避できるかもしれません。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?