特定のビルドシステムに依存したくない理由があります。私は誰かが好きなものを無視したいのではなく、コンパイラに付属しているものに固執したいと思います。この場合はGCCです。 Automakeには特にWindowsとの互換性の問題があります。 <3 GNU makeには大きな制限があり、しばしばシェルスクリプトで補完する必要があります。シェルスクリプトはさまざまな形を取ることができ、簡単に言えば多くの人々を怒らせる可能性が高いので、私がやろうとしているのは次のとおりです。
主なエントリーポイントは神です。 CであれC ++ソースファイルであれ、アプリケーションの中心です。私はメインエントリポイントを最初に実行したいだけでなく、最初にコンパイルしたいと思います。説明します -
排他的および非公開のソースライブラリが一般的だった時がありました。 AppleがUnixに移行し、Microsoftが自分自身を攻撃することで、その時代は終わりました。動的接続を必要とするすべてのライブラリは、アプリケーションのサポートファイルとして含めることができます。したがって、.SO(または.DLL ;])の別々のビルド手順は別々の実行可能ファイルなので、すべて大丈夫です。他のライブラリは静的にリンクする必要があります。それでは、静的リンクについて話しましょう。
静的接続は本当に犬です。これがmakefileの目的です。プロジェクト全体が1つの言語(CまたはC ++など)で書かれている場合は、ライブラリをヘッダーとして#includeできます。いいですね。しかし、もう別の状況を考えてみましょう。
あなたが私と同じで、なぜCで文字列を使用するのが難しいのかわからないので、C ++を使用することにしたとしましょう。しかし、MiniBasicのようなCライブラリを使いたいです。神石で助けてください。 CライブラリのデザインがC ++の構文に従わない場合、問題が発生します。 CソースファイルをコンパイルするにはCコンパイラを使用し、C ++ソースファイルをコンパイルするにはC ++コンパイラを使用する必要があるため、makefileが便利です。 makefileを使用したくありません。
GCCのプリプロセッサマクロを活用して、次のように言える方法があったらと思います。
こんにちはGCCです。大丈夫ですか?忘れてしまった場合に備えて、今見ているソースファイルはC++で作成されました。もちろんG++でコンパイルする必要があります。このファイルにも別のファイルが必要ですが、Cで書かれています。 「lolcats.c」と呼ばれます。 GCCを使用してオブジェクトファイルにコンパイルし、G ++を使用してデフォルトのオブジェクトファイルにコンパイルし、それらを一緒にリンクして実行可能ファイルを形成したいと思います。
プリプロセッサ用語でこのような内容を作成するにはどうすればよいですか? GCCもこのようなことをしますか?
答え1
主なエントリーポイントは神です。 CであれC ++ソースファイルであれ、アプリケーションの中心です。
ただ同じ方法で窒素は松の中核です。ここがすべてがあるところだスタートただし、CやC ++にはアプリケーションの「中心」を配置する機能はありませんmain()
。
多くのCおよびC ++プログラムが構築されました。イベントループまたは入出力ポンプ。これらはそのようなプログラムの「ハブ」です。このループを同じにする必要さえありません。基準寸法のようにmain()
。
私はメインエントリポイントを最初に実行したいだけでなく、最初にコンパイルしたいと思います。
実際に捨てることが最も簡単です。main()
最後C または C++ ソース ファイルから。
C および C++ は、一部の言語とは異なり、宣言の前に記号を使用できます。最初はmain()
あなたがしなければならないことを意味します事前宣言他のすべて。
排他的および非公開のソースライブラリが一般的だった時がありました。 Apple が Unix に移行し、Microsoft が自分自身を攻撃したとき、その時代は終わりました。
OS XとiOSの例いっぱい独自のコードであるマイクロソフトはすぐに消えないでしょう。
とにかく、現在のマイクロソフトの問題は、あなたの質問とどのような関係がありますか?あなたはDLLを作成したいと思うかもしれないと言い、AutomakeはWindowsを効率的に処理できないと述べました。これは、マイクロソフトがあなたの世界でまだ関連性があることを示しています。
静的接続は本当に犬です。
本当に?私はいつもそれを見つけました。簡単に動的ライブラリにリンクする代わりに。これはエラーの可能性が少ない古くて簡単な技術です。
静的リンクは、外部依存関係を実行可能ファイルに統合し、実行可能ファイルが独立して自己完結型になるようにします。あなたの質問の残りの部分と判断した場合、これはあなたにアピールされます。
ヘッダーでライブラリを#includeできます。
いいえ...あなた#include
クトウ、図書館ではなく。
これは単に賢いものではありません。用語問題。言われる。
#include
図書館が利用できれば#include </usr/lib/libfoo.a>
大丈夫です。
多くのプログラミング言語でははい外部モジュール/ライブラリ参照がどのように機能するか。つまり、外部コードを直接参照します。
C と C++ は、このように動作する言語に属しません。
CライブラリのデザインがC ++の構文に従わない場合、問題が発生します。
いいえ、C++の使い方を学ぶだけです。具体的には、extern "C"
。
プリプロセッサ用語でこのような内容を作成するにはどうすればよいですか?
#include
他のCまたはC ++ファイルを使用することは完全に正当です。
#include <some/library/main.cpp>
#include <some/other/library/main.c>
#include <some/other/library/secondary_module.c>
#include <iostream>
int main()
{
call_the_library();
do_other_stuff();
return 0;
}
ここではこれを使用しません。extern "C"
他のライブラリのCおよびC ++コードを直接C ++ファイルにプルするので、Cモジュールも正当なC ++でなければなりません。たくさんありますCとC ++の厄介な小さな違いしかし、両方の言語を混在させるには、それを処理する方法を知る必要があります。
この操作のもう一つのトリッキーな部分は、#includes
リンカコマンドの場合、コマンドの順序がライブラリ参照の順序よりも敏感であることです。この方法でリンカーをバイパスすると、リンカーが自動的に実行するいくつかの操作を手動で実行する必要があります。
これを証明するために私は取った。ミニ基本バージョン(自分の例)script.c
ドライバを#include <basic.c>
代わりに表すスタンドアロンC ++プログラムに変換します#include <basic.h>
(。修理する)これが実際にC ++プログラムであることを証明するために、すべてのprintf()
呼び出しをストリーム挿入に変更しましたcout
。
CとC ++を混在させたい人のために、日常的な作業内でいくつかの変更を加える必要がありました。
void*
MiniBasicコードは、他のポインタタイプの自動変換を許可したいCの意志を利用します。 C++ では明示的に表現できます。最新のコンパイラは、
"Hello, world!\n"
コンテキストでC文字列定数(たとえば)の使用を許可しなくなりましたchar*
。標準によると、コンパイラはそれを読み取り専用メモリに入れることができるのでconst char*
。
それはすべてです。 GCCの苦情を解決するのに数分しかかかりません。
basic.c
私はリンクされたパッチファイルの内容に同様の変更を加えなければなりませんでしたscript.c
。私はそれらがより似ているので、違いを投稿しませんでした。
この問題を解決する他の方法については、SQLiteのマージ、比較SQLiteソースツリー。 SQLiteは#include
他のすべてのファイルを1つのデフォルトファイルとして使用しません。シリーズへ一緒に使用されますが、これは#include
CまたはC ++のすべての操作でもあります。
答え2
gccはC、C、およびC ++をC ++にコンパイルします。ファイル名が正しく指定されたため、プリプロセッサは関連していません。ただし、extern "C"
リンカーがエントリを正しくリンクできるように、C ++ファイルのC宣言の周囲にブロックを配置する必要があります。
しかし、あなたが説明する内容はほとんど役に立ちません。使用しているライブラリが最初にコンパイルするためにいくつかの構成が必要な場合は、ファイルをプロジェクトに直接コンパイルしようとすると、まだ構成が必要です。現実の世界には純粋なISO Cであり、変更や一種の構成スクリプトなしですべてのプラットフォームでコンパイルされる重要なライブラリはほとんどありません。したがって、ほとんどの場合、複雑さを減らすのではなく、複雑さを作成する必要があります。どういうわけか自分のビルドでその設定を処理します。
答え3
いいえ、そうすることはできません。 gccプラグマなし次のようにコンパイル。最も似ているのは、Microsoft Visual C ++#pragma comment(lib, …)
または#pragma comment(linker, …)
[1][2]一部のライブラリはリンクプロセスに含める必要があります。
こんにちはGCCです。大丈夫ですか?忘れてしまった場合に備えて、今見ているソースファイルはC++で作成されました。もちろんG++でコンパイルする必要があります。このファイルにも別のファイルが必要ですが、Cで書かれています。 「lolcats.c」と呼ばれます。 GCCを使用してオブジェクトファイルにコンパイルし、G ++を使用してデフォルトのオブジェクトファイルにコンパイルし、それらを一緒にリンクして実行可能ファイルを形成したいと思います。
あなたの要求は、Makefileが行うこととまったく同じです。
シェルスクリプトを生成してソースファイルを抽出し、使用したいコマンドを使用してコンパイルできます。しかし、それは間違った解決策です™
複数のファイルがある場合は、複数のファイルとして保存してください。人々がmakeやcmakeを使用したくない場合は、Makefile
/を提供しないでくださいCMakefile
。たとえば、ファイルを提供しますcompile-me.sh
。
同様の状況にあると感じる唯一のケースは、単一のファイルにutilを書いたが、コメントの上部にコンパイルコマンドを提供した場合です。
答え4
すべてのコンテンツがプラグインになることを決定できます。それからそれをコンパイルし、デフォルトのgcc -shared -fPIC -O thing1.cc -o thing1.so
スタブプログラムを実行させます。ドロペン(3)それがすべてです。./thing1.so
Linuxでは可能です。dlsym
God
binfmt_miscより透明にするためのヒント。
別のプログラムをしたい場合は、GCC-f独立型オプション。その後、ランタイム環境を提供することはユーザーによって異なります(少なくとも一部のデフォルトI / Oの場合)。システムコールどのインターフェイスを接続する必要がありますか?参考システムコール(2))。関連内容を慎重に勉強してくださいABILinux/x86-64の仕様は次のとおりです。ここ。読む呼び出しルール。
コンパイラプラグインを使用してGCCをカスタマイズすることもできます。溶ける(その後、ランダムな操作を行うことを追加できます。多分#pragma
1つをフォークすることもできますgcc
...)
ところで、エントリポイントGod
あなたのファイルはソースファイルではありませんが、リンカに知られているいくつかのタグと同じです。
詳しくはこちら翻訳者、コネクタ(望むよりレビンの本:リンカーとローダー、宛先ファイル、非常に低い周波数、図書館および共有オブジェクト(参照ドレイパスペーパー: 共有ライブラリの作成方法...),crt0.o役に立ちます。
また見てくださいC++ モジュール提案草案 N3347