2016-09-11 6 views
2

私はGNU makeを学んでいるだけですが、.d(依存関係)ファイルを使用するとリンクに問題があります。誰もがこのエラーで正しい方向に私を指すことができます。Makefile - .o:ファイルが認識されません:ファイルは切り捨てられますか?

...../part1.o: file not recognized: File truncated recipe for target 'bin/target/prog' failed

それが含む単純なプログラムです:main.cppに、part1.cpp、part1.h、part2.cpp、part2.h

ここで、part1とpart2には何かを印刷する方法があります。

makeを実行すると、この端末からである:私は一度の#pragmaを使用するための警告を取得していますなぜ私は得ることはありません

を?

[email protected]:~/Desktop/ISU/L1/2$ make ARCH=target -f Makefile.th 
Compiling...part2.cpp 
arm-devkit-g++ -MTbuild/target/part2.o -MM -I. part2.cpp > build/target/part2.d 
Compiling...part1.cpp 
arm-devkit-g++ -MTbuild/target/part1.o -MM -I. part1.cpp > build/target/part1.d 
Compiling...main.cpp 
arm-devkit-g++ -MTbuild/target/main.o -MM -I. main.cpp > build/target/main.d 
object file....main.o 
arm-devkit-g++ -I. -c main.cpp part1.h part2.h > build/target/main.o 
part1.h:1:9: warning: #pragma once in main file 
#pragma once 
     ^
part2.h:1:9: warning: #pragma once in main file 
#pragma once 
     ^
object file....part1.o 
arm-devkit-g++ -I. -c part1.cpp > build/target/part1.o 
object file....part2.o 
arm-devkit-g++ -I. -c part2.cpp > build/target/part2.o 
arm-devkit-g++ -I. -o build/target/main.o build/target/part1.o build/target/part2.o -o prog 
build/target/part1.o: file not recognized: File truncated 
collect2: error: ld returned 1 exit status 
Makefile.th:27: recipe for target 'bin/target/prog' failed 
make: *** [bin/target/prog] Error 1 

私のMakefileは以下の発見された:

# Variables 
SOURCES=main.cpp part1.cpp part2.cpp 
OBJECTS=$(SOURCES:.cpp=.o) 
DEPS=$(SOURCES:.cpp=.d) 
EXE=prog 
CXXFLAGS =-I. 


# Making for host 
# > make ARCH=host 
ifeq (${ARCH},host) 
CXX=g++ 
BUILD_DIR=build/host 
EXE_DIR=bin/host 
endif 

# Making for target 
# > make ARCH= target 
ifeq (${ARCH},target) 
CXX=arm-devkit-g++ 
BUILD_DIR=build/target 
EXE_DIR=bin/target 
endif 

$(addprefix ${EXE_DIR}/,$(EXE)): $(addprefix ${BUILD_DIR}/,$(DEPS)) $(addprefix ${BUILD_DIR}/,$(OBJECTS)) 
# << Check the $(DEPS) new dependency 
    @mkdir -p $(dir [email protected]) 
    $(CXX) $(CXXFLAGS) -o $(addprefix ${BUILD_DIR}/,$(OBJECTS)) 

$(addprefix $(BUILD_DIR)/, %.o): %.cpp 
    @echo "object file...."$*.o 
    $(CXX) $(CXXFLAGS) -c $^ > [email protected] 


# Rule that describes how a .d (dependency) file is created from a .cpp 
# Similar to the assigment %. cpp -> %.o 
${BUILD_DIR}/%.d: %.cpp 
    @mkdir -p $(dir [email protected]) 
    @echo "Compiling..."$< 
    $(CXX) -MT$(@:.d=.o) -MM $(CXXFLAGS) $^ > [email protected] 

debug: 
    @echo "DEPS: "$(DEPS)"\n" 
    @echo "OBJ: " $(addprefix ${BUILD_DIR}/,$(OBJECTS))"\n" 
    @echo "EXE: " $(addprefix ${EXE_DIR}/,$(EXE))"\n" 


.PHONY:clean 
clean: 
    rm -f $(EXE) $(addprefix ${BUILD_DIR}/,$(DEPS)) $(addprefix ${BUILD_DIR}/,$(OBJECTS)) 

ifneq ($(MAKECMDGOALS),clean) 
-include $(addprefix ${BUILD_DIR}/,$(DEPS)) 
endif 

答えて

2

する必要がありますので、また、あなたは、ヘッダファイルをリストしてはいけませんオブジェクトファイルを正しくコンパイルしていません。 g++はstdoutにファイルを出力せず、直接ローカルに書き込みます。

$(BUILD_DIR)/%.o: %.cpp | $(BUILD_DIR) 
    $(CXX) $(CXXFLAGS) -c $^ -o [email protected] 
          ^^^^^^ 

$(BUILD_DIR): 
    @mkdir -p [email protected] 

はまた、あなたが誤ってあなたの実行可能ファイルを構築している:あなたは、特定のディレクトリ内のオブジェクトファイルを入れたい場合は、-oオプションを使用する必要があります。依存関係が不十分で、ターゲットがリストされていません。

$(EXE_DIR)/$(EXE) : $(addprefix $(BUILD_DIR),$(OBJECTS)) | $(EXE_DIR) 
    $(CXX) $(CXXFLAGS) -o [email protected] $^ 

$(EXE_DIR): 
    @mkdir -p [email protected] 

これにより、ディレクトリ上のバイナリから注文のみの依存関係が作成され、バイナリが正しくビルドされます。 .dファイルでターゲットからの依存関係を持つべきではないことに注意してください。それはほとんど意味がありません。その代わり、.o Sを構築するためのあなたのルールは単純にも.d S(そのルールは、現在お使いの.o原則として同じ問題を被る)を構築する必要があります脇EDITORIAL AS

# build the .o and the .d in one go 
$(BUILD_DIR)/%.o : %.cpp | $(BUILD_DIR) 
    $(CXX) $(CXXFLAGS) -o [email protected] -c $< -MP -MMD -MF $(@:.o=.d) 

を、この共通の傾向がありますSHOUTY_CAPS内のMAKEFILES内のすべての変数を書き込む。これは、snake_caseを使用して読むよりはるかに難しくなります。小文字はうまく動作します。

+0

ありがとうございました。私はメイクファイルを更新しましたが、エラーmain.oが発生しました:ファイルが認識されません:ファイルフォーマットが認識されません。 ターゲット 'bin/host/prog'のレシピにあります。 – Mat0

+0

@ Mat0人々があなたに与える答えで質問を編集しないでください。私はあなたの編集を元に戻しました。 – Barry

4

次の2つの無関係な問題を抱えています。最初の1つは、リンク時に2つの矛盾した-oオプションがあることです。

あなたが尋ねる実際の問題は、別のものですが、依然として-oオプションに関連しています。つまり、オブジェクトファイルを作成しようとしているときに、あなたが持っていないということです。

オブジェクト・ファイルを作成する場合、生成されたオブジェクトファイルは、したがって、あなたのリダイレクトは、あなたが考える名前のオブジェクトファイルを作成するgccフロントエンドプログラムを引き起こすことはありません、標準出力に書き込まれないです。例えば

arm-devkit-g++ -I. -c part1.cpp > build/target/part1.o 

上記のコマンドは、現在ディレクトリ内part1.oという名前のオブジェクトファイルを作成し、ファイルbuild/target/part1.oに(空の)標準出力を書き込みます。それは、build/target/part1.oを空にしてしまいます。これは、リンカが不平を言っていることです(ファイルが切り捨てられているということです)。

コマンドではなく

arm-devkit-g++ -I. -c part1.cpp -o build/target/part1.o 

のようになりますが、出力ファイルに名前を付け-oオプションの使用に注意してください。

オブジェクトファイルをビルドするときに、リダイレクトを使用しないようにmakefileを変更する必要があります。


オブジェクトファイル、あなたが構築したいだけのソースファイルを構築するときに、コマンド

arm-devkit-g++ -I. -c main.cpp part1.h part2.h > build/target/main.o 

が本当に

arm-devkit-g++ -I. -c main.cpp -o build/target/main.o 
関連する問題