Makefileの作成にはたくさんありますが、次のファイルがあります。
https://raw.githubusercontent.com/systems-cs-pub-ro/uso/master/tema1/boo.c
https://github.com/systems-cs-pub-ro/uso/raw/master/tema1/light.o
https://raw.githubusercontent.com/systems-cs-pub-ro/uso/master/tema1/sound.c
https://raw.githubusercontent.com/systems-cs-pub-ro/uso/master/tema1/sound.h
Makefileを作成する必要があります。 「実行ファイルを生成exec
し、light.o
以前の実装のsound.o
コンパイル時に生成しますsound.c
。コマンドを受け取るか、make
ファイルmake build
を生成する必要があります。必要に応じて、プログラム全体に準拠したexec
Makefileにルールを追加し、作成したオブジェクトファイルを削除するルールを追加しますrun
。実行します。また、コンパイル後に中間ファイル(、)を生成するルールを追加します。clean
templates
boo.s
boo.o
boo.c
これは私のメイクファイルです。
build: light.o sound.o
gcc light.o sound.o -o exec
sound.o: sound.c
gcc -c sound.c
templates: boo.c
gcc -c boo.c
gcc -S boo.c
run: exec
./exec
clean:
rm -f sound.o boo.o boo.s exec
ただし、「正しい」実行可能ファイルを作成していないというメッセージが表示されます。私が何を間違っているのでしょうか?私はboo.o
execファイルに追加する必要があると思いますが、そうしようとすると次のような結果が表示されますboo.c multiple definition of main light.o:light.c:first defined here
。
答え1
(宿題のように聞こえますね。)
まずエラーメッセージ:
boo.c multiple definition of main
light.o:light.c:first defined here.
これは、リンクするファイルに名前が付けられた関数のコピーが複数あることを意味します。main()
これは明らかに間違っています。
を再利用しようとしていlight.o
ますが、それ以外の機能がある場合にのみ実際に機能しますmain()
。ただそう呼んでくださいlight()
。また、コンパイラがソースコードを表示せずに関数の属性(デフォルトではパラメータ型と戻り値型)を知ることができるように.h
ファイル#include
dが必要です。boo.c
light()
私が見ると、あなたのファイルが課題で予想したものとは少し異なるように構成されているようです。教授が一連の相互接続された課題を作成した可能性があります。シリーズの以前の課題からショートカットを選択すると、以前の課題のコードを再利用する後続の課題は正しく機能しません。
教授は、再利用できるようにコードを配置する方法と、そうでなければどうなるかを教えようとします。
Makefile ルールの基本形式は次のとおりです。
<name of target>: <names of files the creation process depends on>
<command(s) to create the target file>
ファイルの作成は、.c
ファイル自体だけでなく、.h
ファイルに含まれるファイルによっても異なります。通常、システムにはファイルが含まれていると想定できます(含まれるファイルは#include <filename>
変更されないため、Makefileルールに追加する必要はありません)。ただし、.h
プロジェクトの一部であるすべてのファイルも含める必要があります。 。
実際にはファイルではなく「仮想ターゲット」があるかもしれません。同様のことができますmake clean
。仮想ターゲットを他のターゲットの依存関係として使用することもできます。仮想ターゲットには接続された物理ファイルがないため、仮想ターゲットが何かへの依存関係としてリストされるたびに、仮想ターゲットを「生成」するコマンドが実行されます。他のものを構築する必要があります。
また、コマンドは含まれていませんが、1つ以上のMakefileターゲットを依存関係としてリストするMakefileルールがある可能性があります。依存関係が1つしかない場合、コマンドを持たないターゲットは、依存関係としてリストされているターゲットの別の名前として機能します。依存関係が複数ある場合、コマンドレスターゲットは、単一のコマンドを使用して複数のMakefileターゲットを構築する方法になります。
build:
教授は自分の指示なしに対象を作りたいと思っているようです。これは2つの目標にのみ依存する必要があります。
- 実際の実行可能ファイルをビルドする別のターゲット
templates
目標
light.o
ソースコードを見ずにこれが何であるかをどうやって知ることができるのか疑問に思います。簡単 - 私はあなたのものをダウンロードし、light.o
次のコマンドを使用しました。
$ readelf -s light.o
Symbol table '.symtab' contains 12 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS light.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 SECTION LOCAL DEFAULT 5
6: 00000000 0 SECTION LOCAL DEFAULT 7
7: 00000000 0 SECTION LOCAL DEFAULT 8
8: 00000000 0 SECTION LOCAL DEFAULT 6
9: 00000000 51 FUNC GLOBAL DEFAULT 1 main
10: 00000000 0 NOTYPE GLOBAL DEFAULT UND puts
11: 00000000 0 NOTYPE GLOBAL DEFAULT UND sound
light.o
これは、という名前のソースファイルで、light.c
という関数が定義され、ここで定義されていないという関数をmain()
使用していることを示します。標準ライブラリで提供されていますが、完全な実行可能ファイルを形成するには、このファイルに関連付けられている他のファイルで定義する必要があります。puts()
sound()
puts()
sound()