9

私は学校でC++を学び、小さなコマンドラインプログラムを作成しています。

ただし、VS08やQtCreatorなどのIDEを使用してプロジェクトを構築しただけです。

プロジェクトの構築の背後にあるプロセスを理解しています。ソースをオブジェクトコードにコンパイルしてから、プラットフォーム固有の実行可能ファイル(、、など)にリンクし.exeます.appmakeまた、ほとんどのプロジェクトが、複数のソースファイルとヘッダーファイルのコンパイルとリンクのプロセスを合理化するためにも使用していることも知っています。

重要なのは、IDEはこれらすべてを内部で実行するため、作業が非常に簡単になりますが、実際に何が起こっているのかよくわからないため、プロジェクトの「昔ながらの方法」の構築に慣れる必要があると感じています。コマンドから行、ツールチェーンを明示的に使用します。

私はMakefilesが何であるかを知っていますが、それらを書く方法は知りません。
私は何をするのかは知ってgccいますが、使い方はわかりません。
リンカが何をするかは知っていますが、使い方はわかりません。

私が探しているのは、最初にコードを記述してから生成された実行可能ファイルを実行するまでの、C++プロジェクトのワークフローを説明する説明またはチュートリアルへのリンクです。

C ++を構築する理由、方法、理由を本当に知りたいです。

(違いがある場合は、Mac OSXをgcc4.0.1で実行して3.81にします)

ありがとう!

4

8 に答える 8

15

コンパイル

単純な「helloworld」アプリケーションを作成するとします。3つのファイルがhello.cpp hello-writer.cppありhello-writer.h、その内容は

// hello-writer.h
void WriteHello(void);

// hello-writer.cpp
#include "hello-writer.h"
#include <stdio>
void WriteHello(void){
    std::cout<<"Hello World"<<std::endl;
}

// hello.cpp
#include "hello-writer.h"
int main(int argc, char ** argv){
    WriteHello();
}

g++* .cppファイルは、コマンドを使用して、によってオブジェクトファイルに変換されます。

g++ -c hello.cpp -o hello.o
g++ -c hello-writer.cpp -o hello-writer.o

フラグは今の-cところリンクをスキップします。すべてのモジュールをリンクするには、を実行する必要があります

g++ hello.o hello-writer.o -o hello

プログラムの作成hello。外部ライブラリにリンクする必要がある場合は、たとえば-lm数学ライブラリの場合など、これらをこの行に追加します。libm.a実際のライブラリファイルはまたはのようlibm.soになります。リンカーフラグを追加するときに、ファイル名のサフィックスと「lib」部分を無視します。

Makefile

ビルドプロセスを自動化するには、一連のルールで構成されるmakefileを使用し、作成するものとそれを作成するために必要なファイルをリストします。たとえば、にhello.o依存しhello.cpphello-writer.hそのルールは

hello.o:hello.cpp hello-writer.h
     g++ -c hello.cpp -o hello.o # This line must begin with a tab.

makeマニュアルを読みたい場合は、変数と自動ルールを使用して物事を単純化する方法を説明しています。あなたはただ書くことができるはずです

hello.o:hello.cpp hello-writer.h

ルールは自動的に作成されます。helloの例の完全なmakefileは次のとおりです。

all:hello
hello:hello.o hello-writer.o
    g++ hello.o hello-writer.o -o hello
hello.o:hello.cpp hello-writer.h
    g++ -c hello.cpp -o hello.o
hello-writer.o:hello-writer.cpp hello-writer.h
    g++ -c hello-writer.cpp -o hello-writer.o

インデントされた行はタブで始まる必要があることに注意してください。すべてのルールに実際のファイルが必要なわけではありません。allターゲットは「作成」とだけ言っていますhello。これがmakefileの最初のルールであり、実行時に最初のルールが自動的に作成されるのが一般的ですmake

このすべての設定により、コマンドラインに移動して実行できるようになります。

$ make
$ ./hello
Hello World

より高度なMakefileのもの

makefileで定義できる便利な変数もいくつかあります。

  • CXX:c++コンパイラ
  • CXXFLAGS:コンパイラに渡す追加のフラグ(例:-Iを含むディレクトリを含める)
  • LDFLAGS:リンカーに渡す追加のフラグ
  • LDLIBS:リンクするライブラリ
  • CC:cコンパイラ(リンクにも使用)
  • CPPFLAGS:プリプロセッサフ​​ラグ

を使用して変数を定義し、を使用=して変数に追加します+=

.cppファイルを.oファイルに変換するデフォルトのルールは次のとおりです。

$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< -o $@

ここ$<で、は最初の依存関係で$@あり、は出力ファイルです。変数はで囲むことによって展開されます$()。このルールはパターンで実行されますhello.o:hello.cpp

同様に、デフォルトのリンカールールは

$(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)

ここ$^で、すべての前提条件があります。このルールは、パターンで実行されますhello:hello.o hello-writer.o。このルールをオーバーライドせずにc++を使用している場合は、cコンパイラを使用することに注意して-lstdc++くださいLDLIBS

LDLIBS+=-lstdc++

makefileで。

最後に、ファイルの依存関係をリストしない場合、.omakeはそれ自体を見つけることができるため、最小限のmakefileは次のようになります。

LDFLAGS=-lstdc++
all:hello
hello:hello.o hello-writer.o

これは、上の2つのファイルの依存関係を無視するhello-writer.hため、ヘッダーが変更された場合、プログラムは再構築されないことに注意してください。興味がある場合は、-MDこの依存関係を自動的に生成する方法について、gccドキュメントのフラグを確認してください。

最終的なmakefile

妥当な最終メイクファイルは次のようになります

// Makefile
CC=gcc
CXX=g++
CXXFLAGS+=-Wall -Wextra -Werror
CXXFLAGS+=-Ipath/to/headers
LDLIBS+=-lstdc++ # You could instead use CC = $(CXX) for the same effect 
                 # (watch out for c code though!)

all:hello                                   # default target
hello:hello.o hello-world.o                 # linker
hello.o:hello.cpp hello-world.h             # compile a module
hello-world.o:hello-world.cpp hello-world.h # compile another module
    $(CXX) $(CXXFLAGS) -c $< -o $@          # command to run (same as the default rule)
                                            # expands to g++ -Wall ... -c hello-world.cpp -o hello-world.o
于 2010-01-18T04:09:26.023 に答える
10

簡単な例は、基本的な手順を示すのに役立つことが多いので、次のようになります。

C++ファイルをコンパイルするためのgccの使用例:

$ g++ -c file1.cpp                 # compile object files
[...]
$ g++ -c file2.cpp
[...]
$ g++ -o program file1.o file2.o   # link program
[...]
$ ./program                        # run program

このビルドを行うために使用makeするには、次のMakefileを使用できます。

# main target, with dependencies, followed by build command (indented with <tab>)
program: file1.o file2.o
    g++ -o program file1.o file2.o

# rules for object files, with dependencies and build commands
file1.o: file1.cpp file1.h
    g++ -c file1.cpp

file2.o: file2.cpp file2.h file1.h
    g++ -c file2.cpp

Makefileの使用例:

$ make                              # build it
[...]
$ ./program                         # run it

詳細については、GnumakeのマニュアルGCCのドキュメントを参照してください。

于 2010-01-18T03:56:58.457 に答える
4

Makefileとは何かは知っていますが、書き方はわかりません。

make構文はひどいですが、GNUmakeドキュメントは悪くありません。主な構文は次のとおりです。

<target> : <dependency> <dependency> <dep...>
<tab>    <command>
<tab>    <command>

これは、指定された依存関係からターゲットを構築するためのコマンドを定義します。

ドキュメントや例を読むことは、おそらくほとんどの人がmakefileを学ぶ方法です。これは、makeには独自のわずかな違いがある多くのフレーバーがあるためです。いくつかのプロジェクトをダウンロードし(システムで動作することがわかっているものを選択して、実際に試してみることができます)、ビルドシステムを調べて、それらがどのように動作するかを確認します。

また、単純なmakeを作成してみてください(最初のバージョンのより難しい機能の束を取り除きます)。これは、状況をよりよく把握できる1つのケースだと思います。

gccの機能は知っていますが、使い方はわかりません。

繰り返しにman g++なりますが、情報ページやその他のドキュメントは便利ですが、(ビルドシステムを介してではなく)直接呼び出す場合の主な用途は次のとおりです。

g++ file.cpp -o name            # to compile and link
g++ file.cpp other.cpp -o name  # to compile multiple files and link as "name"

独自のシェルスクリプト(以下は私の〜/ bin / c ++を簡略化したもの)を記述して$ CXXFLAGSを組み込むこともできるので、忘れないでください。

#!/bin/sh
g++ $CXXFLAGS "$@"

他のオプションも含めることができます。これで、その環境変数($ CXXFLAGS、C ++フラグの標準変数)を.bashrcなどに設定したり、特定のセッションで再定義したりして、makefileなしで作業できます(makeも問題なく動作します)。

また、-vフラグを使用して、g++の機能の詳細を確認してください。

リンカが何をするかは知っていますが、使い方はわかりません。

リンカは、ご存じのとおり、オブジェクトファイルを取得してリンクするものですが、g++ -v使用する正確なコマンドを表示します。比較してgcc -v file.cpp(gccはC ++ファイルで動作できます)、たとえばg++ -v file.cpp、最初のコマンドが失敗することが多いリンカーコマンドの違いを確認します。Makeは、デフォルトで実行されるコマンドも表示します。

リンカーを直接使用しない方がよいでしょう。gccまたはg++のいずれかを使用し、必要に応じて特定のリンカーオプションを指定する方がはるかに簡単だからです。

于 2010-01-18T04:02:52.480 に答える
2

これを捨てるために、完全なgccドキュメントはここにあります:http ://www.delorie.com/gnu/docs/gcc/gcc_toc.html

于 2010-01-18T04:09:06.900 に答える
0

これは私がautoconf、automake、...を学ぶのを助けたものです:

http://www.bioinf.uni-freiburg.de/~mmann/HowTo/automake.html

これは、単純なhelloworldから、ライブラリなどを備えたより高度な構造へと進む素晴らしいチュートリアルです。

于 2010-03-21T23:01:24.217 に答える
0

コンパイラはcppを受け取り、ネイティブコードとそのネイティブコードに関する情報を含むオブジェクトファイルに変換します

リンカはオブジェクトファイルを取得し、オブジェクトファイル内の追加情報を使用して実行可能ファイルをレイアウトします。同じものへのすべての参照を見つけてリンクし、オペレーティングシステムがその方法を知るのに役立つイメージを作成します。すべてのコードをメモリにロードします。

オブジェクトファイル形式をチェックして、コンパイラが生成するものをよりよく理解してください。

http://en.wikipedia.org/wiki/Object_file (異なるコンパイラは異なる形式を使用します)

また、チェックアウト(gccの場合)

コマンドラインで入力した内容については、http://pages.cs.wisc.edu/~beechung/ref/gcc-intro.htmlを参照してください。

于 2010-01-18T03:44:38.580 に答える
0

また、automakeファイルとautoconfファイルを設定するAutoprojectを調べることもできます。これにより、さまざまなプラットフォームでパッケージを簡単にコンパイルできます。http: //packages.debian.org/unstable/devel/autoproject

于 2010-01-18T05:00:06.670 に答える
0

Linuxベースのgccを使用してhelloworldプログラムを構築するためのこの風変わりなイントロが好きですが、コマンドラインのものはOS/Xで正常に動作するはずです。特に、よくある間違いを犯したり、エラーメッセージを表示したりする手順を説明します。

ホーリーコンパイラー、ロビン、くそったれがうまくいった!

于 2010-01-18T05:15:05.567 に答える