Linuxの「自分でコンパイルする」という考え方の源は何ですか[終了]


11

私は大学でLinuxを少し使用しましたが、用語に精通しています。私は.NET言語で定期的に開発しているので、私はコンピュータの読み書きができません。

とはいえ、* nixサークルに存在する「自分でコンパイルする」[CIY]考え方を理解しているとは本当に言えません。私はそれがなくなることを知っていますが、それでも時々それを聞きます。開発者として、コンパイラーと必要な依存関係のセットアップはお尻の痛みであることを知っているので、CIYワークフローが* nixのアクセス性を大幅に低下させるのに役立ったように感じます。

CIYメンタリティの上昇につながった社会的または技術的要因は何ですか?


12
LinuxサークルやUNIXサークルで聞いていますか?大きな違いがあります。
terdon

2
Linuxには非常に多くの異なるディストリビューションがあり、それは本当に驚きではありません。現在、いくつかのディストリビューションはフロントランナーとして先に進んでいますが、コンパイルされたバージョンがありますが、以前は実用的ではないようなWebでした。
Centimane 2017年

8
そして記録として、Linuxシステムでの「コンパイラーと必要な依存関係のセットアップ」は実際にはそれほど難しくありません。簡単だと言う人もいます。
デスグリップ2017年

6
@ダーレン-それは逆です、今日ほとんどのオープンソースtarballは何年も前には存在しなかった標準に従います。tarballをダウンロードし、tarballを抽出し、ディレクトリにcdし、を実行して./configure <options>から、makeとmake installを実行します。30年前、AT&T SysV Unixを実行しているAT&T 3B2サーバーとUTXを実行しているグールドアイアンで歯を切りました。当時、物事ははるかに困難でした。一部はconfigureプロセスの始まりであり、ほとんどはmakefile(s)特定のシステム用に手動で編集する必要がありました。
デスグリップ2017年

1
@Deathgrip確かに、Visual Studioを使用せずにシステムプログラミング用のWindows開発環境をセットアップしようとしたことがありますか?不可能に近づきます。

回答:


27

非常に簡単に言うと、* nixの歴史のほとんどについて、他に選択肢はありませんでした。プログラムはソースtarballとして配布され、ソースを使用してコンパイルする方法しかありませんでした。ですから、それは必要な悪ほど精神的なものではありません。

とは言っても、ハードウェアに合わせてコンパイルされるため、自分でコンパイルすることには非常に十分な理由があります。有効にするオプションを有効または無効にできます。そのため、好みに合わせて実行ファイルを微調整できます。 。ただし、これは明らかに、専門家のユーザーにとっては意味のあることであり、作業中のマシンでメールを読むだけの人にとっては意味のないことです。

現在、Linuxの世界では、主要なディストリビューションはすべて、何年も前にこれから遠ざかっています。Gentooのようにこれを行うのが好きな人のために特別に設計されたディストリビューションを使用している場合を除き、ごくまれに、最近自分で何かをコンパイルする必要はありません。ただし、大多数のディストリビューションでは、平均的なユーザーは何もコンパイルする必要はありません。ディストリビューションのリポジトリに必要なもののほとんどすべてが存在し、コンパイルされているためです。

したがって、このCIYの考え方は、あなたが言うように本質的に消えています。それはまだ生きていてUNIXの世界でキックしているかもしれませんが、私はそこでの経験はありませんが、Linuxでは、まともなリポジトリを備えた人気のあるディストリビューションを使用している場合は、自分でコンパイルする必要はほとんどありません。


5
Unixの世界でも、OSによって異なります。私の最後の役職には多数のSolaris(Sun Sparcプラットフォーム)サーバーが関係し、自宅でSolaris 10 x86をデスクトップとして数年間実行していました。HPUXやAIXについて話すことはできませんが、Solarisで少しCIYを行う必要がありました。Sunは、Solaris用にあらかじめパッケージ化された多数のOpenSourceユーティリティを配布しました。opencsw.orgやunixpackages.comなどのサイトもありました。しかし、私はまだソースtarballからかなりの量のコンパイルを行いました。
デスグリップ2017年

「* nixの歴史のほとんどで、他に選択肢はありませんでした。プログラムはソースtarballとして配布されました。」-それのため CIYの考え方の、右?
Woodrow Barlow

2
@woodrowはそうではありません。他に利用できる選択肢はありませんでした。* nixは古いことを忘れないでください。また、ほとんどのプログラムは、すでに専門家であった同僚の間で受け渡されました。なぜ、あなたのコードを使用する他の8人のために、インストーラーやパッケージマネージャーのような複雑なものを発明するのですか?そのようなツールが発明されたとき、* nixの人々は他の皆と同じようにそれらを使用し始めました。
terdon

@WoodrowBarlowいいえ、原因と結果を交換しています。多くの異なるプラットフォーム(異なるハードウェアアーキテクチャ、異なるオペレーティングシステム、異なるライブラリセット)があったため、プログラムはソースとして配布されたため、プログラム作成者はそれらすべてをカバーするために数百または数千のバイナリを配布する必要がありました。CIYは「エキゾチックな」プラットフォームを実行している人々のためにまだ存在していますが、大多数はバイナリがディストリビューションから簡単に入手できる「主流」のプラットフォームを実行しています。
Gilles「SO-邪悪なことをやめよ」

@terdon大丈夫、なるほど。指摘したいのですが、その段落は少しトートロジーです。あるレベルで、OPは「* nix開発者はコンパイルされたバイナリの代わりにソースコードを配布するのはなぜですか?」と尋ねました。そしてあなたの最初の段落は「* nix開発者はコンパイルされたバイナリの代わりにソースコードを配布するから」と言っています。はい、わかりやすくしていますが、コメントの引数を回答テキストに追加すると、回答がより明確になると思います。
Woodrow Barlow 2017年

13

その考え方には、エンドユーザー、配布メンテナー、コードサプライヤー/開発者/プロジェクトグループなどからいくつかの原因があり、それらはすべて完全に有効です。

オープンソースの側面

フリーソフトウェアを使用していることを知り、ソースからコンパイルすることを選択してそれを検証する人もいます。ここから、Linux From Scratchプロジェクト/ howto / guide / bookなどが登場します。

最適化とオプションの側面

特定のCPUアーキテクチャ向けに特定の最適化を行ってコンパイルしたいですか?おそらく、必要な特定の機能を有効または無効にするコンパイル時オプション(またはパッチを作成するためのパッチ)があるでしょう。この例としては、postfixにパッチを適用して割り当て量を管理したり、Gentooのようなディストリビューションを使用してsystemdを使用しないように選択したり、ライセンスの問題によりogg / theora / vorbis / whateverやmp3をサポートしないように特別に選択したりすることができます。または何でも。

CPUアーキテクチャの側面

職場では、x86 / amd64以外のハイエンドマシンを使用していますか?必要なパッケージは、CPUアーキテクチャ用にプリコンパイルされていない可能性があり、実行しているディストリビューションがはるかに少ない場合があります。確かに、この種のハードウェアを実行しているほとんどの場所は、IBMなどからのサポートも受けているため、物事をインストールしたりコンパイルしたりすることはありません。しかし、もしあなたが余剰セールからそれを手に入れたら、古いiMac w / PPCプロセッサーなどを掘り出してしまったらどうでしょう?

流通面

ディストリビューションの「ファミリー」、つまりDebian w / Ubuntu、Mintなど、およびRedHatとCentOS、Whitebox、Fedoraなどは、すべて異なるパッケージ形式を使用しています。また、各バージョンには異なるライブラリバージョンなどが同梱されています。単純な単一ファイルシェルスクリプトでも、適切なDebian .debファイルを設定するには時間と労力がかかります。かゆみをかいくぐるためにソフトウェアを作成し、それを無料にしてgitlabに投稿したい場合は、独自のWebサーバーなど、ビルドの手順が記載されたソースの一般的な.tar.gzファイルを投稿するか、むしろDebianの2つのバージョン(安定版とテスト版、旧安定版)、RPMとしてのRedhatとFedoraの複数バージョン、SlackwareのTGZ、Gentooのebuildプロファイルなどのパッケージバージョン


1
もう1つの理由は、アップストリームソースが、以前のリリースでは機能していたがその後壊れた機能の重大ではないバグにパッチを適用することです。ただし、より安定したディストリビューションのパッケージでは、数週間または数か月間パッケージが更新されない場合があります。これは、通常のユーザーがソースからいくつかのものをコンパイルする方法を学びたい理由の1つです。また、Archのようなレポジトリで最先端のソフトウェアを提供しているという評判のディストリビューションでさえ、ある時点で遅れを取ります。ソースからコンパイルするということは、あなたが言及したすべてのものに加えて、導入されたかもしれない新しい機能があることを意味します。

@ChronoKitsune非常に正しい。Gentoo(CIYディストリビューション)のパッケージバージョンを他のディストリビューションと比較します。ずっと新しい。コンパイル命令を作成することは、すべてのアーキテクチャで動作するバイナリパッケージを作成するよりも千倍簡単です。つまり、他の人にはしばらく見られないクールな新しいソフトウェア機能を使用できるようになります。
dogoncouch 2017年

9

@terdonが言うように、最近では特にホームユーザーにとっては、物事をコンパイルする必要性はほとんどありません。

以前は、Unixの世界では、たとえば、ベンダーによってメンテナンスされなくなったSolaris、AIX、Ultrix、Digital UltrixおよびHP / UXシステムを管理していたため、ソースのコンパイルに大きく依存していました。一般的なサービスの数は、Linuxを含む他のUnixで一般的に使用されているものよりもはるかに遅れていました。

リポジトリに存在しないいくつかのより不明瞭な、または時代遅れのソフトウェアを入手するため、または互換性のあるバイナリがないパッケージのより新しいバージョンを使用するため、またはパッチやモジュールを作成できる場合は、追加の機能を追加するか、まれに追加する必要があります。

また、OSでサポートされなくなったフレームワークを持つDebianやDebianの新しいバージョンに移植するためのシステムのリエンジニアリングを行うときは、手作業でソフトウェアをコンパイルする必要がありました。

たとえば、過去には、DHCPデーモンを手動でコンパイルして、プロトコルに対する(最近までの)Windowsの変更をサポートしたり、テレコムの世界でプロビジョニングする特定のパッチをサポートしたりする必要がありました。

Debianに(深刻な)バグがある一連の安定したバージョンがあり、通常、Debian / Ubuntuに対応する.debsがなかったため、私は自分で開発したgit gitリポジトリからFreeRadiusバージョンのローカルリポジトリdebsを保持しています。私たちのニーズに十分です。

そして言うまでもないことですが、自分で書いたものを実行したりコンパイルしたりする必要があることもあります。

今日の依存関係のインストールは以前ほど難しくありません。一部のソフトウェアは、コンパイルする依存関係に名前を付け、組み込みの依存関係のリストを使用してパッケージファイルを作成するという重労働を行ういくつかの一般的なLinuxディストリビューション用にカスタマイズされたルールファイルを備えています。ローカルリポジトリからそのようなパッケージをインストールすることは、公式リポジトリから同じパッケージをインストールすることと大差ありません。


4

CIYメンタリティの上昇つながった社会的または技術的要因何ですか?

根本的な原因は明らかに技術的な理由です。 バイナリの移植性は、ソースの移植性よりも困難です。ディストリビューションパッケージ以外では、ほとんどのフリーソフトウェアは、作成者/メンテナにとって非常に便利であるため、依然としてソース形式でのみ利用できます。

Linuxディストリビューションが平均的な人々が使用したいと思うであろうほとんどのもののパッケージ化を開始するまで、あなたの唯一の選択肢はソースを入手して自分のシステム用にコンパイルすることでした。商用のUnixベンダーは通常、ほとんどすべての人が望むもの(たとえば、GNU bashなどの素敵なシェル)を含まず、独自のshand / or 実装のみを使用しているため、csh(システム管理者として)ユーザーにインタラクティブな使用のための素晴らしいUnix環境を提供するため。

現在、ほとんどの人が唯一の管理者であり、デスクトップに座っているマシンの唯一のユーザーであるという状況は、従来のUnixモデルとは大きく異なります。 システム管理者は、中央システムとすべてのユーザーのデスクトップでソフトウェアを維持していました。(多くの場合、人々のワークステーションにNFSマウント/opt/usr/local/中央サーバーからのマウントを行い、そこにものをインストールします。)


.NETやJavaなどの以前は、異なるCPUアーキテクチャ間での真のバイナリ移植性は不可能でした。Unixカルチャーは、このため、デフォルトでソースの移植性を備えて進化しました。LSBのような最近のLinuxの取り組みまで、バイナリの移植性を有効にしようとする努力さえほとんどありませんでした。例えば、POSIX(主要なUnixの標準)のみであっても最近のバージョンでは、ソース移植を標準化しようと試みます。

関連する文化的要因:初期の商用AT&T Unixには、ソースコード(テープ上)が付属していました。あなたはしていない持っているあなたは何かがどのように見てみたかった場合にはそれだけであった、ソースからシステムを構築するために、本当にドキュメントが十分でなかったときに働きました。

ウィキペディアは言う

「広範なオンラインドキュメントと(長年にわたって)すべてのシステムソースコードにいつでもアクセスできるというUnixポリシーは、プログラマーの期待を高め、1983年のフリーソフトウェア運動の立ち上げに貢献しました。」

顧客が商用ソフトウェアのソースコードにアクセスできるようにすることは最近では前例がないため、この決定の動機が何であるかはわかりません。この方向には明らかに初期の文化的偏見がいくつかありますが、おそらくそれはUnixのルーツから、さまざまなハードウェア用にコンパイルできる(アセンブリ言語ではなく)ほとんどがCで書かれたポータブルOSとして生まれたのでしょう。以前の多くのOSでは、特定のCPU用にasmで記述されたコードが多かったため、ソースレベルの移植性は、初期のUnixの強みの1つでした。(私はこれについて間違っているかもしれません。私は初期のUnixの専門家ではありませんが、UnixとCは関連しています。)


ソフトウェアをソース形式で配布することは、ソフトウェアを実行したいシステムにそれを適応させる最も簡単な方法です。(エンドユーザーまたはLinuxディストリビューション用にパッケージ化した人)。ソフトウェアが配布によってパッケージ化されている場合、エンドユーザーはそれを使用できます。

しかし、ほとんどのパッケージの作成者がすべての可能なシステム自体にバイナリを作成することを期待するのは、あまりにも多すぎます。いくつかの主要なプロジェクトは、いくつかの一般的なケース(特に、OSにビルド環境が付属しておらず、OSベンダーがバイナリのみのインストーラーの配布に重点を置いているx86 / windows)のバイナリを提供します。

作者が使用したシステムとは別のシステムでソフトウェアを実行するには、いくつかの小さな変更が必要になる場合もあり、これはソースを使用すると簡単です。誰かが自分のかゆみを掻くために書いた小さな1回限りのプログラムは、ほとんどのあいまいなシステムではテストされていません。ソースがあれば、そのような変更を行うことができます。元の作成者が何かを見落としたか、多くの時間を節約したため、移植性の低いコードを意図的に作成した可能性があります。Info-ZIPのような主要なパッケージでさえ、すぐにすべてのプラットフォームにテスターがいるわけではなく、問題が発見されたときに、移植パッチを送る必要がありました。

(そこだけのためのビルドENVの違いにより起こる、ソースレベルでの移植性の問題の他の種類があり、ここでの問題には本当に関係ありません。とJavaスタイルのバイナリポータビリティ、自動ツール(autoconf/ auto-make)など同様のことcmakewouldn 一部のシステム<netinet/in.h>では<arpa/inet.h> for 代わりに含める必要ntohl(3)があるようなものはありません(そして、そもそもntohl()やその他のバイト順のものはないでしょう!)


私は.NET言語で定期的に開発しているので、私はコンピュータの読み書きができません。

どこでもコンパイル、どこでも実行は.NETとJavaの主要な目標の1つなので、この問題を解決するために言語全体が発明されたと言っても過言ではありません。開発経験はそのうちの1つです。.NETでは、バイナリはポータブルランタイム環境(CLR)で実行されます。Javaは、そのランタイム環境をJava仮想マシンと呼びます。任意のシステム(少なくとも誰かがすでにJVMまたはCLRを実装しているシステム)で動作する1つのバイナリを配布するだけで済みます。あなたはまだ、のような移植性の問題を持つことができる/\パス区切り、またはどのように印刷するか、GUIはもちろん、細部をレイアウト。

多くのソフトウェアは、完全にネイティブコードにコンパイルされた言語で記述されています。ない、.netまたはJavaバイトコードではなく、実行可能なCPUのネイティブマシンコードのみが、移植性のない実行可能ファイル形式で保存されます。特にUnixの世界では、CとC ++がこの主要な例です。これは明らかに、特定のCPUアーキテクチャ用にバイナリをコンパイルする必要があることを意味します。

ライブラリバージョンも別の問題です。ライブラリは、バイナリレベルのABIを変更している間、ソースレベルのAPIを安定させることができます。(APIとABIの違いを参照してください。)たとえば、不透明に別のメンバーを追加structすると、そのサイズは変更され、動的な(malloc)かどうかにかかわらず、そのような構造体にスペースを割り当てるコードには、新しいライブラリバージョンのヘッダーを使用して再コンパイルする必要があります。 )、静的(グローバル)、または自動(スタック上のローカル)。

オペレーティングシステムも重要です。同じCPUアーキテクチャ用のUnixの異なる味が異なるバイナリファイル形式を持っているかもしれない、などの定数のためのシステムコール、および異なる数値を作るための異なるABI fopen(3)s「はO_RDONLYO_APPENDO_TRUNC

動的にリンクされたバイナリであっても、以前に実行されるOS固有の起動コードがまだあることに注意してくださいmain()。Windowsでは、これはcrt0です。UnixとLinuxには同じものがあり、Cランタイムスタートアップコードがすべてのバイナリに静的にリンクされています。理論的には、そのコードが動的にリンクされたシステム、およびlibcの一部または動的リンカー自体を設計することもできると思いますが、これは私が知っているOSで実際に機能する方法ではありません。これは、システムコールのABI問題のみを解決し、標準ライブラリ関数の定数の数値の問題は解決しません。(通常、システムコールはlibcラッパー関数を介して行われます。使用mmap()するソース用の通常のx86-64 Linuxバイナリには、syscall命令は含まれません。call 同名のlibcラッパー関数への命令。

これは、i386-Linuxでi386-FreeBSDバイナリを実行できない理由の一部です。(しばらくの間、Linuxカーネルにはシステムコール互換性レイヤーがありました。BSDの少なくとも1つは、同様の互換性レイヤーでLinuxバイナリを実行できると思いますが、もちろんLinuxライブラリが必要です。)


バイナリを配布したい場合は、CPU / OS-flavour + version / installed-library-versionsの組み合わせごとに個別のバイナリを作成する必要があります

80年代/ 90年代には、Unixシステム(MIPS、SPARC、POWER、PA-RISC、m68kなど)で一般的に使用されているさまざまな種類のCPUと、さまざまな種類のUnix(IRIX、SunOS、 Solaris、AIX、HP-UX、BSDなど)。
そして、それは単なるUnixシステムです。多くのソースパッケージは、VAX / VMS、MacOS(m68kおよびPPC)、Amiga、PC / MS-DOS、Atari STなどの他のシステムでもコンパイルおよび動作します。

現在でも多くのCPUアーキテクチャとOSがありますが、デスクトップの大多数は3つの主要なOSの1つを実行しているx86です。

そのため、異なるシステムの異なるバージョンにある可能性のあるサードパーティのライブラリへの依存について考え始める前であっても、あなたが棒を振るよりも多くのCPU / OSの組み合わせがすでにあります。(OSベンダーによってパッケージ化されていないものはすべて手動でインストールする必要があります。)

バイナリにコンパイルされるパスもシステム固有です。(これにより、起動時に構成ファイルから読み取るよりもRAMと時間が節約されます)。古い学校のUnixシステムには通常、多くの手作業でカスタマイズされたものがあり、何がどこにあるかについて有効な仮定を立てることはできません。

バイナリを配布することは、すべての主要な組み合わせでビルドおよびテストする余裕のある主要な商用プロジェクトを除いて、昔ながらのUnixでは完全に実行不可能でした

バイナリを作ることさえも、i386-linux-gnuそしてamd64-linux-gnu難しいです。ポータブルバイナリを可能にするために、Linux Standard Baseなどに多くの時間と労力が費やされています。バイナリを静的にリンクしても、すべてが解決されるわけではありません。(たとえば、RedHatシステムとDebianシステムでワードプロセッシングプログラムをどのように印刷する必要がありますか?インストールでデーモンのユーザーまたはグループを追加し、再起動するたびに起動スクリプトを実行するように調整するにはどうすればよいですか?)ソースからの再コンパイルはそれらを解決しないので、例。


それだけでなく、当時の記憶は今よりも貴重でした。 コンパイル時にオプション機能を省略すると、データ構造に使用するメモリが少なくなる小さなバイナリ(コードサイズが小さい)を作成できます。機能が特定のすべてのインスタンスで追加のメンバーを必要とする場合、classまたはstruct何かを追跡するために、その機能を無効にすると、オブジェクトが4バイト縮小されます(たとえば)。

最近のオプションのコンパイル時機能は、追加のライブラリをオプションにするために最もよく使用されます。例えば、あなたがコンパイルできるffmpegの有無にかかわらずlibx264libx265libvorbisより一般的には、物事の多くはの有無にかかわらずコンパイルすることができるなどなど、特定のビデオ/オーディオエンコーダ、字幕処理のための、および他の多くの図書館libreadline:それは利用可能だ場合は、実行すると./configure、結果のバイナリーはライブラリーに依存し、端末から読み取るときに豪華な行編集を提供します。そうでない場合、プログラムはフォールバックサポートを使用して、stdinからの行を読み取りfgets()ます。

一部のプロジェクトでは、オプションの機能を使用して、パフォーマンス上の理由から不要なコードを除外しています。たとえば、Linuxカーネル自体をSMPサポートなしで構築できます(たとえば、組み込みシステムや古代のデスクトップ用)。この場合、多くのロックがより簡単になります。または、ドライバーやその他のハードウェア機能を除外するだけでなく、コアコードの一部に影響を与える他の多くのオプション機能を使用します。(アーキテクチャ固有およびハードウェア固有の構成オプションは、ソースコード全体の多くを占めています。Linuxカーネルが15百万行以上のコードである理由を参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.