思春期ブログ
ディレクトリ分けてて、automakeでも使おうかと思ったんだけど、automakeがインストールされてなかったという。
futonマシンのよいところは、ネットワークに繋がらないことです。あと、冬場に強い(僕がふとんにこもりたがるので)。あと、最近Macをfutonマシンにしました。僕も立派なApple信者です。OSはUbuntuだけど。
話が逸れた。んで、ディレクトリ分けたいけど、automakeもautoconfも無かったので、Makefile自動生成するのを作った。
もちろんautomake使ったほうがよい。
for i in `find -name module.sh | sed -e 's|^\./||g'` do (mod_dir=`dirname $i` . $i srcs=`echo $SOURCES | sed -e 's|\([a-zA-Z./\-]\+\)|'${mod_dir}'/\1|g'` gen_files=`echo $GENERATED | sed -e 's|\([a-zA-Z./\-_]\+\)|'${mod_dir}'/\1|g'` redirect_err="2>&1 |sed -e 's|${mod_dir}/||g'" cat <<EOF # Do not edit. This file is generated by readmodule.sh ${MODNAME}_SOURCES=${srcs} ${MODNAME}_LEX_SRCS=\$(filter %.l,\$(${MODNAME}_SOURCES)) ${MODNAME}_LEX_GEN_SRCS=\$(patsubst %.l,%.c,\$(${MODNAME}_LEX_SRCS)) ${MODNAME}_C_SRCS=\$(filter %.c,\$(${MODNAME}_SOURCES)) \$(${MODNAME}_LEX_GEN_SRCS) \$(patsubst %.l,%.flex.h,\$(${MODNAME}_LEX_SRCS)) ${MODNAME}_CXX_SRCS=\$(filter %.cpp,\$(${MODNAME}_SOURCES)) ${MODNAME}_OBJS=\$(patsubst %.c,%.o,\$(${MODNAME}_C_SRCS)) \$(patsubst %.cpp,%.o,\$(${MODNAME}_CXX_SRCS)) ifeq (\$(COMPILE_DIR),$mod_dir) REDIRECT_ERR=${redirect_err} endif EOF if echo $SOURCES | grep '\.cpp' then linker='$(CXX)' else linker='$(CC)' fi if test x"${NEED_MODULE}" != x""; then depends="\$(${NEED_MODULE}_OUTPUT)" fi if test "$OUT_EXE" != ""; then cat <<EOF ${mod_dir}/${OUT_EXE}: \$(${MODNAME}_OBJS) ${depends} ${linker} -o \$@ \$^ \$(ALL_LIBPATH) \$(LDFLAGS) $LDFLAGS \$(REDIRECT_ERR) ${MODNAME}_OUTPUT=${mod_dir}/${OUT_EXE} EOF target="${mod_dir}/${OUT_EXE}" elif test "$OUT_LIB" != ""; then cat <<EOF ${mod_dir}/${OUT_LIB}: \$(${MODNAME}_OBJS) ${depends} ar rsu \$@ \$^ ALL_LIBPATH+=-L${mod_dir} ${MODNAME}_OUTPUT=${mod_dir}/${OUT_LIB} EOF target="${mod_dir}/${OUT_LIB}" fi if echo $SOURCES | grep '.l'>/dev/null ; then LDFLAGS="$LDFLAGS -lfl" fi cat<<EOF ${mod_dir}/%.o: ${mod_dir}/%.c \$(CC) -o \$@ -c -I${mod_dir} \$(CFLAGS) \$(CPPFLAGS) $CFLAGS $CPPFLAGS \$< \$(REDIRECT_ERR) ${mod_dir}/%.o: ${mod_dir}/%.cpp \$(CXX) -o \$@ -c -I${mod_dir} \$(CXXFLAGS) \$(CPPFLAGS) $CXXFLAGS $CPPFLAGS \$< \$(REDIRECT_ERR) ${mod_dir}/%.c: ${mod_dir}/%.l flex --header-file=\$(patsubst %.l,%.flex.h,\$(${MODNAME}_LEX_SRCS)) --outfile=\$@ \$< \$(REDIRECT_ERR) ${MODNAME}_GEN_FILES=$target \$(${MODNAME}_LEX_GEN_SRCS) \$(${MODNAME}_OBJS) ${MODNAME}_GEN_SOURCES=\$(${MODNAME}_LEX_GEN_SRCS) ${gen_files} ALL_GEN_FILES+=\$(${MODNAME}_GEN_FILES) ALL_SOURCES+=\$(${MODNAME}_C_SRCS) \$(${MODNAME}_CXX_SRCS) ALL_TARGETS+=$target ALL_GEN_SOURCES+=\$(${MODNAME}_GEN_SOURCES) DEPEND_INC+=-I${mod_dir} ${MODNAME}_clean: rm -f \$(${MODNAME}_GEN_FILES) ${POST_APPEND} EOF cat >$mod_dir/Makefile <<EOF all: make -C $PWD $target COMPILE_DIR="${mod_dir}" clean: make -C $PWD ${MODNAME}_clean COMPILE_DIR="${mod_dir}" redep: make -C $PWD redep COMPILE_DIR="${mod_dir}" EOF ) done
module.shという名前で、
MODNAME=nanika SOURCES='a.c b.c d.c' OUT_EXE='a.out'
こういう感じのファイルを転がしておけば、(←ここらへんがautomakeより偉い。automakeはconfigure.inにMakefileの位置を書かないといけない)
# Do not edit. This file is generated by readmodule.sh nanika_SOURCES=sub/a.c sub/b.c sub/d.c nanika_LEX_SRCS=$(filter %.l,$(nanika_SOURCES)) nanika_LEX_GEN_SRCS=$(patsubst %.l,%.c,$(nanika_LEX_SRCS)) nanika_C_SRCS=$(filter %.c,$(nanika_SOURCES)) $(nanika_LEX_GEN_SRCS) $(patsubst %.l,%.flex.h,$(nanika_LEX_SRCS)) nanika_CXX_SRCS=$(filter %.cpp,$(nanika_SOURCES)) nanika_OBJS=$(patsubst %.c,%.o,$(nanika_C_SRCS)) $(patsubst %.cpp,%.o,$(nanika_CXX_SRCS)) ifeq ($(COMPILE_DIR),sub) REDIRECT_ERR=2>&1 |sed -e 's|sub/||g' endif sub/a.out: $(nanika_OBJS) $(CC) -o $@ $^ $(ALL_LIBPATH) $(LDFLAGS) $(REDIRECT_ERR) nanika_OUTPUT=sub/a.out sub/%.o: sub/%.c $(CC) -o $@ -c -Isub $(CFLAGS) $(CPPFLAGS) $< $(REDIRECT_ERR) sub/%.o: sub/%.cpp $(CXX) -o $@ -c -Isub $(CXXFLAGS) $(CPPFLAGS) $< $(REDIRECT_ERR) sub/%.c: sub/%.l flex --header-file=$(patsubst %.l,%.flex.h,$(nanika_LEX_SRCS)) --outfile=$@ $< $(REDIRECT_ERR) nanika_GEN_FILES=sub/a.out $(nanika_LEX_GEN_SRCS) $(nanika_OBJS) nanika_GEN_SOURCES=$(nanika_LEX_GEN_SRCS) ALL_GEN_FILES+=$(nanika_GEN_FILES) ALL_SOURCES+=$(nanika_C_SRCS) $(nanika_CXX_SRCS) ALL_TARGETS+=sub/a.out ALL_GEN_SOURCES+=$(nanika_GEN_SOURCES) DEPEND_INC+=-Isub nanika_clean: rm -f $(nanika_GEN_FILES)
こんな感じのを出力してくれます。
あと、automakeよりも良い点として、ディレクトリ深くなっても「入ります」「出ます」が一回ぐらいしか出ない。