問題はおそらく私の問題を説明するのに最適なものではありませんが、より良い問題を考えることができませんでした。私のメイクファイルは次のようになります:
PROGRAM_NAME = prog
OBJECT_FILES = $(PROGRAM_NAME).o
CFLAGS = -O2 -Wall -g
$(PROGRAM_NAME) : $(OBJECT_FILES)
gcc $(CFLAGS) -o $@ $(OBJECT_FILES)
$(PROGRAM_NAME).o : $(PROGRAM_NAME).c data.h
gcc $(CFLAGS) -c $<
clean :
$(RM) $(PROGRAM_NAME)
$(RM) $(OBJECT_FILES)
$(RM) *~ *.bak
run :
@$(MAKE) && ./$(PROGRAM_NAME) $(ARGS)
コンパイルして実行したいときは、「make run」を実行するだけです。この問題は、私のプログラムがCtrl + Zによって生成された信号を処理することであり、「make run」でプログラムを開始すると、信号はプログラム自体ではなく「make run」に送信されます。
基本的に、「make run」を呼び出すことは、直接「make && ./prog」を呼び出すことと同じではありません。最初のケースでは、「prog」が最初に終了しない限り、「make run」は終了しないためです。
これを回避する方法はありますか?
Makefileから実行するのは少し変わっています。おそらく、一部のIDE=が提供する「コンパイルして実行」メニュー項目を複製しようとしていますか?Makeは、それを行うための十分な設備が整っていません。
ターゲットコマンドで発生するすべてのものは、端末に直接接続されていないサブプロセスで発生します。そのため、makeはキーストロークを受け取ります。
注目すべきもう1つのこと:通常、オブジェクトファイルから実行可能ステージ(リンク)は、コンパイルステージとは異なるフラグ(LDFLAGS
とLIBS
)のセットを使用します。この簡単な例ではそれを回避できますが、より複雑なケースで使用するためにこのメイクファイルをコピーすると、問題が発生します。
プログラムが最新であるかどうかに依存するようにすることで、「実行」ターゲットを単純化してから、単にプログラムを実行することができます。
run: ${PROGRAM_NAME}
./${PROGRAM} ${ARGS}
make
をすでに実行している場合、make
を実行してもあまり意味がありません。少なくとも、このコンテキストではそうではありません。 (異なるディレクトリでの)再帰的な操作の可能性がありますが、「 再帰的に有害と見なされる 」を参照してください。
また、makefileは通常、ターゲット 'all
'を提供する必要があり、通常は最初の、したがってデフォルトのターゲットでなければなりません。
何度もビルドして実行する場合は、history
コマンドを使用してこれを支援できます。
# Run this once
make && ./foo
# Repeat last command
!!
Dmckeeの答えが言ったように、make(1)はコンパイルおよび実行用ではなく、何かを作成しています。
もちろん、意図した 'make && ./prog argsを実行するShellエイリアスmake-runを作成しても何も問題はありません。 = '。
あなたはこのように試すことができます:
_APP = olupxtest
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
CXXFLAGS = -g -fPIC -c
LDFLAGS =
LIBS =
.PHONY: all clean
all: clean $(APP) run
$(APP): $(OBJS)
$(CXX) $(LDFLAGS) $^ $(LIBS) -o $@
clean:
$(RM) $(OBJS) $(APP)
run: ${APP}
./${APP} ${ARGS}
_
ここでは、ターゲットの複数のルールを呼び出しています:all: clean $(APP) run