11

テスト コード ( ) の場所を変更したいのですが、tsnnls_test_DKU.cこのフォルダーの変更を正しく反映するためにメイクファイルを変更することができません。いくつかの助けをいただければ幸いです。

2 つの質問があります 。1) 異なるサブディレクトリからオブジェクト ファイルをリンクする方法 2) 異なる検索パス (私の例では 3 つの検索パス) を含めます。

makefile が正常に動作する元のセットアップでは、テスト コードtsnnls_test_DKU.cを次の場所 (サード パーティ ライブラリ内) に配置しました。

Dir1 = /home/dkumar/libtsnnls-2.3.3/tsnnls

私がリンクしているすべてのオブジェクトファイルは、

OBJDir = /home/dkumar/libtsnnls-2.3.3/tsnnls

また、 に含まれる一部のインクルード ファイルtsnnls_test_DKU.cは、次の 3 つの場所 ( 3 つの検索パス) にあります。

Dir1 = /home/dkumar/libtsnnls-2.3.3/tsnnls  
Dir2 = /home/dkumar/libtsnnls-2.3.3
Dir3 = /home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic

私のメイクファイルは正常に動作します。

ただし、テスト コードの場所を次のように変更したいと思います。

Dir4 = /home/dkumar/CPP_ExampleCodes_DKU/Using_tsnnls_DKU/

これが私のmakefileの外観です(他のユーザーからの入力後に更新されました:

# A sample Makefile

VPATH = -L/home/dkumar/libtsnnls-2.3.3/tsnnls
INC_PATH  = -I/home/dkumar/libtsnnls-2.3.3/ -I/home/dkumar/libtsnnls-2.3.3/tsnnls/  -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/

# Here is a simple Make Macro.
LINK_TARGET     = tsnnls_test_DKU
OBJS_LOC    = tsnnls_test_DKU.o

# Here is a Make Macro that uses the backslash to extend to multiple lines.
OBJS =  libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \
    libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \
    libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \
    libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \
    libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \
    libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \
    libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \
    libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o   \
    $(OBJS_LOC)

REBUILDABLES = $(LINK_TARGET) 

all : $(LINK_TARGET)
    echo All done

clean : 
    rm -f $(REBUILDABLES)   
    echo Clean done

#Inclusion of all libraries
RANLIB = ranlib
STATICLIB= /usr/local/lib/taucs_full/lib/linux/libtaucs.a 

tsnnls_test_LDADD = $(LDADD)
LIBS = -largtable2 -llapack -lblas -lquadmath -lm

$(LINK_TARGET) : $(OBJS)   $(tsnnls_test_LDADD) $(LIBS)  $(STATICLIB)
gcc -g ${INC_PATH} -o $@ $^

「$make」を実行しようとすると発生するエラー

make: *** No rule to make target `libtsnnls_la-taucs_malloc.o', needed by `tsnnls_test_DKU'.  Stop.

明らかに、VPATH を適切に使用できていません。

更新: 私の質問に答えてくれた Mike Kinghan に感謝します。

4

2 に答える 2

33

Q1: 別のサブディレクトリからオブジェクト ファイルをリンクする方法を教えてください。

プログラムが objectからリンクされ、サブディレクトリにコンパイルされるprogC プログラムであるとしましょう。これは、そのリンケージを実行するためにメイクファイルで通常必要となるものです。file0.ofile1.oobj

$(OBJS) = $(patsubst %.o,obj/%.o,file0.o file1.o)

prog: $(OBJS)
    gcc -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)

これにより$(OBJS)=obj/file0.o, obj/file1.oが作成され、そのようなオブジェクト ファイルを link コマンドに渡すだけです。ドキュメンテーションpatsubst

:オブジェクト ファイルをサブディレクトリにコンパイルするときにサブディレクトリが存在しない場合、これではサブディレクトリを作成するのに十分ではありません。obj自分で作成するか、作成方法を研究する必要makeがあります。

Q2: 異なる検索パスを含めるにはどうすればよいですか?

これはあいまいな質問です - あいまいさがあなたを混乱させています - そして、Q2.a、Q2.b、Q2.c に分解する必要があります:

Q2.a:#includeソース コードで -ed されているヘッダー ファイルをプリプロセッサが検索する別の検索パスを指定する方法を教えてください。

デフォルトでは、プリプロセッサは組み込みの標準検索パスのリストを使用してヘッダー ファイルを検索します。プリプロセッサを冗長モードで実行すると、それらを確認できますcpp -v(例: CTRL-C で終了)。出力には次のようなものが含まれます。

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

サブディレクトリに独自のヘッダー ファイルがいくつか あり、プリプロセッサにこれらのディレクトリも検索させたいとしますincinc/foo/bar次に、プリプロセッサ オプションを渡す必要があります。

-I inc -I inc/foo/bar

コンパイルコマンドに。プリプロセッサ オプションは、慣例的に make 変数CPPFLAGSに割り当てられます。

CPPFLAGS = -I inc -I inc/foo/bar

(必要なその他のプリプロセッサ オプションと共に)、コンパイル コマンド レシピでこの変数を介して渡されます。

gcc -c -o $@ $(CPPFLAGS) $(CFLAGS) $<

CPPFLAGS: を C++ コンパイラ フラグの従来の make 変数と考えるのはよくある間違いです。C++ コンパイラ フラグの従来の make 変数はCXXFLAGS.

-I次のコマンドを実行すると、オプションの効果を確認できます。

mkdir -p inc/foo/bar # Just to create the path
cpp -v -I inc -I inc/foo/bar

(CTRL-C で終了)。出力には次のようなものが含まれます。

#include "..." search starts here:
#include <...> search starts here:
 inc
 inc/foo/bar
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.

Q2.b: リンカーがライブラリを検索する別の検索パスを指定する方法は?

libfoobar.aリンクする必要のあるライブラリがあり、それが makefile から 2 レベル上progのディレクトリにあるとします。lib次に、リンカー オプションを渡す必要があります。

-L ../../lib

-lfoobar

あなたのリンクコマンドに。../../libこれらの最初のものは、ライブラリを探す場所の 1 つであるリンカーに通知します。通常、このオプションは を介し​​てリンカ コマンド レシピで渡しますLDFLAGSlibfoobar.a2 つ目は、 (静的ライブラリ) または(動的ライブラリ)と呼ばれるライブラリを検索するようにリンカーに指示しますlibfoobar.so 。通常、このオプションをリンカー コマンド レシピで渡します。LDLIBS

プリプロセッサの検索パスのデフォルト リストがあるように、リンカの検索パスのデフォルト リストがあります。次のコマンドを実行すると、それらを確認できます。

gcc -v -Wl,--verbose 2>&1 | grep 'LIBRARY_PATH'

出力は次のようになります。

LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/: / usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/: /usr /lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/: /usr/lib/

デフォルトのライブラリ検索パスの 1 つに存在する標準ライブラリの 1 つ (数学ライブラリなど) をリンクする必要がある場合、オプションlibmを渡す必要はありません。一人で行います。-L-lm

Q2.c:makeターゲットの前提条件を検索する別の検索パスを指定する方法は?

: これは に関する質問makeであり、プリプロセッサ、コンパイラ、またはリンカーに関する質問ではありません。

すべてのオブジェクト ファイルがサブディレクトリにコンパイルされると想定していますobj。それらをそこでコンパイルするには、パターンルールを使用するだけで簡単にできます。

obj/%.o:%.c
    gcc -c -o $@ $(CPPFLAGS) $(CFLAGS) $<

これはmake、たとえば、レシピによってobj/file0.o作られていることを示しています。file0.c

gcc -c -o obj/file0.o $(CPPFLAGS) $(CFLAGS) file0.c

同様に、任意のファイルobj/*.oと一致するファイルについても*.c

file0.cこれは、makefile と同じディレクトリにある限り問題ありませんが、*.cファイルが別の場所にあるとしますか? ソース ファイルがサブディレクトリに整理されているfoo/file0.cとしbar/file1.cます。次にmake、そのパターン ルールを満たすことができず、「ターゲット obj/file0.o を作成するルールはありません」などと表示されます。

この問題を解決するには、特別な意味を持つ変数 をVPATH使用します。make':' で区切られたディレクトリ名のリストを に割り当てるとVPATHmake現在のディレクトリで見つからない場合は常に、リストされた各ディレクトリで前提条件が検索されます。そう:

VPATH = foo:bar

make現在のディレクトリを検索し、そのパターン ルールに一致するファイルを検索しようとしますfoo。ルールを満たすことに成功し、必要なソース ファイルをコンパイルします。bar.c

注意VPATH:投稿されたコードで間違って使用しました:

VPATH = -L/home/dkumar/libtsnnls-2.3.3/tsnnls

リンカーオプションを使用して、リンカー検索パスをそれに割り当てましたが-L、そこには何の関係もありません。

結論:

  • ヘッダー ファイルを検索するための先行検索パスは、プリプロセッサの-I<dirname>オプションで指定されます。これらのオプションをコンパイル レシピに渡します。CPPFLAGS

  • ライブラリを見つけるためのリンカ検索パスは、リンカの-L<dirname>オプションで指定されます。これらのオプションをリンク レシピに渡します。LDFLAGS

  • ルールの前提条件の検索パスは、ディレクトリ名の ':-句読点リストとして変数にmake指定されます。makeVPATH

于 2015-01-27T14:35:40.987 に答える
0

My answer to part of question リンクする方法を見つけることができましたobject files from different subdirectory/ subdirectories。しかし、まだcould not figure out how to use different search path:

私の現在のメイクファイルは次のとおりです。

    # A sample Makefile

OBJS_PATH = /home/dkumar/libtsnnls-2.3.3/tsnnls/
C_INCLUDE_PATH  = -I/home/dkumar/libtsnnls-2.3.3/ -I/home/dkumar/libtsnnls-2.3.3/tsnnls/  -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/
CPATH  = -I/home/dkumar/libtsnnls-2.3.3/ -I/home/dkumar/libtsnnls-2.3.3/tsnnls/  -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/

# Here is a simple Make Macro.
LINK_TARGET     = tsnnls_test_DKU
OBJS_LOC    = tsnnls_test_DKU.o

# Here is a Make Macro that uses the backslash to extend to multiple lines.
OBJS =  libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \
    libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \
    libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \
    libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \
    libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \
    libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \
    libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \
    libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o   

 ## adding "$(OBJS_PATH)" to each word in "$(OBJS)"
# which in our case is basically to add the same folder in front of all "*.o" object files.
OBJS2 = $(addprefix $(OBJS_PATH)/, $(OBJS)) 


# OBJS_LOC is in current working directory,
OBJS_ALL = $(OBJS2) \
    $(OBJS_LOC)

## DKU IS COPING THIS FROM ORIGINAL MAKEFILE THAT ARE GENERATED USING /home/dkumar/libtsnnls-2.3.3/tsnnls/MAKEFILE.AM
RANLIB = ranlib
STATICLIB= /usr/local/lib/taucs_full/lib/linux/libtaucs.a 

tsnnls_test_LDADD = $(LDADD)
LIBS = -largtable2 -llapack -lblas -lquadmath -lm


REBUILDABLES = $(OBJS_LOC) $(LINK_TARGET) 


all : $(LINK_TARGET)
    echo All done

clean : 
    rm -f $(REBUILDABLES)   
    echo Clean done

# Here is a Rule that uses some built-in Make Macros in its command:
$(LINK_TARGET) : $(OBJS_ALL)   $(tsnnls_test_LDADD) $(LIBS)  $(STATICLIB)
    gcc -g -o $@ $^
于 2015-01-26T16:49:16.937 に答える