JetsonでROS1/ROS2を使う際のCUDA互換性問題と解決策
はじめに
古い世代のJetsonでROS 1/ROS 2を動かそうとした際、CUDAの互換性問題やJetPackの制約に直面しました。特に、新しいROS 2 Jazzyと古いCUDAツールキットの組み合わせで発生する問題の解決策を探る中で、Jetson特有の技術的な制約について理解を深める機会がありました。
この記事では、JetsonでのROS 1/ROS 2環境構築における技術的な課題と解決策について、調査結果と手元のJetsonでの動作確認結果をまとめます。
なお、この記事では実装の詳細には触れません。
NVIDIAのソフトウェア関連は名称が変わることもあるので、基本的なところから整理しています。
CUDAツールキットとドライバの関係性
基本構成
NVIDIAのハードウェアを使うためのソフトウェアは、CUDAツールキット(ライブラリ)とNVIDIAドライバの2つに分かれています。

https://docs.nvidia.com/deploy/cuda-compatibility/index.html より引用
重要な特徴
-
CUDAツールキット:GPUが存在しないハードウェアでもビルド等には使用可能
- Apple Silicon搭載のMacBook上のDockerなどでも利用できる
- CUDAドライバ:基本的にアプリケーションに同梱できない
- 互換性の制約:実行環境のCUDAドライバが古く、ランタイムが要求するドライバAPIをサポートしていなければ、アプリケーションは動作しない
ソフトウェアスタック
CUDAアプリケーションは以下の階層構造で動作しています。
アプリケーションコード → CUDAランタイム API → CUDAドライバ API → GPUハードウェア
この依存関係のため、新しいCUDAランタイムを静的リンクしても、実行環境のCUDAドライバが古ければランタイムが要求するドライバAPIをサポートせずアプリケーションは動作しません。
JetPack
JetPackの構成
NVIDIAのSBCであるJetsonは「JetPack」と呼ばれるソフトウェア群を導入して動作します。
JetPack = OS + NVIDIAドライバ + CUDAツールキット + その他諸々
- その他諸々
- Jetson用のNVIDIA Container Toolkit(旧nvidia-docker2)
- OpenCV
- その他NVIDIA製ライブラリ
Jetson Linux(OS)
基本特徴は以下の通りです。
- UbuntuベースのカスタムOS
- Jetson対応のためにNVIDIAがカスタマイズ
-
NVIDIA® Jetson™ Linux Driver Package is the board support package for Jetson. It includes Linux Kernel, UEFI bootloader, NVIDIA drivers, flashing utilities, sample filesystem based on Ubuntu, and more for the Jetson platform.
-
- 昔(JetPack 4まで)は「L4T」と呼ばれていた
残念ながら使う上で少し不便な制約があります。
-
Ubuntuのリリースから2年遅れて公開
- Ubuntu 22.04ベースのJetson Linuxは2024年に公開
- OSバージョンの問題で、アプリケーション開発の際にはDockerやパッケージマネージャによるバージョン切り替えが多用される
- NVIDIA公式のサンプルもDockerを前提としたものが多数
-
ホストOSのアップグレードが困難
- 通常のPCでは
do-release-upgradeコマンドなどでUbuntuのバージョンを簡単に上げられるが、Jetsonでは困難 - ハードウェアが特定のバージョンのOSに紐付いているため、ライブラリバージョンも事実上固定される
- 仮想環境やコンテナである程度新しいバージョンにも追従可能だが、ホストOS自体の変更は基本的に不可
- 古いOSではglibcのバージョンが古いため、Dockerコンテナ実行時などでエラーが発生する(ことがある)
- Dockerオプションで回避可能(ただしセキュリティ観点では推奨されない)
- 通常のPCでは
Jetson用NVIDIA Container Toolkit
PC用GPUとの違い
Jetson用のNVIDIA Container Toolkitは、PC用GPUに使うNVIDIA Container Toolkitとは異なる特殊なソフトウェアです。
Dockerコンテナ起動時にホストOSからNVIDIAドライバやCUDAツールキットがマウントされます
- JetPack 4まで:NVIDIAドライバとCUDAツールキットがマウントされる
- JetPack 5から:NVIDIAドライバのみがマウントされる
L4T Baseイメージ
NVIDIAが公式で公開しているL4T Baseイメージは、JetsonのGPUにアクセスできるようDockerfile内で予め設定済みです。
- JetPackと同じバージョンのUbuntuをベースに作成
- 主にEGL(Embedded-System Graphics Library)関連が設定済み
JetPackの書き込み方法
JetPackの書き込み方法は以下の2つがあります。
-
SDK Manager経由
- Ubuntu用アプリケーション
- Windows版SDK Managerも存在するが、JetPackの書き込みには未対応(2025年7月時点)
- PCとJetsonをUSB接続して書き込み
- Ubuntu用アプリケーション
-
microSDカードへのFlash
- microSDカード対応モデル(Jetson Orin Nanoなどエントリーモデル)のみ
- イメージファイルをmicroSDカードに書き込み
同じモデルのJetsonであれば、microSDカードやSSDをクローンして動作させることも可能です。
Compute CapabilityとCUDA
Compute Capability
NVIDIAのGPUやJetsonには「Compute Capability」という概念があります。
Pascal、Turing、Ampereなどのコードネームで呼ばれているアーキテクチャごとに異なります。

https://www.macnica.co.jp/business/semiconductor/articles/nvidia/133162/ より引用
各ハードウェアのCompute Capability
- 7.2:Jetson AGX Xavier、Jetson Xavier NX
- 8.7:Jetson AGX Orin、Jetson Orin NX、Jetson Orin Nano
詳細はNVIDIAの公式ページにまとまっています。
世代による制約
- 新しい世代のハードウェアになるほどCompute Capabilityの数値が大きい
- Compute Capabilityが上がると、必要なCUDAツールキットのバージョンも上がる
ビルド時の制約
新しいハードウェア対応バイナリをビルドするには、対応バージョンのCUDAツールキットとGCCが必要です。
例えば、Jetson Orin NXにはJetPack 5以降に同梱されているCUDAツールキットが必要になります。
重要な制約
- CUDAツールキットリリース時点で未発表のハードウェア向けバイナリは原則ビルドできない
- 新しいCUDAツールキットでは、古いハードウェアへのサポートが終了することもある
- CUDAツールキットに対応するGCCのバージョンは限定的
- CUDA 10.0:GCC 7
- CUDA 10.2:GCC 8
- CUDA 11.4:GCC 11
- CUDA 12.6:GCC 13
CUDA用のバイナリの作成
コンパイルプロセス
nvccコマンドでコンパイルします。実行時に以下のオプションを指定します。
-
arch:PTXのターゲット- PTX:NVIDIAのGPU向け仮想アセンブリ言語(Parallel Thread eXecution)
-
code:SASSのターゲット- SASS:GPUアーキテクチャに最適化されたバイナリコード(Streaming Assembler)
CUDAコードのコンパイルは以下の流れで行われます。
CUDAコード → PTX(中間表現) → SASS(バイナリコード)
PTXは仮想アセンブリ言語とのことで、このアセンブリを直接書くことも想定されているようです。
バイナリ互換性の問題
アーキテクチャ固有の最適化
バイナリはアーキテクチャごとに最適化されており、互換性はありません。
具体例
CUDA 10.0でCompute Capability 7.2向けにビルドしたバイナリの場合
- CUDA 10.0のJetson AGX Xavier:動作する
- CUDA 11.4のJetson Orin NX:動作しない
API互換性の問題
CUDAのAPIはバージョンごとに変更が加えられるため、さらに複雑な問題が発生します。
具体例
CUDA 10.0でCompute Capability 7.2向けにビルドしたバイナリは、Compute Capability 7.2のJetson AGX XavierでもCUDA 10.2環境ではinsufficient driverエラーが発生して動作しません。
PTXの前方互換性
中間表現の利点
中間表現であるPTXには前方互換性があります。
- 基本的に新しい世代の環境では、古い世代をターゲットとしてビルドされたPTXを実行可能
- JIT(Just-In-Time)コンパイルが発生するため、パフォーマンスに影響が出る可能性はある
具体例
CUDA 10.0でCompute Capability 7.2向けにコンパイルしたPTXは以下すべてで動作します。
- CUDA 10.0のJetson AGX Xavier
- CUDA 10.2のJetson AGX Xavier
- CUDA 11.4のJetson Orin NX
制約事項
世代固有の機能を使う場合は他の世代では動作しません。
開発環境構築における課題例と解決策
主な課題
OSバージョンの制約
古いUbuntuでROSをコンパイルする選択肢もありますが、パッケージ入れ替えのたびに長時間のビルドが必要になる点でメンテナンスコストが大きくなりがちです。
dusty-nv/jetson-containersではそのような選択がされることもあります。
GCCのバージョン制約
例えばCUDA 10.0を使う場合は、GCC 7までしかサポートしていません。
ROS 2 Jazzyで使う場合はUbuntu 24.04でGCC 7を使うことになります。
新しいlibstdc++に依存するROS 2 Jazzyのライブラリをリンクすると、ABI(Application Binary Interface)の非互換性で下記のようなリンクエラーが発生します。
/usr/bin/ld: /opt/ros/jazzy/lib/librclcpp.so: undefined reference to `std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30'
/usr/bin/ld: /opt/ros/jazzy/lib/librcl_logging_spdlog.so: undefined reference to `std::filesystem::__cxx11::path::_M_split_cmpts()@GLIBCXX_3.4.26'
collect2: error: ld returned 1 exit status
L4T Baseイメージの制約
Ubuntu 24.04を使ったL4T Baseイメージは存在しません。また、Ubuntu 22.04を使ったL4T BaseイメージはJetPack 6相当のもののみとなり、古いハードウェアではCUDAツールキットのバージョンが合いません。
解決策
共有ライブラリとして分離
ROSに依存しない、CUDA APIを利用する処理のみを独立させた共有ライブラリを作成します。
その共有ライブラリは実行環境の差異を吸収させるため、CUDAランタイムに対して動的リンクを使用します。
この共有ライブラリはROSに依存しないため、ROS 1/ROS 2の両方で使用できます。
カスタムL4T Baseイメージ
Ubuntu 22.04/24.04に対してL4T Baseイメージと同様にEGL関連の設定をします。
@atinfinityさんの l4t-ros2-docker や l4t-base-docker が参考になります。
まとめ
調査結果
JetsonでのROS1/ROS2環境構築では、以下の技術的な制約と解決策を理解しておくと役立ちます。
これらの理解により、古い世代のJetsonでもROS 2を効率的に運用できるようになります。特に、CUDA処理を独立したライブラリとして分離するアプローチは、他の組み込みシステムでも応用できそうです。
主要な制約
-
CUDAツールキットとドライバの依存関係
- アプリケーションは実行環境のCUDAドライバに依存する
- 新しいCUDAランタイムを静的リンクしても古いドライバでは動作しない
-
JetPackの制約
- ハードウェアとOSバージョンが紐付けられている
- Ubuntu 24.04ベースのL4T Baseイメージが存在しない
-
Compute Capabilityによる互換性問題
- バイナリはアーキテクチャ固有で互換性がない
- PTXは前方互換性があるが、世代固有機能は使用不可
-
GCCバージョンの制約
- CUDAツールキットごとにサポートするGCCバージョンが限定的
- ROS 2 Jazzyと古いCUDAの組み合わせでABI非互換が発生
実践的な解決策
-
共有ライブラリの分離
- CUDA処理をROSに依存しない共有ライブラリとして分離
- 動的リンクにより実行環境の差異を吸収
-
カスタムL4T Baseイメージの活用
- Ubuntu 24.04にEGL関連設定を追加
- 既存のプロジェクトを参考に環境構築
参考資料
Discussion