aboutsummaryrefslogtreecommitdiffstats
path: root/cppMakefile
diff options
context:
space:
mode:
Diffstat (limited to 'cppMakefile')
-rw-r--r--cppMakefile/!readme.asciidoc56
-rw-r--r--cppMakefile/GNUmakefile79
-rwxr-xr-xcppMakefile/GNUmakefile.dependency.sh24
3 files changed, 159 insertions, 0 deletions
diff --git a/cppMakefile/!readme.asciidoc b/cppMakefile/!readme.asciidoc
new file mode 100644
index 0000000..da89fc4
--- /dev/null
+++ b/cppMakefile/!readme.asciidoc
@@ -0,0 +1,56 @@
+
+
+
+.Description
+
+這是一個簡單的 *GNU makefile for 'C++' project*
+類似AutoTool等工具, 不過又更簡化了, 操作方法是利用GNUMakefile裡的targets
+當作指令, 生出一個targets檔, 以後鍵入 `make all` 就會自動把所有targets都
+編譯出來.
+
+.Commands
+
+* `make init` +
+初始化, 設定完之後所在位置會多幾個資料夾如下
+
+** 'bin/' 放編譯出來的執行檔
+** 'dep/' dependency相關資料, 內容會自動生成, 不用理它
+** 'inc/' 自定義的include file放置位置
+** 'src/' source code放置位置
+** 'obj/' obj file放置位置, 會自動生成, 不用理它
+
+* `make new NAME=<name> [OBJS=<OBJ_FILES> LIBS=<LIBRARIES>]` +
+新增一個target, 須給定目標名 , 並且此Makefile會假定 `main() { ... }` 放在
+'src/<name>.cpp' 而最終輸出會是 'bin/<name>' . +
+關於 'OBJS=' 與 'LIBS=' 參考下面說明
+
+* `make add NAME=<name> [OBJS=<OBJ_FILES> LIBS=<LIBRARIES>]` +
+針對target為 '<name>' 的目標新增需要的 '<OBJ_FILES>' , 與 '<LIBRARIES>'.
+'<LIBRARIES>' 的部份會用 `pkg-config` 去解讀, 例如 '<LIBRARIES>' 為
+'opencv lapackpp' 則link時會被以下指令展開 +
+`pkg-config --libs opencv lapackpp` +
+而 '<OBJ_FILES>' 的部份則只需要給 *name* 就好, 不需要有完整個 pathname, 例如
+例如 '<OBJ_FILES>' 是 'a b c' 則此makefile會視為
+
+** source code: 'src/a.cpp src/b.cpp src/c.cpp'
+** obj file: 'obj/a.o obj/b.o obj/c.o'
+
+* `make del NAME=<name> [OBJS=<OBJ_FILES> LIBS=<LIBRARIES>]` +
+與 add相反, 嘗試將指定target所需的'<OBJ_FILES>'和'<LIBRARIES>'移除
+
+* `make clean` +
+將 'bin/*' 'dep/*' 'obj/*' 清除, 有時候覺得dependency怪怪的
+時可以嘗試執行此指令
+
+[NOTE]
+其中整個project到底有哪些obj file會完全依照 *src/* 裡面有哪些 `.cpp` 檔決定
+
+===== GNUMakefile
+
+就是一個 Makefile, 不過裡面有些東西是 `GNU-make` only的
+
+===== GNUMakefile.dependency.bash
+
+產生 dependency檔用的
+
+
diff --git a/cppMakefile/GNUmakefile b/cppMakefile/GNUmakefile
new file mode 100644
index 0000000..839be8e
--- /dev/null
+++ b/cppMakefile/GNUmakefile
@@ -0,0 +1,79 @@
+INC := inc
+SRC := src
+OBJ := obj
+BIN := bin
+DEP := dep
+
+LIB_INCS :=
+CXX := g++
+CXXFLAGS := -Wall -O2 -I$(INC) $(LIB_INCS) -g -pedantic -lstdc++ -lm
+CXX_OBJ := $(CXX) -c
+CXX_DEP := $(CXX) -MM
+
+DEPENDENCY_CREATER := ./GNUmakefile.dependency.sh
+
+OBJECTS := $(patsubst $(SRC)/%.cpp,$(OBJ)/%.o,$(wildcard $(SRC)/*.cpp))
+DEPENDENCYS := $(patsubst $(SRC)/%.cpp,$(DEP)/%.d,$(wildcard $(SRC)/*.cpp))
+
+TARGET_FILE := GNUmakefile.targets
+TARGETS :=
+
+NAME := empty
+
+.PHONY: all all2 dep clean init new del add sub
+
+all: all2
+
+-include $(TARGET_FILE)
+
+all2: $(TARGETS)
+
+init:
+ -@mkdir -p $(BIN)
+ -@mkdir -p $(SRC)
+ -@mkdir -p $(INC)
+ -@mkdir -p $(OBJ)
+ -@mkdir -p $(DEP)
+ -@echo '' > $(TARGET_FILE)
+
+new:
+ @set -e; echo "Add target '$(NAME)'"; \
+ echo 'TARGETS := $$(TARGETS) $$(BIN)/$(NAME)' >> $(TARGET_FILE); \
+ echo '$(NAME)_OBJS := $(foreach n,$(OBJS),$$(OBJ)/$(n).o)' >> $(TARGET_FILE); \
+ echo '$(NAME)_LIBS := $(LIBS)' >> $(TARGET_FILE); \
+ echo '$$(BIN)/$(NAME): $$(OBJ)/$(NAME).o $$($(NAME)_OBJS)' >> $(TARGET_FILE); \
+ echo '\t@echo Target: $$@...' >> $(TARGET_FILE); \
+ echo '\t@$$(CXX) $$^ $$(CXXFLAGS) `pkg-config --cflags --libs $$($(NAME)_LIBS) 2>/dev/null` -o $$@' >> $(TARGET_FILE); \
+ echo '' >> $(TARGET_FILE)
+
+add:
+ @set -e; echo "Add Objects $(OBJS) to Target '$(NAME)'"; \
+ sed '/^$(NAME)_OBJS :=/s/$$/& $(foreach n,$(OBJS),\$$(OBJ)\/$(n).o)/' $(TARGET_FILE) >$(TARGET_FILE).$$$$; \
+ mv -f $(TARGET_FILE).$$$$ $(TARGET_FILE)
+ @set -e; echo "Add Libraries $(LIBS) to Target '$(NAME)'"; \
+ sed '/^$(NAME)_LIBS :=/s/$$/& $(subst /,\/,$(LIBS))/' $(TARGET_FILE) >$(TARGET_FILE).$$$$; \
+ mv -f $(TARGET_FILE).$$$$ $(TARGET_FILE)
+
+sub:
+ @set -e; echo "Remove Objects $(OBJS) from Target '$(NAME)'"; \
+ sed '/^$(NAME)_OBJS :=/s/$(subst \ ,|,$(foreach n,$(OBJS),\$$(OBJ)\/$(n).o))//' $(TARGET_FILE) >$(TARGET_FILE).$$$$; \
+ mv -f $(TARGET_FILE).$$$$ $(TARGET_FILE)
+ @set -e; echo "Remove Libraries $(LIBS) from Target '$(NAME)'"; \
+ sed '/^$(NAME)_OBJS :=/s/$(subst \ ,|,$(foreach n,$(LIBS),\$$(OBJ)\/$(n).o))//' $(TARGET_FILE) >$(TARGET_FILE).$$$$; \
+ mv -f $(TARGET_FILE).$$$$ $(TARGET_FILE)
+
+clean:
+ -rm -f $(BIN)/*
+ -rm -f $(OBJ)/* 2>/dev/null
+ -rm -f $(DEP)/*
+
+dep: $(DEPENDENCY);
+
+-include $(DEPENDENCYS)
+
+$(DEPENDENCYS):: $(DEP)/%.d: $(SRC)/%.cpp
+ $(DEPENDENCY_CREATER) "`$(CXX_DEP) $(CXXFLAGS) $<`" $@
+
+$(OBJECTS): $(OBJ)/%.o: $(SRC)/%.cpp $(DEP)/%.d $(DEP)/%.d
+ @echo 'Objects: $@...'
+ @$(CXX_OBJ) $(CXXFLAGS) -o $@ $<
diff --git a/cppMakefile/GNUmakefile.dependency.sh b/cppMakefile/GNUmakefile.dependency.sh
new file mode 100755
index 0000000..0d2b65a
--- /dev/null
+++ b/cppMakefile/GNUmakefile.dependency.sh
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+out=`echo "$2" | sed -e 's/\\//\\\\\//g'`
+
+echo $1 \
+ | sed -e 's/\\ / /g' \
+ | sed -e ':x; /\\$/ {N;s/\\\n//; tx};' \
+ | sed -e 's/.*://g' \
+ > $2.$$
+rm -f $2
+cat $2.$$ \
+ | sed -e 's/^/'$out'::/g' \
+ >> $2
+printf '\t%s "`%s %s $<`" $@\n' \
+ '$(DEPENDENCY_CREATER)' \
+ '$(CXX_DEP)' \
+ '$(CXXFLAGS)' \
+ >> $2
+cat $2.$$ \
+ | sed -e 's/ */\n/g' \
+ | sed -e 's/$/::;/g' \
+ | sed -e 's/^::;$//g' \
+ >> $2
+rm -f $2.$$