質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

ビルド

ソースコードを単体で実行可能なソフトウェアへ変換する過程をビルド(build)と呼びます

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

4113閲覧

別環境でのC++のビルド結果を一致させる方法

gougorou

総合スコア6

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

Ubuntu

Ubuntuは、Debian GNU/Linuxを基盤としたフリーのオペレーティングシステムです。

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

ビルド

ソースコードを単体で実行可能なソフトウェアへ変換する過程をビルド(build)と呼びます

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

3クリップ

投稿2020/03/06 05:48

前提・実現したいこと

小型ロボットに低スペックなPC+Ubuntuを載せて動かしているのですが、
実機でのビルドは時間がかかるため、
よりハイスペックな環境でクロスコンパイルしたいと考えています。

動作は完全一致させたいので、別々の環境でビルドしたC++の実行ファイルを、
バイナリレベルで一致させたいです。

発生している問題

質問①
同一のC++のソースコードからバイナリを生成するとき、
生成される実行ファイルのバイナリは何の影響を受けるのでしょうか?
e.x. コンパイラのバージョン、CPUの種類(Intelであれば全部一緒?)、ライブラリのバージョン など

質問②
ある環境(低スペックのPC)でコンパイルした結果と同一のバイナリを
別の環境(ハイスペックのPC)で生成しようと思った時、
どのようにしてバイナリを一致させるのが良いのでしょうか?
CmakeListなどから依存するライブラリ一覧などを抜き出せないでしょうか。

環境

Ubuntu 16.04
ROS Kinetic (Robot Operating System)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yumetodo

2020/03/06 06:13

そもそもバイナリレベルで一致させたいという理由がよくわからないです。同一の動作をしないとすればそれは未定義動作を踏んでいるのでは・・・?
gougorou

2020/03/06 06:55

ソフトウェアの品質管理において、同一の動作を保証するためですね。 経験的に同じソースでビルドすれば同じ動作するのかはわかっていますが、特定の環境でのビルド結果ではバグが入り込む、などが発生すると困るからです。
cateye

2020/03/06 11:55

>特定の環境でのビルド結果ではバグが入り込む、などが発生すると困る ・・・・・というのは、問題が発生する可能性があるコーディングをしているからなのでは?
gougorou

2020/03/06 12:40 編集

前提として、ある程度以上の規模のソフトウェアでバグがゼロというのはありえない(またはありえないコストがかかる)ので。 もちろんコンパイラやライブラリが多少変わっても動作にほとんど影響ないことはわかりますが、複数のビルド環境での生成物全てで問題が発生しないことをテストする、というのは厳しいです。 それこそ回答でもいただきましたが、組み込みなどではビルド環境固定して生成物に差異が生まれないようにするのが一般的かと思います。 同じことをLinux用のバイナリのビルドでも実施したく。
guest

回答4

0

既に回答の通り、クロス環境と実機環境でバイナリ一致させるというのは現実的に不可能です。
私のところでは、必ずどちらかに統一します。
実機環境を使うのは、短納期の仕事でクロス環境を用意している余裕がなく、品質もそれほど要求されないときくらいです。
バイナリ一致を気にするほどの品質管理が要求される場合、実機環境は使いません。コンパイルが遅いだけでなく、環境を復元させるのも困難だからです。

私のところでは、だいたい次のどちらか、もしくは両方の方法を取ります

  1. ビルド環境専用のマシンを用意し、リリース物は常にこのマシンを使う
  2. 仮想環境なりコンテナなりのディスクイメージを作成し、どのマシンでも同じ動作をすることを保証する。(仮想化によって多少遅くなるのは許容する)

投稿2020/03/06 09:32

編集2020/03/06 09:36
yuki23

総合スコア1448

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gougorou

2020/03/06 11:30

回答ありがとうございます。 なるほど、常にクロスコンパイルにすることでバイナリを統一するんですね。 > 仮想環境なりコンテナなりのディスクイメージを作成し、どのマシンでも同じ動作をすることを保証する。 この場合、仮想化していてもCPUの型番やLinuxカーネルのバージョンは変わってしまう(dockerの場合)と思うのですが、この辺はバイナリへの影響は無いのでしょうか?
yuki23

2020/03/06 13:37

開発用マシンのカーネルバージョンをしょっちゅう変えるということも普通はしませんが、仮想化してしまえば、影響があるかどうかは実際にやってみればすぐにわかることです。仮に影響がなかったとしても、リスクヘッジのためにリリース用の環境は別にするのがよりよいです。突き詰めれば、品質のためにどこまでコストを掛けてよいかのバランスです。理論上影響はないかもしれませんが、実務では「理論上ないはず」という傲慢によって痛い目を見るリスクと比べて結論を出すものです。
guest

0

ベストアンサー

こんにちは。

質問①

同一のC++のソースコードからバイナリを生成するとき、
生成される実行ファイルのバイナリは何の影響を受けるのでしょうか?
e.x. コンパイラのバージョン、CPUの種類(Intelであれば全部一緒?)、ライブラリのバージョン など

「同じバイナリ」=「全く同じ機能のバイナリ」とした場合は、以下の通りです。

  1. コンパイラとCPUの影響は当然受けます。ただし、CPUが異なっても入力が同じなら出力も同じというコンパイラが存在すれば影響を回避できます。(本質的にはそのようなコンパイラが存在する可能性はあります。例えば、コンパイラの同じバイナリが走るなら、期待できるでしょう。)
  2. リンクする全てのライブラリもバイナリ・レベルで同じである必要があります。

ターゲット・マシンのアプリがクロス開発環境では走らないならリンクするライブラリを管理しやすいです。クロス環境でも走るようなケースでは、クロス環境に何かアプリをインストールする際に、ターゲットのアプリにリンクしているライブラリが更新されることもあるので、なかなかハードです。
3. 当たり前ですが、ソース(インクルードするライブラリのヘッダも含めて)が、同じバイナリを出力するものであることも必要です。(コメントがちょっと変わっているくらいの変更は問題ないはずですし、変数名や関数名も外部リンケージのないものなら異なっていても大丈夫な筈です。)
4. コンパイラやリンカへ与えるオプションや環境変数も同じバイナリを出力できるものである必要があります。ターゲット環境とクロス環境の両方で同じバイナリを出力させる設定は結構難易度高いと思います。

他には影響する要素はないと思います。(見落としていたらごめんなさい。)
でも、これらを全て満たすのは現実問題無理な気がします。手間が凄いことになりそうです。

質問②

ある環境(低スペックのPC)でコンパイルした結果と同一のバイナリを
別の環境(ハイスペックのPC)で生成しようと思った時、
どのようにしてバイナリを一致させるのが良いのでしょうか?
CmakeListなどから依存するライブラリ一覧などを抜き出せないでしょうか。

Ubuntuで走るアプリには恐らくビルド時刻が埋め込まれていると思いますので、現実問題不可能と思います。ビルド時刻やデバッグ情報等のリリース・モードでの実行のためには必要でない情報を全て剥ぎ取るようなツールがあれば理論上は可能ですが、OS上で走るアプリに対してそのようなことが可能なツールを見たことはないです。(OS無しで走らせる場合ならROM化することが多いですが、ROMイメージを出力するツールは不要な情報を全て剥ぎ取ることができる筈です。)

投稿2020/03/06 19:20

編集2020/03/06 19:24
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

e.x. コンパイラのバージョン、CPUの種類(Intelであれば全部一緒?)、ライブラリのバージョン など

既に回答があるように、全て影響受けます。

ある環境(低スペックのPC)でコンパイルした結果と同一のバイナリを

当然、環境が変われば、変わります。同一環境でおこなうしかないです。

もっとも、同一環境と言っても、OSのバージョンアップとかでも影響を受けるのが頭痛いところ。昔、あった事では、フリーのメモリサイズでバイナリが違った事も。(大昔。 MS-DOS環境。ただし、動作は同じ)

最近のコンパイル環境について、詳しくないですが、ビルド情報なんて入りませんか? ROM化には、必要ない情報はそぎ落としていたのですが、ビルド情報なんて入ると、同一環境でもバイナリ一致しないと思います。

この辺は、他の方も掛かれているように割り切りしかないです。

動作は完全一致させたいので、.... バイナリレベルで一致させたいです。

このためには、同じバイナリで、動作を検証すべきです。その都度、ビルドはあり得ません。また、ビルドする環境も固定にする(PCも含め)。再ビルドしたら、別モノとして、評価するしかないです。(実際にそうするところは多いです)

投稿2020/03/06 12:35

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

生成される実行ファイルのバイナリは何の影響を受けるのでしょうか?
e.x. コンパイラのバージョン、CPUの種類(Intelであれば全部一緒?)、ライブラリのバージョン など

全部影響をうけます。
完全にハード、OS、環境を同一にできれば、理論上できなくはないが、ハードが異なる時点でバイナリレベルで完全に一致させるのは、現実的には無理だと思いますし、一般的なやり方ではないと思います。

以前、ROS を使った組み込みデバイス (Nvidia Jetson) 上で動かすソフトを作ったことがありますが、

  • 開発は普通のデスクトップ PC (Ubuntu) で行なう。ソースコードは git で管理。
  • デプロイ時は動かすデバイス上でビルドする。

としました。
ROS は CMake でライブラリ等を管理するようになっているので、基本的には ROS が入っていれば、他の環境に持っていってもハードに依存しない部分では問題は起こらないかと思います。

投稿2020/03/06 06:24

編集2020/03/06 06:26
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

gougorou

2020/03/06 07:02

> 現実的には無理 なるほど・・・。難しいんですね・・・。 一般的には、ライブラリマネージャがあって、ソースコードが同一であれば動作は同じ、と判断されるんですかね? 医療機器など絶対に誤動作が許されない製品でもC++とPC使われていると思うのですが、ああいう世界でのビルド環境の管理どうされるんだろう。
tiitoi

2020/03/06 07:19

> 絶対に誤動作が許されない製品 デバイスの差異により、開発 PC と同じように動作すると100%言えないため、網羅的かつ綿密なテストをきちんと実機で行なうことで品質を保証することになると思います。
tmp

2020/03/06 09:03 編集

私の知っている組み込みの開発環境2つとも、ライブラリだけでなくビルド環境(コンパイラ、アセンブラ、リンカー、ライブラリ等)全部、管理されますよ バグでコンパイラーの修正があったとしても、以前のコンパイラーは残ったままで、コンパイルも変更しないかぎり以前のコンパイラーを使用します。普通は開発中はほとんど変更しない。 一式同じにしないとビルドしたPCによってバイナリが変わってしまって困ります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問