25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Makefile 11 KiB

10 년 전
10 년 전
10 년 전
10 년 전
10 년 전
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. # Makefile --- 10sr make dotfiles
  2. # 2014, 10sr. Unlicensed <http://unlicense.org>
  3. # TODO: Add help message
  4. # Variable definitions
  5. dotfiles_url_base := https://raw.githubusercontent.com/10sr/dotfiles/master
  6. use_git ?= t
  7. git_auth ?= t
  8. dotfiles_git_path := 10sr/dotfiles.git
  9. ifneq (,$(git_auth))
  10. dotfiles_git := git@github.com:$(dotfiles_git_path)
  11. else
  12. $(warning 'git_auth' is empty. Use public read-only git repository.)
  13. dotfiles_git := http://github.com/$(dotfiles_git_path)
  14. endif
  15. current_origin_url := $(shell git config remote.origin.url)
  16. ifeq (,$(dotfiles_dir))
  17. ifneq (,$(findstring $(dotfiles_git_path),$(current_origin_url)))
  18. $(warning Currently in dotfiles repository)
  19. dotfiles_dir := $(PWD)
  20. else
  21. # Current directory is not 10sr/dotfiles.git reposioty
  22. ifeq (,$(DOTFILES_DIR))
  23. $(warning Neigher DOTFILES_DIR nor dotfiles_dir is defined)
  24. $(warning Use default value)
  25. dotfiles_dir := $(HOME)/10sr_dotfiles
  26. else
  27. # dotfiles_dir is empty but DOTFILES_DIR has a value
  28. $(warning dotfiles_dir is set from DOTFILES_DIR)
  29. dotfiles_dir := $(DOTFILES_DIR)
  30. endif
  31. endif
  32. endif
  33. $(warning dotfiles_dir: $(dotfiles_dir))
  34. dotfiles_home_dir := $(dotfiles_dir)/.home
  35. ifeq ($(home),)
  36. ifeq ($(global_home),)
  37. $(warning home not set and global_home is empty)
  38. # TODO: What this should be?
  39. home := $(dotfiles_home_dir)
  40. else
  41. home := $(HOME)
  42. endif
  43. endif
  44. $(warning home: $(home))
  45. localdir := $(home)/.local
  46. vardir := $(home)/.var
  47. bindir := $(localdir)/bin
  48. directories := $(dotfiles_dir) $(home) $(localdir) $(vardir) $(bindir) \
  49. $(home)/.emacs.d
  50. current := $(shell date)
  51. uname := $(shell uname)
  52. shrc_loadables := sh bash zsh
  53. emacs ?= $(shell which emacs 2>/dev/null)
  54. git ?= $(shell which git 2>/dev/null)
  55. curl ?= $(shell which curl 2>/dev/null)
  56. grep ?= GREP_OPTIONS= $(shell which grep 2>/dev/null)
  57. files := Makefile emacs.el profile shrc tmux.conf vimrc _keysnail.js
  58. # Targets
  59. all: default
  60. tests := test-el
  61. test: test-syntax $(tests)
  62. test_syntaxes := test-syntax-el test-syntax-sh
  63. test-syntax: $(test_syntaxes)
  64. setups := setup-darwin setup-directories setup-emacs setup-gitconf \
  65. setup-repository setup-util setup-rc
  66. # `make setup` to setup these all sounds to be too match
  67. setup-all: $(setups)
  68. runs := run-emacs run-bash run-zsh
  69. # `make check` is just an alias for `make test`
  70. check: test
  71. # Similarly, check-syntax is test-syntax
  72. check-syntax: test-syntax
  73. .PHONY: all default clean \
  74. test check $(tests) \
  75. test-syntax check-syntax $(test_syntaxes)\
  76. setup-all $(setups)
  77. $(directories):
  78. test -d "$@" || mkdir -vp "$@"
  79. # System detection
  80. # ================
  81. # Is this usefull? Just checking uname is not enough?
  82. ismsys :=
  83. iscygwin :=
  84. iswindows :=
  85. isdarwin :=
  86. isfreebsd :=
  87. isbsd :=
  88. islinux :=
  89. ifneq (,$(findstring MINGW,$(uname)))
  90. ismsys := t
  91. endif
  92. ifneq (,$(findstring CYGWIN,$(uname)))
  93. iscygwin := t
  94. endif
  95. ifneq (,$(ismsys)$(iscygwin))
  96. iswindows := t
  97. endif
  98. ifneq (,$(findstring Darwin,$(uname)))
  99. isdarwin := t
  100. endif
  101. ifneq (,$(findstring FreeBSD,$(uname)))
  102. isfreebsd := t
  103. endif
  104. ifneq (,$(isdarwin)$(isfreebsd))
  105. isbsd := t
  106. endif
  107. ifneq (,$(findstring Linux,$(uname)))
  108. islinux := t
  109. endif
  110. # Clean
  111. # =====
  112. # Usage: Define a target as a dependency for clean and .PHONY
  113. clean: clean-home
  114. .PHONY: clean-home
  115. clean-home:
  116. $(RM) -r $(dotfiles_home_dir)
  117. # preparing files
  118. # ===============
  119. files_fullpath := $(files:%=$(dotfiles_dir)/%)
  120. fetch_files := $(files:%=fetch-%)
  121. .PHONY: $(fetch_files)
  122. $(fetch_files): fetch-%: $(dotfiles_dir)
  123. curl --url $(dotfiles_url_base)/$* --output $@
  124. ifeq (,$(use_git))
  125. $(files_fullpath): $(dotfiles_dir)/%: fetch-%
  126. $(warning 'use_git' is empty. Use curl to fetch files)
  127. else
  128. $(warning 'use_git' is not empty. Use git to retrieve files)
  129. $(files_fullpath): setup-repository
  130. test -f "$@"
  131. endif
  132. # setups
  133. # ======
  134. # setup git repository
  135. # --------------------
  136. setup-repository: $(dotfiles_dir)/.git
  137. $(dotfiles_dir)/.git:
  138. ifeq (,$(git))
  139. false "Git not installed"
  140. endif
  141. $(git) clone $(dotfiles_git) $(dotfiles_dir)
  142. # utils
  143. # -----
  144. setup_utils := colortable16.sh 256colors2.pl pacapt ack-2.12
  145. setup-util: $(setup_utils)
  146. .PHONY: $(setup_utils)
  147. setup_utils_path := $(setup_utils:%=$(bindir)/%)
  148. $(setup_utils): %: $(bindir)/%
  149. $(setup_utils_path): $(bindir)
  150. $(curl) -L --url "$(util_url)" --output "$@"
  151. chmod +x "$@"
  152. colortable16.sh: \
  153. util_url := https://gist.github.com/10sr/6852317/raw/colortable16.sh
  154. 256colors2.pl: util_url := https://gist.github.com/10sr/6852331/raw/256colors2.pl
  155. pacapt: util_url := https://github.com/icy/pacapt/raw/ng/pacapt
  156. ack-2.12: util_url := http://beyondgrep.com/ack-2.12-single-file
  157. # darwin setup
  158. # ------------
  159. setup_darwins := setup-darwin-defaults setup-darwin-daemon
  160. setup-darwin: $(setup_darwins)
  161. .PHONY: $(setup_darwins)
  162. setup-darwin-defaults:
  163. # http://appdrill.net/60641/mac-boot-mute.html
  164. #sudo nvram SystemAudioVolume=%80
  165. # add quit entry in menu
  166. defaults write com.apple.finder QuitMenuItem -bool YES
  167. # show full path on titlebar
  168. defaults write com.apple.finder _FXShowPosixPathInTitle -bool YES
  169. # do not show desktop icons
  170. defaults write com.apple.finder CreateDesktop -boolean false
  171. killall Finder
  172. # disable dashboard
  173. #defaults write com.apple.dashboard mcx-disabled -bool YES
  174. setup-darwin-daemon:
  175. test "`launchctl getenv LC_ALL`" = C || sudo launchctl setenv LC_ALL C
  176. if ! (launchctl list | grep com.apple.locate) >/dev/null ;\
  177. then \
  178. sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist ;\
  179. fi
  180. # emacs setup
  181. # -----------
  182. setup-emacs: $(dotfiles_dir)/emacs.el
  183. $(emacs) -q --batch \
  184. --eval "(setq user-emacs-directory \"$(home)/.emacs.d/\")" \
  185. --load $< \
  186. -f my-auto-install-package
  187. # git config setup
  188. # ----------------
  189. ifneq (,$(git))
  190. git_conf := $(git) config --global
  191. endif
  192. xz := $(shell which xz 2>/dev/null)
  193. setup-gitconf:
  194. ifeq (,$(git))
  195. $(warnning "Git program not found")
  196. else
  197. $(git_conf) user.name '10sr'
  198. $(git_conf) user.email '8slashes+git@gmail.com'
  199. $(git_conf) core.autocrlf false
  200. $(git_conf) core.excludesfile '~/.gitignore'
  201. $(git_conf) color.ui auto
  202. $(git_conf) status.relativePaths false
  203. $(git_conf) status.showUntrackedFiles normal
  204. $(git_conf) log.date iso
  205. $(git_conf) push.default current
  206. ifneq (,$(xz))
  207. $(git_conf) tar.txz.command "xz -c"
  208. endif
  209. $(git_conf) alias.graph "log --graph --date-order -C -M --pretty=tformat:\"%C(green)%h%C(reset) %C(white)%ad%C(reset) %C(red)%an%C(reset)%C(yellow)%d%C(reset) %C(white bold)%s%C(reset)\" --date=short -n 499"
  210. $(git_conf) alias.st "status -s -b"
  211. $(git_conf) alias.b "branch"
  212. $(git_conf) alias.sb "show-branch"
  213. $(git_conf) alias.ci "commit --verbose"
  214. $(git_conf) alias.co "checkout"
  215. $(git_conf) alias.cim "commit --verbose -m"
  216. $(git_conf) alias.di "diff --color"
  217. $(git_conf) alias.me "merge --no-ff --stat --verbose"
  218. $(git_conf) alias.ffme "merge --ff-only --stat --verbose"
  219. $(git_conf) alias.gr "grep -n"
  220. $(git_conf) alias.ls "ls-files"
  221. # $(git_conf) alias.ls "ls-files -v --full-name"
  222. # $(git_conf) alias.ls "status -u -s ."
  223. $(git_conf) alias.sl "!sl"
  224. # $(git_conf) alias.my-ls "ls-files | xargs ls"
  225. # $(git_conf) alias.ll "!git ls-files | xargs ls -l -CFG --color=auto --time-style=long-iso"
  226. $(git_conf) alias.addi "add -i"
  227. # Add patch to index
  228. $(git_conf) alias.ap "apply --cached"
  229. $(git_conf) alias.clean-p "diff --quiet"
  230. $(git_conf) alias.echo-ref "for-each-ref --format='%(refname:short)'"
  231. $(git_conf) alias.todo "grep -nH -E -i 'todo:|note:|fixme:'"
  232. $(git_conf) alias.stashsnap '! gitdir="`git rev-parse --git-dir`" && : >>"$$gitdir"/logs/refs/snapshot && cmt=`git stash create` && test -n "$$cmt" && git update-ref refs/snapshot $$cmt && echo Snapshot created: $$cmt'
  233. $(git_conf) alias.snap '! gitdir="`git rev-parse --git-dir`" && export GIT_INDEX_FILE="$$gitdir"/snapshot.index && cp "$$gitdir"/index "$$GIT_INDEX_FILE" && git add -A && : >>"$$gitdir"/logs/refs/snapshot && git update-ref refs/snapshot $$(git commit-tree $$(git write-tree) -m Snapshot -p HEAD) && git show --stat snapshot'
  234. $(git_conf) alias.setcmd '! f(){ git config alias.$$1 "! $$2"; }; f'
  235. #$(git_conf) alias.wc "!git ls-files -z | xargs -0 wc"
  236. # $(git_conf) push.default "simple"
  237. ifneq (,$(iswindows))
  238. $(git_conf) core.fileMode false
  239. endif
  240. endif
  241. # setup rc files
  242. # --------------
  243. # Generate load codes from the files themselves.
  244. # Load codes are defined by following SETUP_LOAD: indicator.
  245. # String DOTFILES_DIR in the load codes will be replaced into the value of
  246. # $(dotfiles_dir).
  247. # The load codes are appended to $(topfile).
  248. setup_rcs := setup-rc-vimrc setup-rc-tmux.conf setup-rc-emacs.el
  249. setup-rc: $(setup_rcs)
  250. .PHONY: $(setup_rcs)
  251. setup-rc-vimrc: $(home)/.vimrc
  252. setup-rc-tmux.conf: $(home)/.tmux.conf
  253. setup-rc-emacs.el: $(home)/.emacs.d/init.el
  254. $(home)/.emacs.d/init.el: $(dotfiles_dir)/emacs.el $(home) $(home)/.emacs.d
  255. $(home)/.vimrc: $(dotfiles_dir)/vimrc $(home)
  256. $(home)/.tmux.conf: $(dotfiles_dir)/tmux.conf $(home)
  257. command_extract_setup_load := $(grep) -e 'SETUP_LOAD: ' | \
  258. sed -e 's/^.*SETUP_LOAD: //' -e 's|DOTFILES_DIR|$(dotfiles_dir)|'
  259. setup_rc_marker := ADDED BY 10sr_dotfiles/Makefile
  260. $(home)/.emacs.d/init.el $(home)/.vimrc $(home)/.tmux.conf:
  261. set -x; if ! $(grep) "$(setup_rc_marker)" "$@"; \
  262. then \
  263. (echo '$(line_comment)' $(setup_rc_marker); cat "$<" | $(command_extract_setup_load)) \
  264. | tee -a "$@"; \
  265. fi
  266. $(home)/.emacs.d/init.el: line_comment := ;;
  267. $(home)/.vimrc: line_comment := \"
  268. $(home)/.tmux.conf: line_comment := \#
  269. # run
  270. # ===
  271. run-emacs: $(home)/.emacs.d/init.el
  272. $(emacs) -q \
  273. --eval "(setq user-emacs-directory \"$(home)/.emacs.d/\")" --load "$<"
  274. # test
  275. # ====
  276. test_els := test-el-emacs.el
  277. test-el: $(test_els)
  278. .PHONY: $(test_els)
  279. $(test_els): test-el-%: $(dotfiles_dir)/% $(home)
  280. $(emacs) -Q -batch -f batch-byte-compile $<
  281. EMACS_EL_DRY_RUN=t $(emacs) -q --debug-init --batch \
  282. --eval "(setq debug-on-error t)" \
  283. --eval "(setq user-emacs-directory \"$(home)/.emacs.d/\")" \
  284. --load $<c --kill
  285. # test syntax
  286. # ===========
  287. test_syntax_shs := test-syntax-shrc test-syntax-profile \
  288. test-syntax-xinitrc test-syntax-xprograms
  289. test-syntax-sh: $(test_syntax_shs)
  290. .PHONY: $(test_syntax_shs)
  291. $(test_syntax_shs): test-syntax-%: $(dotfiles_dir)/%
  292. sh -ec 'for sh in $(shrc_loadables); do $$sh -n $<; done'
  293. test_syntax_els := test-syntax-emacs.el
  294. test-syntax-el: $(test_syntax_els)
  295. .PHONY: $(test_syntax_els)
  296. sexp_elisp_syntax_check := \
  297. (with-temp-buffer \
  298. (emacs-lisp-mode) \
  299. (insert-file-contents file) \
  300. (condition-case err \
  301. (check-parens) \
  302. (user-error \
  303. (error (format "%s:%d:%d:Unmatched brancet or quote" \
  304. file \
  305. (line-number-at-pos) \
  306. (- (point) (point-at-bol)))))))
  307. $(test_syntax_els): test-syntax-%: $(dotfiles_dir)/%
  308. $(emacs) -Q --debug-init --batch \
  309. --eval '(let ((file "$<")) $(sexp_elisp_syntax_check))' --kill