• 締切済み

makefileでコピーしてからコンパイルする方法

諸事情あって、C言語のコンパイルするファイルを(vpathで指定せずに)カレントディレクトリにコピーしてから、コンパイルを実行したいと思っています。 以下のように、compile_pre でコピー、compile_main でgcc を起動しているのですが、main.oがコンパイルできない旨、エラーで終了してしまいます。 これはどうしてなのでしょうか? (compile_pre → comple_main の順番には実行しないのでしょうか?) また、このようなことをしたいばあい、何か良い方法はありませんでしょうか。 ----------------------------------------------- # (src/main.c から main.o を生成して、main.exe を生成する) TARGET = main.exe TARGET_OBJS = main.o #TARGET_OBJS += sub.o ... .PHONY: compile compile_pre compile_main compile: compile_pre compile_main compile_pre:      cp -fp ./src/main.c .; compile_main: $(TARGET) $(TARGET): $(TARGET_OBJS)      gcc -o $(TARGET) $(TARGET_OBJS) %.o : %.c      gcc -c -o $@ $< ----------------------------------------------- UNIX%> make compile --dry-run --debug GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for i686-pc-linux-gnu Reading makefiles... Updating goal targets....  File `compile' does not exist.    File `compile_pre' does not exist.   Must remake target `compile_pre'. cp -fp ./src/main.c .;   Successfully remade target file `compile_pre'.    File `compile_main' does not exist.      File `main.exe' does not exist.        File `main.o' does not exist.       Must remake target `main.o'. make: *** No rule to make target `main.o', needed by `main.exe'. Stop. 宜しくお願い致します。

みんなの回答

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.5

>%.o : %.c を %.o : src/%.c にするだけでもコピーなんてしなくても良くなりますけど。 #3へ -jオプションの並列処理がありますから、その関係で順番はなくなったんじゃないでしょうか。

tk_1980024
質問者

お礼

ありがとうございます。 ま、諸事情あってのことなので、そう簡単でもありません。 結局正解がでませんでしたが、このmake が動作しない理由は「GNU make 第3版 3.4 変数はいつ展開されるか」にヒントがありました。 make の内部処理は2段階に分かれていて、1段目のファイルチェックの段階ではコピーは実行されてないため、ファイルの依存関係グラフを作成する際にエラーとなるということです。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

http://www.gnu.org/software/make/manual/html_node/Instead-of-Execution.html#Instead-of-Execution よーく読んでください。 http://linuxjm.sourceforge.jp/html/GNU_make/man1/make.1.html でもいいです。 --dry-runの説明、なんと書いてありますか? 素直にVPATH使うとか(Makefile中に書けないならコマンドラインで指定するとか)、main.cのシンボリックリンクを作るとか、同等のことをするやり方はいくらでもあります。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

ちょいと確認しましたが, GNU make では #2 で言われるように依存ファイルの間の順序は「決まっていない」ということなので, 今の場合 compile_pre と compile_main のどちらを先に処理するかわかりません. 必要ならさらに依存関係を追加する必要がありますね. かつての make では, 必ず compile_pre を先に作り直したものですが. あと, この最後のエラーは実質的に「『main.o を作るために必要なファイル』を作る方法がわからない」と言っているんだと読むといいかな.

tk_1980024
質問者

補足

自分でも少ししらべてみました。 > GNU make では #2 で言われるように依存ファイルの間の順 > 序は「決まっていない」ということなので, は、手元の書籍と見解が違います。 「GNU make 第3版 6章 大きなプロジェクトの管理」p110 によると > 複数の必須項目が同じ行に書かれていた場合、GNU make はそれらを > 左から右に更新します。 ご指摘は間違えだと考えます。

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

>(compile_pre → comple_main の順番には実行しないのでしょうか?) しません。 >compile: compile_pre compile_main 「compile は、compile_pre と compile_main に依存している」という事であって 「compile の実行には、先に compile_pre, compile_main の順に実行する」ではありませんから。

tk_1980024
質問者

お礼

ありがとうございます。 No3 で書きましたが、 > 「compile の実行には、先に compile_pre, compile_main の > 順に実行する」ではありませんから。 は少なくとも GNU makeの実装とは違います。 「compile_pre, compile_main の順に実行する」が正解です。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

そりゃそうなるわな. だって 何もしてない んだもん.

関連するQ&A

  • Makefileについて

    makeファイルの書き方で悩んでいます。 makeファイルは書いたことがなく、ほとんど丸写しです。 私がしたいのは、 (1)run:部分で削除するファイルがなかった場合、エラーとなり次の行へ進みません。なくても(エラーでも/エラー回避して)次の行へ進む方法が知りたいです。 もうひとつは(2)run:部分で、cleanを実行し、makeしてrunを実行させる方法が知りたいです。 --------------以下、サンプルMakefileです。 CC = gcc OBJS = main.o sub.o PROG = test.exe .c.o: $(CC) -c $< -o $@ $(PROG) : $(OBJS) $(CC) $(OBJS) -o $(PROG) $(OBJS) : Makefile clean: rm -f *.o $(PROG) run: rm *.log <---- (1)ここでファイルがないとエラーで止まる $(PROG) all:   <-- (2)[clean]を実行して、makeして、[run]を実行させたい 以上です。

  • gfortranでmakefile

    gfortranのmakefileを作成し、"make test"と実行しても成功しません。 どうすればいいのでしょうか? どこか間違いがあるでしょうか? 下にmakefileを全文載せましたのでアドバイスをよろしくお願いします。 OBJS = main.o tree.o treef.o test : ${OBJS} gfortran -c test ${OBJS} main.fやtree.fやtreef.fのファイルの中身は問題ありません。 他のパソコンではキチンとコンパイルに成功しています。 ちなみに、"make test"と実行して出てくるエラーメッセージが「makefile:3 *** 最初のターゲットより前にコマンドを起動. 中止.」 です。

  • C言語のmakefileについて

    C言語のmakefileについて質問です。 例えば下記makefileでは、“CC”というマクロを“gcc”という文字列で再定義しています。 しかし中には(1)『CC = gcc』という定義なしでいきなり(2)『$(CC) -o hello $(objs)』 でコンパイルしているmakefileを見るのですが、その場合(2)は何でコンパイルされているのでしょうか。($(CC)の中身はCC??GCC?ACC??) ※下記ターゲット名等はサンプルです。 ------------------ # Makefile objs = hello.o edajima.o CC = gcc hello: $(objs) $(CC) -o hello $(objs) .PHONY: clean clean: $(RM) hello $(objs)

  • gfortranでmakefile

    gfortranのmakefileを作成し、"make test"と実行しても成功しません。 どうすればいいのでしょうか? どこか間違いがあるでしょうか? 下にmakefileを全文載せましたのでアドバイスをよろしくお願いします。 OBJS = main.o tree.o treef.o\ test : ${OBJS} gfortran -c test ${OBJS} main.fやtree.fやtreef.fのファイルの中身は問題ありません。 他のパソコンではキチンとコンパイルに成功しています。

  • gdbデバッグのためのmakefile作成

    現在Ubuntu Linuxでgccプログラミングを行っています。現在、ソースコードをいくつかのファイルに分割して作成しています。コンパイル時はmakefileを使用してmakeして実行ファイルを作成しています。 現在のプログラムをgdbでデバッグできるようにしたいと思っているのですが、 その場合のmakefileはどのようにして書けば良いのかをご教示頂きますよう、お願い致します。 現在のmakefile内容 https://sourceforge.jp/projects/cc1101driver/scm/svn/blobs/2319/trunk/20140411/Makefile #test #CC = gcc #test:main.c event.c exe: main.o event.o env.o audio.o task.o comm.o menu_show_status.o gcc -o exe main.o event.o env.o audio.o task.o comm.o menu_show_status.o -lpthread main.o:main.c gcc -c main.c event.o:event.c gcc -c event.c env.o:env.c gcc -c env.c audio.o:audio.c gcc -c audio.c task.o:task.c gcc -c task.c comm.o:comm.c gcc -c comm.c menu_show_status.o:menu_show_status.c gcc -c menu_show_status.c

  • Makefileと共有ライブラリ

    main.c sub1.c sub2.cに対して 共有ライブラリlibsub1.soとlibsub2.soを生成して それをもちいてmainをコンパイルするMakefileを以下のように記述しました。 CC=gcc LIB= CFLAGS=-Wall TARGET = main SHAD = -shared .SUFFIXES:.so .o SRCS = main.c libsub1.so libsub2.so $(TARGET):$(SRCS) $(CC) -o $@ $(SRCS) @echo "make finished!!" #.o.so: # $(CC) $(SHAD) -o $@ $< libsub1.so:sub1.o gcc -shared -o libsub1.so sub1.o libsub2.so:sub2.o gcc -shared -o libsub2.so sub2.o .c.o: $(CC) -c $< #sub1.o:sub1.c # gcc -c -fPIC sub1.c #sub2.o:sub2.c # gcc -c -fPIC sub2.c clean: @rm -f libsub?.so sub?.o ここで.oから.cを生成するのはサフィックスでできたのですが、同じように.oから.soを生成するのは できませんでした。 #.o.so: # $(CC) $(SHAD) -o $@ $< ここはどのように記述したらいいのでしょうか? 回答お願いします。

  • makefile の書き方

    OBJS1 = a.o b.o c.o OBJS2 = d.o e.o f.o OBJS1のそれぞれの元のソースコードと OBJS2のそれぞれに元のソースコードを 違うコンパイルオプションでオブジェクトファイルを作りたいのですが、 間単に書ける方法があれば教えてください。 つまり、以下を簡単に書く方法です。 よろしくお願いします。 a.o: a.c ${CC} ${CFLAGS_1} $< -o $@ b.o: b.c ${CC} ${CFLAGS_1} $< -o $@ c.o: c.c ${CC} ${CFLAGS_1} $< -o $@ d.o: d.c ${CC} ${CFLAGS_2} $< -o $@ e.o: e.c ${CC} ${CFLAGS_2} $< -o $@ f.o: f.c ${CC} ${CFLAGS_2} $< -o $@

  • Makefileでのコンパイル方法

    こんにちは。 Windows環境で下記のソースコードのコンパイルを行いたいのですが http://research.microsoft.com/en-us/projects/detours/ rcコマンドがわからないというような内容のエラーが発生し、 うまくコンパイルすることができませんでした。 プログラムの知識はほとんどなく、VisualStudioで 簡単なソースを書いてコンパイルできる程度です。 Vistaで起動できなくなったプログラムを起動させたく、 似たような事例があったため、こちらのページを参考にしています。 http://d.hatena.ne.jp/ardarim/20080801/1217609557 表示されるログは下記のとおりです。 c:\Detours>nmake Microsoft (R) Program Maintenance Utility Version 10.00.20506.01 Copyright (C) Microsoft Corporation. All rights reserved. cd "c:\Detours\src" Building for 64-bit X64. if not exist "..\include" mkdir "..\include" if not exist "..\lib" mkdir "..\lib" if not exist "..\bin" mkdir "..\bin" rc detoured.rc 'rc' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 NMAKE : fatal error U1077: 'rc' : return code '0x1' Stop. NMAKE : fatal error U1077: 'c:\Detours\nmake.exe' : return code '0x2' Stop. c:\Detours> C:\Detouls内に上記のソースコードを置き(Makefileがある階層)、 VisualStudioをインストールし、nmake.exeを同フォルダにコピーし、実行しました。 解決法わかる方いらっしゃいましたらよろしくお願いいたします。

  • Makefile作成時の拡張子.oとは?

    main2.o: main.c gcc -o main2.o -c main.c hello2.o: hello.c gcc -o hello2.o -c hello.c test2: main2.o hello2.o gcc -o test2 main2.o hello2.o のようなMakefile作成時の拡張子.oとは何のファイルという意味なのでしょうか? Makefile作成初心者なのでご教授お願いいたします。

  • makefileの書き方

    makefileを書いたのですが、コンパイルしたあとに、main.cppの内容を変更してから、またmakeってタイプして変更した箇所が反映されません。どこがおかしいでしょうか?よろしくお願いします。 program : main.o g++ -o program main.o main.o : main.cpp g++ -Wall -c main.cpp DeleteObj: rm main.o

専門家に質問してみよう