テストコード(tsnnls_test_DKU.c
)の場所を変更したいのですが、このフォルダーの変更を正しく反映するためにmakefileを変更できません。いくつかの助けをいただければ幸いです。
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つの場所にあります(つの検索パス):
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
そして私のmakefileはうまく機能します。
ただし、テストコードの場所を次のように変更したいと思います。
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を適切に使用することができませんでした。
PDATE:私の質問に答えてくれたMikeKinghanに感謝します。
Q1:別のサブディレクトリからオブジェクトファイルをリンクする方法は?
プログラムprog
が、サブディレクトリobj
にコンパイルされるオブジェクト_file0.o
_、_file1.o
_からリンクされるCプログラムであるとします。これは、そのリンケージを実行するためにメイクファイルで通常必要な種類のものです。
_$(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
のドキュメント
NBコンパイルするときにobj
サブディレクトリが存在しない場合、これはcreateには不十分です。その中にオブジェクトファイル。自分で作成するか、make
に実行させる方法を学習する必要があります。
Q2:さまざまな検索パスを含める方法は?
これはあいまいな質問です-あいまいさはあなたを混乱させます-そして私たちはそれをQ2.a、Q2.b、Q2.cに分解しなければなりません:
Q2.a:プリプロセッサがソースコードで_#include
_-されたヘッダーファイルを検索するさまざまな検索パスを指定するにはどうすればよいですか?
デフォルトでは、プリプロセッサは組み込みの標準検索パスのリストを使用してヘッダーファイルを検索します。プリプロセッサを冗長モードで実行すると、それらを確認できます。例:_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.
_
サブディレクトリinc
および_inc/foo/bar
_に独自のヘッダーファイルがいくつかあり、プリプロセッサがこれらのディレクトリも検索するようにしたいとします。次に、プリプロセッサオプションを渡す必要があります。
_-I inc -I inc/foo/bar
_
コンパイルコマンドに。プリプロセッサオプションは、通常、make変数CPPFLAGS
に割り当てられます。
_CPPFLAGS = -I inc -I inc/foo/bar
_
(必要な他のプリプロセッサオプションとともに)、コンパイルコマンドレシピでこの変数を介して渡されます。
_gcc -c -o $@ $(CPPFLAGS) $(CFLAGS) $<
_
N.B。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:リンカーがライブラリを検索するさまざまな検索パスを指定するにはどうすればよいですか?
prog
とリンクする必要のあるライブラリ_libfoobar.a
_があり、それがメイクファイルから2レベル上のディレクトリlib
にあるとします。次に、リンカーオプションを渡す必要があります。
_-L ../../lib
_
そして
_-lfoobar
_
リンクコマンドに。これらの最初のものは、_../../lib
_がライブラリを探す場所の1つであることをリンカに通知します。従来、このオプションはLDFLAGS
を介してリンカーコマンドレシピで渡します。 2つ目は、_libfoobar.a
_(静的ライブラリ)または_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つをリンクする必要がある場合。 libm
(数学ライブラリ)。デフォルトのライブラリ検索パスの1つにあり、_-L
_オプションを渡す必要はありません。 _-lm
_だけで十分です。
Q2.c:make
がターゲットの前提条件を検索するさまざまな検索パスを指定する方法は?
N.B。これは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
を使用します。 ':'で区切られたディレクトリ名のリストをVPATH
に割り当てると、make
は、リストされている各ディレクトリで前提条件が見つからない場合は常に検索します。カレントディレクトリ。そう:
_VPATH = foo:bar
_
make
が現在のディレクトリを検索し、そのパターンルールに一致する_.c
_ファイルを検索しようとするとfoo
とbar
が検索されます。ルールを満たすことに成功し、必要なソースファイルをコンパイルします。
N.B。投稿されたコードでVPATH
を誤って使用しました:
_VPATH = -L/home/dkumar/libtsnnls-2.3.3/tsnnls
_
リンカオプション_-L
_を使用して、linker検索パスを割り当てました。
結論:
ヘッダーファイルを検索するための先行検索パスは、プリプロセッサの_-I<dirname>
_オプションで指定されます。これらのオプションをCPPFLAGS
のコンパイルレシピに渡します
ライブラリを検索するためのリンカ検索パスは、リンカの_-L<dirname>
_オプションで指定されます。これらのオプションをLDFLAGS
のリンケージレシピに渡します
make
ルールの前提条件の検索パスは、make
変数VPATH
で、 ':-ディレクトリ名の句読点リストとして指定されます。
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 $@ $^