makefile
をCとC++の両方で使用するには、言語ごとに別々のルールが必要ですが、いくつかのルールは同じです。
別の問題はリンカです。 Cのみのプロジェクトではリンカーは1つではなくリンカーを使用します。
メイクファイルをここにダンプしています(それはthis projectです)。
この例からわかるように、Cファイルで作成されたオブジェクトとC++で作成されたオブジェクトの2つの異なるビルドルールがあります。最初のものが失敗すると、2番目のものが試行されるので、オブジェクトのリストを共有することができます。
また、あなたはC++の規則はC++を使用しているプロジェクトでC++リンカにリンカ変数(CCL
)を設定し、このライン$(eval CCL = $(CPP))
を持っていることに気づくかもしれません。このようにして、ビルドルールが呼び出されると、正しいリンカーが使用されます。
もう1つのことは、このコードがリストと拡張子置換を処理する方法です。 foreach
、addsuffix
、およびbasename
の機能を使用していることに注目してください。これは、あなたが提案した$(CSRCS:.c=.o)
のはっきりと複雑です。
make変数を表示するルールを追加することをお勧めします。迷子になったもの(デモを参照)をデバッグすることができます。これは、問題を解決するだけでなく問題を解決するための素晴らしい方法です。
私はここに貼り付けていmakefile
に関する警告のいくつかの単語は...
これは、CおよびC++の両方(混合)のプロジェクトのために働き、それはほとんど「プラグアンドプレイ」ですが、あなたは必見へフォルダ名とターゲットファイルをフォルダ構造に合わせて変更します。また
、場合、それはあなたが(それは、クリーンアップが本物容易になりますよう、それが、理由tmp
として定義されています)プロジェクトフォルダとして一時フォルダを定義し、プロジェクトの全体を削除することを予告。
今後、src
サブフォルダが自動的に追加されるように更新するかもしれませんが、現時点では、いくつかのフォルダを除外する特別なコントロールが必要です。
このメイクファイルはほとんどが怠惰な作業です...メイクファイルを常に更新するのは嫌ですので、私はプロジェクトのフォルダ構造や必要性を変更しない限り、異なるライブラリ。パートビースパイツ提案として
NAME=demo
OUT_ROOT=./tmp
TMP_ROOT=./tmp
SRC_ROOT=.
SRC_EXTRA_FOLDERS=src src/http
LIBS=-pthread -lssl -lcrypto
INCLUDE=/usr/local/include
[email protected]
[email protected]++
[email protected]
OPTIMIZATION=O3
#auto computed values
BIN = $(OUT_ROOT)/$(NAME)
SRCDIR = $(SRC_ROOT) $(foreach dir, $(SRC_EXTRA_FOLDERS), $(addsuffix /,$(basename $(SRC_ROOT)))$(dir))
SRC = $(foreach dir, $(SRCDIR), $(wildcard $(addsuffix /, $(basename $(dir)))*.c*))
BUILDTREE =$(foreach dir, $(SRCDIR), $(addsuffix /, $(basename $(TMP_ROOT)))$(basename $(dir)))
OBJS = $(foreach source, $(SRC), $(addprefix $(TMP_ROOT)/, $(addsuffix .o, $(basename $(source)))))
CCL = $(CC)
# the C flags
CFLAGS=-Wall -g -$(OPTIMIZATION) -std=c11 $(foreach dir,$(INCLUDE),$(addprefix -I, $(dir))) $(foreach dir,$(SRCDIR),$(addprefix -I, $(dir)))
CPPFLAGS= -Wall -$(OPTIMIZATION) -std=c++11 $(foreach dir,$(INCLUDE),$(addprefix -I, $(dir))) $(foreach dir,$(SRCDIR),$(addprefix -I, $(dir)))
$(NAME): build
build: $(OBJS)
$(CCL) -o $(BIN) $^ -$(OPTIMIZATION) $(LIBS)
$(TMP_ROOT)/%.o: %.c
$(CC) -o [email protected] -c $^ $(CFLAGS)
$(TMP_ROOT)/%.o: %.cpp
$(CPP) -o [email protected] -c $^ $(CPPFLAGS)
$(eval CCL = $(CPP))
clean:
[email protected] $(BIN)
[email protected] -R $(TMP_ROOT)
[email protected] -p $(BUILDTREE)
execute:
@$(BIN)
run: | clean build execute
db: | clean build
$(DB) $(BIN)
vars:
@echo "BIN: $(BIN)"
@echo ""
@echo "SRCDIR: $(SRCDIR)"
@echo ""
@echo "SRC: $(SRC)"
@echo ""
@echo "BUILDTREE: $(BUILDTREE)"
@echo ""
@echo "OBJS: $(OBJS)"
@echo ""
@echo "CFLAGS: $(CFLAGS)"
@echo ""
@echo "CPPFLAGS: $(CPPFLAGS)"
、私はそこにすべての同時実行の人々のために、注文したとして、前提条件をマークするために、パイプ記号(|
)を追加しました。
エラーメッセージは何ですか? – immibis
あなたはそのメークファイルにターゲットを持っていません - 何が起こると思いますか? –
@ Toby Speight私の実際のメイクファイルには、.cppファイルと.cファイルのターゲットと異なるルールがありますが、わかりません。これは、.cppファイルと.cファイルの両方から.oファイルを正しく生成できないこと(1つから生成することは簡単です)という中核的な問題を解決するためのおもしろい例でした。 – NutellaFan