make makes many problems
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
NGNG日本語のまともな資料ないし・・・。
だれかもっと便利でわかりやすいビルドツール作ってくれって感じ?
参考リンク
http://tanaka-www.cs.titech.ac.jp/~euske/doc/make_qref.html
http://www.tk.airnet.ne.jp/nagae/jp/comp/make/makefile.html
http://www-or.amp.i.kyoto-u.ac.jp/algo-eng/db/makefile.html
http://kanon.plala.jp/develop/makefile.html
http://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/make-intro/simplest.html
0232デフォルトの名無しさん
NGNG0233デフォルトの名無しさん
NGNG0234デフォルトの名無しさん
NGNGどの話?
0235デフォルトの名無しさん
NGNGDIR_LIST:=たくさんサブディレクトリ
ARC_LIST:=$(addsuffix /lib.a,$(DIR_LIST))
さて、このARC_LISTを、それぞれのディレクトリ内のすべての.oファイルから作るとして、
はじめに思いついたのが、
$(ARC_LIST) : %/lib.c : $(wildcard %/*.o)
というやつだったのですが、このwildcardの中の%がどうやら展開されないようです。
foo/lib.c : $(wildcard foo/*.o)
こうすれば一応依存関係は作れるんですが、DIR_LISTはmakeが起動されるまでわかりません。
なんか解決法はないですか?
0236デフォルトの名無しさん
NGNGARC_RULE:=$(DIR_LIST:%=.%.arc_rule)
.%.arc_rule:
@echo '$*/lib.a: $$(wildcard $*/*.o)' > $@
@echo ' $$(AR) $$(ARFLAGS) $$@ $$?' >> $@
clean::
rm -f $(ARC_RULE)
include $(ARC_RULE)
0237デフォルトの名無しさん
NGNGまちがいがあったので修正版。
ARC_RULE:=$(DIR_LIST:%=.%.arc_rule)
.%.arc_rule:
@echo '$*/lib.a: $$(wildcard $*/*.o)' > $@
@echo ' $$(AR) $$(ARFLAGS) $$@ $$?' >> $@
clean::
rm -f $(ARC_RULE)
ifneq ($(MAKECMDGOALS),clean)
include $(ARC_RULE)
endif
0238235
NGNGあーいっこづつ別のファイルに出せばいいんですね。
そういうやつを一個のファイルに出してみて、「いける?」とか思って、
「あーでもこのファイル更新するタイミングがわからん」とか思ってあきらめてました。
いけそうですね。まだ試せないけど。ありがとーデス。
0239236
NGNG期待通りの動作になるかもしれませんが、wildcardで
全部アーカイブにするのは作り方としてよくないとおもいます。
(ソースコードを生成するためのプログラムのオブジェクトまで
拾ってしまう可能性がある。)
lib.aにするところまでサブディレクトリのMakefileで記述したほうが
いいとおもいます。
0240デフォルトの名無しさん
NGNG> (ソースコードを生成するためのプログラムのオブジェクトまで
> 拾ってしまう可能性がある。)
それはまた別のディレクトリにすべきなんじゃないの?
> lib.aにするところまでサブディレクトリのMakefileで記述したほうが
> いいとおもいます。
ともあれこれには同意。
0241235
NGNGそうした場合には、ディレクトリの数だけ無条件でmakeを起動してしまうわけですよね。
実は、なんとかそれを避けれないかということで、いろいろやって>>235のようになったのですよ。
0242236
NGNG>実は、なんとかそれを避けれないかということで、いろいろやって>>235のようになったのですよ。
ライブラリの元になるオブジェクトはいつ作るのでしょうか?
wildcardでマッチさせようとしているので、makeを起動する前にすでに
オブジェクトができているはずです。だとしたけ結局makeを
複数回起動しているのでは?
0243235
NGNGあ、すんません、実際にwildcardをかけるのは.cとかなんですよ。
foo/lib.c : $(patsubst %.c,%.o,$(wildcard foo/*.o))
ってな感じです。wildcardが適用されない問題に絞るために端折ってました。
0244236
NGNG237の一部差し替え。
.%.arc_rule:
@echo '$*_SRC:=$$(wildcard $*/*.c)' > $@
@echo '$*_OBJ:=$$($*_SRC:%.c=%.o)' >> $@
@echo '$*/lib.a: $$(*_OBJ)' >> $@
@echo ' $$(AR) $$(ARFLAGS) $$@ $$?' >> $@
0245236
NGNG.%.arc_rule:
@echo '$*_SRC:=$$(wildcard $*/*.c)' > $@
@echo '$*_OBJ:=$$($*_SRC:%.c=%.o)' >> $@
@echo '$*/lib.a: $$($*_OBJ)' >> $@
@echo ' $$(AR) $$(ARFLAGS) $$@ $$?' >> $@
@echo 'clean::' >> $@
@echo ' rm -f $$($*_OBJ)' >> $@
0247デフォルトの名無しさん
NGNG> ARC_RULE:=$(DIR_LIST:%=.%.arc_rule)
っていったい何をやっているの?
0248235
NGNGさて、後はソースファイルが削除されたときの・・・。
>>247
ARC_RULE:=$(patsubst %,.%.arc_rule,$(DIR_LIST))
↑の、ちょっと短く書ける書式。
0250デフォルトの名無しさん
NGNGこんなんでどうよ。
.%.arc_rule:
@echo '$*_SRC:=$(wildcard $*/*.c)' > $@
@echo '$*_OBJ:=$$($*_SRC:.c=.o)' >> $@
@echo '$*/lib.a: $$($*_OBJ)' >> $@
@echo ' $$(AR) $$(ARFLAGS) $$@ $$?' >> $@
@echo 'ifneq($*_SRC,$$(wildcard $*/*.c))' >> $@
@echo '$@: .force' >> $@
@echo 'endif' >> $@
@echo 'clean::' >> $@
@echo ' rm -f $$($*_OBJ)' >> $@
.PHONY: .force
0251235
NGNG> ifneq($*_SRC,$(wildcard $*/*.c))
ぱっと見、これが常に偽になりそうです・・・。
> $@ : .force
これは、$*/lib.a : .force ですかね。
ちょっと修正して、こんな感じになるかなぁ?(↓見やすくするための擬似表記です)
$*_SRC:=$(wildcard $*/*.c)
$*_OBJ:=$($*_SRC:.c=.o)
$*/lib.a : $($*_OBJ)
ifneq($*_OBJ,$(wildcard $*/*.o))
$*/lib.a : .force
endif
0252235
NGNG0253デフォルトの名無しさん
NGNG↓jam
http://www.perforce.com/jam/jam.html
0254デフォルトの名無しさん
NGNG> > ifneq($*_SRC,$(wildcard $*/*.c))
> ぱっと見、これが常に偽になりそうです・・・。
なんで? $*_SRCと右の$(wildcard $*/*.c)はワイルドカードが展開されるタイ
ミングが違うはずだが。
> > $@ : .force
> これは、$*/lib.a : .force ですかね。
ちがう。ソースが追加/削除されたら.arc_ruleを書き換えたいんだろ?
0255235
NGNGごめんなさい。完全に勘違いしてました。
試させてもらいました。
ソースを削除したとき、.arc_ruleは更新されますが、
lib.aの中に削除されたソースから生成した.oが含まれたままになってしまい、
リンク時に有効な.oファイルとして認識されてしまいます。
削除されたソースファイル名を認識して、対応する.oファイルを削除し、
lib.aからも削除するようにしないいといけないのですが、
既に存在しないファイルに対してmakeがアクションをおこすような指示をどう書けばいいのかが
思いつきません。
0256デフォルトの名無しさん
NGNGそうなるとたしかに$*/lib.aは強制的に作り直さなきゃだな。
@{ \
echo '$*_SRC:=$(wildcard $*/*.c)'; \
echo '$*_OBJ:=$$($*_SRC:.c=.o)'; \
echo '$*/lib.a: $$($*_OBJ)'; \
echo ' @rm -f $$@'; \
echo ' $$(AR) $$(ARFLAGS) $$@ $$?'; \
echo ' $$(RANLIB) $$@'; \
echo 'ifneq($*_SRC,$$(wildcard $*/*.c))'; \
echo '$@ $*/lib.a: .force'; \
echo 'endif'; \
} > $@
0257235
NGNGそいつだと、%.arc_ruleが作り直された段階で
$*/lib.a: .force の関係がキャンセルされてしまうみたいです。
なので、%.arc_ruleの出力時に$*/lib.aを削除するようにしました。
最終的にはこのようになりまして、(↓全角スペースがタブのかわり)
.PHONY : .force_update
$(ARC_LIST) : %/lib.a :
$(AR) $(ARFLAGS) $@ $?
ARC_RULES:=$(addsuffix /.arc_rule,$(DIR_LIST))
$(ARC_RULES) : %/arc_rule :
@{ \
echo '.$*_SRC:=$(wildcard $*/*.c)' ;\
echo '.$*_OBJ:=$$(.$*_SRC:.c=.o)' ;\
echo '$*/lib.a : $$(.$*_OBJ)' ;\
echo 'ifneq ($$(.$*_SRC),$$(wildcard $*/*.c))' ;\
echo '$@ : .force_update' ;\
echo 'endif' ;\
} >@ ;\
$(RM) -f $*/lib.a
include $(ARC_RULES)
動作は良好です。
ソースの追加、削除、引越しを完全に追跡してくれます。
快適です。
助言くださったみなさま、ありがとうございました。
優良スレage
0258デフォルトの名無しさん
NGNGINCS=`find *.h`
0259デフォルトの名無しさん
NGNG> >>256
> そいつだと、%.arc_ruleが作り直された段階で
> $*/lib.a: .force の関係がキャンセルされてしまうみたいです。
> なので、%.arc_ruleの出力時に$*/lib.aを削除するようにしました。
$*/lib.aを%.arc_ruleに依存するようにするのはどうよ。
0260デフォルトの名無しさん
NGNG対応するソースの無くなったオブジェクトがlib.aに残る問題を考えると、
あのタイミングで削除してしまったほうが効率もよく、すっきりします。
0261デフォルトの名無しさん
NGNG0262デフォルトの名無しさん
NGNG0263デフォルトの名無しさん
NGNGOSTYPEでうまくいきそうですがLinuxは両方linux-gnuになってしまいます。
setやenvにはディストリビューションの情報はなさそうです。
両者の区別は可能ですか?
0264デフォルトの名無しさん
NGNGサポートしているモノのうちのひとつを引数で受け取る仕様に汁。
0265デフォルトの名無しさん
NGNGSYSTEM := $(...) # ディストリビューションを見分けるプログラムを呼ぶ。
include Makefile
0266デフォルトの名無しさん
NGNG> SYSTEM := $(...) # ディストリビューションを見分けるプログラムを呼ぶ。
しまった。$(shell ...)ね。
0267山崎渉
NGNG0268山崎渉
NGNG( ^^ )< ぬるぽ(^^)
0269デフォルトの名無しさん
NGNGmake の本(GNU make の本ではありません)に
.SUFFIXES:
と書くとサフィックスに関するデフォルトの設定をクリアできると書いてありましたが、
GNU make でやってみると何かデフォルトの設定も使われているようなんですね。
-r オプションは使わないとすると、
GNU make では Makefile にどう書けばいいんでしょうか?
実際に問題が発生した例)
debug.cpp と debug ターゲットがある場合、
make debug とやると .cpp: サフィックスルールも適用されてしまう。
0270デフォルトの名無しさん
NGNG0271デフォルトの名無しさん
NGNG0272デフォルトの名無しさん
NGNG.PHONY ではなくて?
0274山崎渉
NGNGピュ.ー ( ^^ ) <これからも僕を応援して下さいね(^^)。
=〔~∪ ̄ ̄〕
= ◎――◎ 山崎渉
0275デフォルトの名無しさん
NGNG0276デフォルトの名無しさん
NGNG同じコマンドラインでも、Windows98上ではエラーにならず、Windows2000では
エラーになります。
エラーメッセージは
make: *** [target] Error 255
というもので原因や対策がはっきりわかりません。
検索すると、よく知られた問題のようですが、根本的な解決方法は見つかりませんでした。
というわけで、
おしえて、えろいひと。
0277デフォルトの名無しさん
NGNG解決法: コマンドラインの引数を少なくする
……しかないんじゃないの?
0279山崎 渉
NGNG__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
0280山崎 渉
NGNG__∧_∧_
|( ^^ )| <寝るぽ(^^)
|\⌒⌒⌒\
\ |⌒⌒⌒~| 山崎渉
~ ̄ ̄ ̄ ̄
0281デフォルトの名無しさん
NGNGgmakeの質問させてください。
Linux上で
$(DEPDIR)/%.d: $(SRCDIR)/%.cpp
<tab>@[-e $(DEPDIR)] || mkdir $(DEPDIR)
<tab>@$(CXX) -なんとか…
って感じで動かしてたんですが、
Solaris8に移植してgmakeかけようとしたら
/bin/sh: test: 引数が足りません。
とか言われてしまいます。
[-e $(DEPDIR)]
でなんでつまづくかわかりません。
ご存知の方がいたら、教えてもらえないでしょうか
0282デフォルトの名無しさん
NGNG自己レスです
[がシェルコマンドとは気づかなかった
Solarisのbin/shだと [-eが使えなかった模様
すいませんでした。
0283デフォルトの名無しさん
NGNGttp://www.freebsd.org/cgi/man.cgi?query=test&sektion=1&apropos=0&manpath=SunOS+5.9
ところで[]の内側にほんとにスペース入れてないのか?
0284デフォルトの名無しさん
NGNGいれてません。
bin/shで-eオプションがないようです。
bin/ksh じゃないと駄目みたいなんですが、
GUN makeってbin/shじゃないと駄目ってのはありませんでしたっけ?
0285デフォルトの名無しさん
NGNG誤解を招くので追記(汗
全角スペースの意味でとりました。
半角は入ってます
0286デフォルトの名無しさん
NGNG0287デフォルトの名無しさん
NGNG「-d filename
ファイル filename が存在し、ディレクトリであれ ば真。」
あぅ、こーいうものがあったんですね。
試してみます、ありがとうございました。
0288デフォルトの名無しさん
NGNG(TAB)rm *.o
(TAB)rm *.a
って書いたら *.o がない時点でエラーになっちゃって *.a が消されません
みなさんはこういう時ってどうしますか?
rm *.o *.a とかでしょうか?
0289デフォルトの名無しさん
NGNGrm -f *.o *.a
0290山崎 渉
NGNG0292山崎 渉
NGNG│ ^ ^ │<これからも僕を応援して下さいね(^^)。
⊂| |つ
(_)(_) 山崎パン
0293デフォルトの名無しさん
NGNG進捗を表示しつつmakeする方法ってありませんか?
0294デフォルトの名無しさん
NGNG0295デフォルトの名無しさん
NGNG@を外す
0296デフォルトの名無しさん
NGNG0297デフォルトの名無しさん
NGNG0298デフォルトの名無しさん
NGNG大きいプロジェクトならmakefile分割しなよ。
そうすれば望みもかなうし管理も楽になるから。
0299デフォルトの名無しさん
NGNG後は、現在時刻と表示された時刻を見比べて、「どの程度」なのかを推測しろ。
できるよな? な?
0300300
NGNG0301デフォルトの名無しさん
NGNG0302デフォルトの名無しさん
NGNG.for n in $(NAMES)
.for v in $(VALUES)
result-$(v)-$(n): foobar data-$(n)
./foobar $(v) < data-$(n) > result-$(v)-$(n)
.endfor
.endfor
こういう構文を GNU make で書くにはどうすればいいんでしょうか?
ループが一重なら % を使って書けるのですが、2つ変化する部分があると
どう書いたらいいものか...
0303デフォルトの名無しさん
NGNGdefine RULE_TEMPLATE
result-$(v)-$(n) : foobar data-$(n)
./foobar $(v) < data-$(n) > result-$(v)-$(n)
endef
$(eval $(foreach n,$(NAMES),$(foreach v,$(VALUES),$(RULE_TEMPLATE))))
と書けるみたい。(全角スペースはタブね)
0304デフォルトの名無しさん
NGNGこの中間にある書きやすくて読みやすくて高機能なビルド支援ツールってないのかね。
0306303
NGNGeval使わない場合は、 -include のファイルが更新対象になるのを利用して、
NAMES:=a b c
VALUES:=1 2 3
RULE_FILE:=.rules
$(RULE_FILE) : $(MAKEFILE)
{ \
$(foreach n,$(NAMES),$(foreach v,$(VALUES), \
echo 'result-$(v)-$(n) : foobar data-$(n)' ;\
echo ' ./foobar $(v) < data-$(n) > result-$(v)-$(n)' ;\
)) \
}>$@
-include $(RULE_FILE)
と書けるみたい。(全角スペースはタブね)
0307302
NGNGおお、makefile を更新したら、ちゃんとルールファイルを更新してから
include するんですね。これは使えそうです。どうも、ありがと。
# $(MAKEFILE) は自分で値を設定しておかないといけないみたいですね。
0308デフォルトの名無しさん
NGNG0309デフォルトの名無しさん
NGNG0310デフォルトの名無しさん
NGNGパスカルに逢わせてくれてありがとう〜♪
0311デフォルトの名無しさん
NGNGMakefile
--------------------
FILE_1 = a.tmp
FILE_2 = ${FILES_1:.tmp=.tmp2}
FILE_3 = *.tmp
FILE_4 = ${FILES_3:.tmp=.tmp2}
all::
@echo ${FILES_1}
@echo ${FILES_2}
@echo ${FILES_3}
@echo ${FILES_4}
--------------------
実行結果
> make
a.tmp
a.tmp2
a.tmp
*.tmp2
FILES_4 でFILES_2 と同じ結果を得たいのですが、
思ったようにできません。
make のみで FILES_2 と同じ内容を FILES_4 に
設定することは可能でしょうか?
0312デフォルトの名無しさん
NGNG0313デフォルトの名無しさん
NGNG0314デフォルトの名無しさん
NGNGmakeなんて初心者虐め、他文化虐め、異端者排除の大好きなUN*X厨の道具だもの。
その証拠にこのスレでは幾多の質問が無かった事のように流されてきたじゃない?
0315デフォルトの名無しさん
NGNGmakefileを書く必要はないんです。
ただ単に、hello.cをコンパイルしたければ
「make hello」とか「make hellow.exe」と打つだけです。
何が難しいんですか?
...makefileを書かねばならんのは、
分割コンパイルをや非標準のライブラリの導入をする
中級者以上だけです。
0316いなむらきよし
NGNG0317デフォルトの名無しさん
NGNG0318デフォルトの名無しさん
NGNG0319デフォルトの名無しさん
NGNG0320デフォルトの名無しさん
NGNG#!/usr/bin/make
なんてスクリプトが書かれるのかな。嫌だな。
0321デフォルトの名無しさん
NGNG0322デフォルトの名無しさん
NGNGいろんな make で扱えるように Makefile を書くかで, 面倒くささが
変わってきて, ちょっといや.
0323デフォルトの名無しさん
NGNGいろんな make で扱えるように Makefile を書くかで, 面倒くささが
変わってきて, ちょっといや.
0324デフォルトの名無しさん
NGNG他には?
0325デフォルトの名無しさん
NGNG7行プログラムじゃないけど、必要最小限、極力簡潔に書くの。
0326デフォルトの名無しさん
NGNGWindowsでもcygwin/binにパス通して使ってる。
nmakeは名前違うからいいけどBorlandのはまんまmakeで激しく迷惑だな。
0327デフォルトの名無しさん
NGNG同位。
あんな変態的なのがmakeを名乗るな。
しょうがないのでこういうスクリプトをbmakeとつけて使ってる。
#!/bin/sh
bccdir=`type bcc32`
bccdir="${bccdir#bcc32 is }"
bccdir="${bccdir%/*}"
if [ -z "$bccdir" ]; then
echo "$0: bcc32 not found" 1>&2
exit 1
fi
if [ "x$1" = x-C ]; then
cd "$2"
shift 2
fi
PATH="$bccdir:$PATH" exec make "$@"
0328デフォルトの名無しさん
NGNGmakeをgmake.exeにリネームするとmakeを起動するmakefileが
通らんので、環境変数からmingw32-make.exeのあるディレクトリを
検索し、PATHの中身を並べ替えてexecvp("make.exe"...する
wmake.exeを書かされた。
void rebuild(std::vector<std::string> &buff,
const char *name, char slash = '\\') {
for (std::vector<std::string>::iterator it = buff.begin();
it != buff.end(); it++) {
struct stat st;
if (stat((*it + slash + name).c_str(), &st)) {
; /* ignore:win32-execvpは存在しないディレクトリもPATHに書いていい */
} else {
std::string s = *it;
buff.erase(it);
buff.insert(buff.begin(), s);
return;
}
}
throw std::runtime_error(std::strerror(ENOENT));
}
0329デフォルトの名無しさん
NGNG0330デフォルトの名無しさん
NGNG仕事じゃないよ。でも後で使うつもり。
低機能だけどMFCやVCLよりシンプルで使うのがラクだからね。
0331デフォルトの名無しさん
NGNG■ このスレッドは過去ログ倉庫に格納されています