Clean Craftsmanshipを読んだ
仕事から家に帰ったとき、鏡に映った自分を見て「今日はいい仕事をした」と言うだろうか?それとも、すぐにシャワーを浴びるだろうか?
あまりにも多くの人たちが、一日の終わりに心残りを感じている。あまりにも多くの人たちが、標準以下の仕事をしていると感じている。あまりにも多くの人たちが、品質を犠牲にして速度が求められていると感じている。あまりにも多くの人たちが、生産性と品質は反比例すると考えている。
本書では、そうした考え方を打ち破る。本書はより良く働くための本だ。良い仕事をするための本だ。 仕事を速くして、生産性を高め、毎日自分が書いたものに誇りが持てるように、すべてのプログラマーが知るべき規律とプラクティスについて書いた本だ。 (p. 18「はじめに」)
2度目の『Clean Craftsmanship』を読み終えた。1度目は読書会に参加する形で、今回はチームの読書会を主導する形で読んだ。自身の普段の仕事に対するものの見方を後押ししてくれた。端的に、勇気を与えられた。 本書を読む前は、漠然とした「私は正しいことをやっているのか」という迷いが多くあったが、迷いが減り、目前の仕事に集中できるようになり、自らの仕事に自信が持てるようになった。この効用は大きい。
他のCleanシリーズ、『Clean Architecture』や『Clean Code』に比べて知名度が低いように思うが、本書を読む人が増えてくれると嬉しい。
サブタイトルに「規律、基準、倫理」とある通り、本書のよいところは、社会に生きる職業人のプログラマとして持つべき考えについて述べている点にある。類似書に『達人プログラマー』や『チーム・ギーク』などがあるが、プログラマーの社会的・歴史的位置づけについて書かれた本は他にはないのではないだろうか。 倫理や社会と聞くと警戒する人もいるかもしれないが、押し付けがましい説教を延々聞かされるのではないので安心してほしい。
訳者あとがきにもあるように、「過去の著作から大事なことが抜粋されてまとめられているため、大変オトクなパッケージにもなっている」。他のCleanシリーズや類書で見覚えのある話が多々現れる。
- テスト駆動開発
- 基礎、なぜTDDなのか
- ドキュメンテーションや設計との関係性
- テストの効果
- テストの壊れやすさ
- 不確定性問題
- データベースやGUIのテスト
- 高速なテスト
- アーキテクチャの境界線
- リファクタリング
- シンプルな設計
- YAGNI
- 偶然の重複
- 協力的プログラミング
- 継続的ビルド
- などなど
ソフトウェア・テストの技法や考え方に注目して言えば、『単体テストの考え方/使い方』が理解を助けてくれると思う。重複する部分も大いにあるが、この2冊を読むことで習熟度がぐんと上がると思う。プラクティスや、物事をうまくやるための基本的な考えかたに注目して言えば、『エクストリーム・プログラミング』を併読するのがよいだろうと思う。
大変オトクなパッケージであると同時に、人類史の参照もありがたい。
- 航空機開発と事故の歴史
- 手洗い法(センメルヴェイス・イグナーツ)
- 複式簿記(ガイウス・プリニウス・セクンドゥス)
- ナイト・キャピタル・グループの事例
- HealthCare.govの事例
- など
当然、コンピューターやプログラマーに関する歴史にも触れている。
第2章から第5章(p.41〜p.207)はテスト駆動開発とリファクタリングの実践が主である。ミーティングツールの音声をオンにして、チームメンバーとワイワイそれぞれ好きな言語で実装するのは楽しいし、テスト駆動開発の威力が体感できるいいワークショップになると思う。ただ、それなりに時間がかかる。ちなみに、私は1度目はDeno、2度目はJavaで実装した。
Cleanシリーズを読んだことのある人にはお分かりかもしれないが、相変わらず語気は若干強めで、読了後の感想戦でもちらほらとそういった感想があった。筆者のスタイルに調子をアジャストして読むのはよくある読書スキルであるし、「はじめに」で著者もこう書いている。
本書を読むと、これこそが「クラフトマンに到達するたったひとつの道」だと感じるかもしれない。だが、私にとってはそうであっても、あなたにとっては必ずしもそうではないかもしれない。本書はあくまでも私の道を示したものだ。あなたには、もちろん、あなた自身の道を選択する必要がある。
とはいえ、TDDに対する姿勢については、人によっては解説が必要かもしれない。例えば、テストのカバレッジについて第6章で以下のように記している。
カバレッジの数値はいくつにすべきだろうか?80%だろうか?それとも90%?多くのチームがそのような数値を満足気に報告している。だが、さきほどの60年前の論文の答えは違う。彼らの答えは「100%」である。
TDDには諸派あり、必ずしもテストファーストのアプローチを取らなかったり、カバレッジをどの程度重視するかなど、グラデーションがある。私は、テストファーストのアプローチを取ることが少ないし、カバレッジをさほど重視しない。コストパフォーマンスのバランス重視であるといえる。そのために、100%を漸近的な目標として掲げることには懐疑的だ。このように書いてあること全てを信じる必要はないのである。
(…が、ミューテーション・テストの効果を再発見したり、「1対1の対応関係」を「対応関係の解消」する様子を見ていると、100%を目指すのが正解のようにも思えて来るし、単体テストをよりテストサイズの大きな領域に移行することを考えると、逆に不正解のようにも思えてくる。)
TDDの諸流派の話については、fukabori.fmの114回でt-wadaさんが詳しく述べられている。
Hello, blogsync
yo yo yo yo yo
see: github.com
macOS Mojave で gdb を動かす(2020年10月)
2017年6月発表の macOS High Sierra(10.13)から SIP(System Integrity Protection: システム整合性保護)が導入され、gdb
が動かなくなりました。過去には SIP 自体を無効化しなければなりませんでしたが、どうも最近ではそこそこ妥当な対処方法が取れるようになったようです。
困った話なので様々な対処方法がネットにありますが、現状にマッチした情報が見つかりませんでしたので、私の環境で動作した方法を書き記しておきます。 support.apple.com
対処方法
対処方法の手順はざっくり4つです。ポイントは SIP の無効化(csutil disable
)や一部無効化(csutil enable --without=debug
)しなくても動くという点です。
~/.gdbinit
にset startup-with-shell off
を書く- Code Signing Certificate を作る(
Keychain\ Access.app
) --entitlements
付きでgdb
にcodesign
するtaskgated
を殺す
動かすもの
今回動かすものはこちらの解説記事のものをそのまま使わせていただきました。 rat.cis.k.hosei.ac.jp
再現手順は以下の通りです。
$ gcc -g -O0 bubblesort.c $ gdb a.out GNU gdb (GDB) 10.1 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-apple-darwin19.6.0". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from a.out... Reading symbols from /private/tmp/gdb/a.out.dSYM/Contents/Resources/DWARF/a.out... (gdb) break main Breakpoint 1 at 0x100003db8: file bubblesort.c, line 9. (gdb) run Starting program: /private/tmp/gdb/a.out Unable to find Mach task port for process-id 8203: (os/kern) failure (0x5). (please check gdb is codesigned - see taskgated(8)) (gdb) quit
1. ~/.gdbinit
に set startup-with-shell off
を書く
brew install gdb
時にもメッセージが出る通り、~/.gdbinit
に set startup-with-shell off
の記述が必要です。
これがないとコード署名の問題が解消しても During startup program terminated with signal SIGTRAP, Trace/breakpoint trap.
が発生するようです。
2. Code Signing Certificate を作る
Keychain Access
を使って Code Signing Certificate を作ります。
- Keychain Access を開きます
- メニューから「Keychain Access > Certificate Assistant > Create a certificate」を選びます
Create Your Certificate
を設定しますName
はgdb
とします。この名前を後のコマンドで指定することになります。Identity Type
にSelf Signed Root
を選択しますCertificate Type
にCode Signing
を選択しますLet me override defaults
にチェックを入れます
Certificate Information
を設定しますValidity Period (days)
はデフォルト1年ですが10年程度に設定しておくとよいと思います
Key Pair Information
を設定します- デフォルト選択肢のままでも動くようですが、念のため
Key Size
を512 bits
、Algorithm
をECC
にしておくとよいと思います
- デフォルト選択肢のままでも動くようですが、念のため
- しばらく
Continue
で飛ばします Specify a Location for The Certificate
を設定しますKeychain
をSystem
に設定します
Conclusion
Your certificate has been successfully created.
と表示されます- 作成された証明書の内容を確認してみてください
- 一覧から作成された証明書(Name = gdb, Kind = certificate)をダブルクリックして詳細を開きます
Trust
の三角矢印をクリックして開き、When using this certificate
をAlways Trust
に設定します- この手順は不要かもしれません
3. --entitlements
付きで gdb
に codesign
する
以下の内容の gdb.xml
を作ります。何度も使うものではないので適当な場所に作成してよいと思います。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.cs.debugger</key> <true/> </dict> </plist>
com.apple.security.cs.debugger
という設定項目自体は、公式のドキュメントによると Availability は macOS 10.7+ とのことです。
developer.apple.com
codesign
の状態を確認します
$ codesign -vv $(which gdb) /usr/local/bin/gdb: code object is not signed at all In architecture: x86_64
gdb
に --entitlements
を指定して codesign
します。このとき、-fs
の引数に Keychain Access に登録したときの名前を指定します。
$ codesign --entitlements gdb.xml -fs gdb $(which gdb)
成功するとこのようになります
$ codesign -vv $(which gdb) /usr/local/bin/gdb: valid on disk /usr/local/bin/gdb: satisfies its Designated Requirement
4. taskgated
を殺す
OS を再起動するか taskgated
を殺して Code Sign を有効化します。
$ sudo pkill taskgated Password:
しばらく待たないと以下のようにスレッドを立ち上げた所でハングするかもしれません。
Reading symbols from a.out... Reading symbols from /private/tmp/gdb/a.out.dSYM/Contents/Resources/DWARF/a.out... (gdb) break main Breakpoint 1 at 0x100003db8: file bubblesort.c, line 9. (gdb) run Starting program: /private/tmp/gdb/a.out [New Thread 0x2503 of process 8351] [New Thread 0x2103 of process 8351]
動作確認
冒頭の再現手順を試します。期待通り動作しました。
Reading symbols from a.out... Reading symbols from /private/tmp/gdb/a.out.dSYM/Contents/Resources/DWARF/a.out... (gdb) break main Breakpoint 1 at 0x100003db8: file bubblesort.c, line 9. (gdb) run Starting program: /private/tmp/gdb/a.out [New Thread 0x1d03 of process 8511] [New Thread 0x1f03 of process 8511] warning: unhandled dyld version (16) Thread 2 hit Breakpoint 1, main (argc=1, argv=0x7ffeefbff3f0) at bubblesort.c:9 9 int array[4] = {4, 1, 3, 2}; (gdb)
動作環境情報
- macOS Catalina (10.15.7)
$ gdb --version GNU gdb (GDB) 10.1 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
$ gcc --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1 Apple clang version 12.0.0 (clang-1200.0.32.21) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
$ csrutil status System Integrity Protection status: enabled.
この記事の内容を含むリポジトリです。こちらも参考にどうぞ。 github.com
参考
- https://gist.github.com/gravitylow/fb595186ce6068537a6e9da6d8b5b96d
- https://daisuzu.hatenablog.com/entry/2019/04/13/190018
- http://asamomiji.jp/contents/fix-the-phenomenon-that-hangs-in-macos-mojave-eclipse-gdb
- https://sira.dev/2019/09/17/macos-gdb-codesign.html
- https://leico.github.io/TechnicalNote/Mac/csrutil
- https://www.gnu.org/software/gdb/news/
- https://intellij-support.jetbrains.com/hc/en-us/articles/206556469-What-compiler-debugger-can-I-use-within-CLion-
- https://gist.github.com/gravitylow/fb595186ce6068537a6e9da6d8b5b96d
HomeBrew で Custom Build from Source する
最近ソースコードをビルドする機会が増えてきて、ホストOS上で常用するツールについては少し管理できた方がよさそうということで、HomeBrew で Build from Source を試しています。
例えば vim
の clientserver
オプションを有効化したい、とかが brew install
でできるようになります(まだできていない)。
HomeBrew は独特の世界観があってか[?] 情報が少ないからなのか少し混乱しましたが、慣れればまあ使えるんじゃないかと思います。 慣れれば自作のソフトウェアを配布する敷居が下がったり、macOS を使っている人の環境向上に寄与できていいんじゃないでしょうか。知らんけど。
Tap を作る
まずは Tap を作ります。Tap とは A Git repository of Formulae and/or commands
らしいです。
Formula は *.rb
になっている The package definition
、つまり vim
git
make
とかです。
HomeBrew の用語はこちら(Keg、Cellar、Cask など)。 docs.brew.sh
リポジトリの名前を考えます。tamakiii/homebrew-core
は本家の homebrew/homebrew-core
と競合する(本家に Pull Request を送りたいときに困る)ので tamakiii/homebrew-tap
とします。
$ brew tap-new tamakiii/homebrew-tap Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap/.git/ [master (root-commit) 390ec63] Create tamakiii/tap tap 3 files changed, 85 insertions(+) create mode 100644 .github/workflows/publish.yml create mode 100644 .github/workflows/tests.yml create mode 100644 README.md ==> Created tamakiii/tap /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap When a pull request making changes to a formula (or formulae) becomes green (all checks passed), then you can publish the built bottles. To do so, label your PR as `pr-pull` and the workflow will be triggered.
作った Tap がこちら。README と Formula/
.github/workflows
があるだけの簡単な構成です。
名前の homebrew-
部分は省略できるようです。
$ ls -lsa /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap total 8 0 drwxrwxr-x 6 tamakiii admin 192 10 28 19:23 . 0 drwxrwxr-x 4 tamakiii admin 128 10 28 19:23 .. 0 drwxrwxr-x 12 tamakiii admin 384 10 28 19:28 .git 0 drwxrwxr-x 3 tamakiii admin 96 10 28 19:23 .github 0 drwxrwxr-x 3 tamakiii admin 96 10 28 19:27 Formula 8 -rw-rw-r-- 1 tamakiii admin 254 10 28 19:23 README.md $ brew --repo tamakiii/tap /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap $ brew --repo tamakiii/homebrew-tap /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap
ビルドしてみる
試しに本家の vim.rb
を入れてみます。
$ cp /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/vim.rb Formula/
コピーした中身はこちら。依存関係やインストールコマンド本体、テストなどがあり、単体の Ruby ファイルで完結して動きます。 github.com
追加した vim
Formula は、<tap-name>/<formula-name>
で指定できます。
$ brew info tamakiii/tap/vim tamakiii/tap/vim: stable 8.2.1900 (bottled), HEAD Vi 'workalike' with many additional features https://www.vim.org/ Conflicts with: ex-vi (because vim and ex-vi both install bin/ex and bin/view) macvim (because vim and macvim both install vi* binaries) /usr/local/Cellar/vim/8.2.1900 (1,953 files, 33.3MB) * Built from source on 2020-10-28 at 19:29:45 From: https://github.com/tamakiii/homebrew-tap/blob/HEAD/Formula/vim.rb License: Vim ==> Dependencies Required: gettext ✔, lua ✔, perl ✔, python@3.9 ✔, ruby ✔ ==> Options --HEAD Install HEAD version ==> Analytics install: 83,045 (30 days), 238,945 (90 days), 873,774 (365 days) install-on-request: 80,611 (30 days), 231,601 (90 days), 835,450 (365 days) build-error: 0 (30 days)
ビルド出来ました。Bottle が落とせなくて怒られていますが今回は気にしなくてよさそうです。
$ brew install tamakiii/tap/vim Updating Homebrew... Warning: tamakiii/tap/vim 8.2.1900 is already installed and up-to-date To reinstall 8.2.1900, run `brew reinstall vim` $ brew reinstall tamakiii/tap/vim ==> Downloading https://homebrew.bintray.com/bottles-tap/vim-8.2.1900.catalina.bottle.tar.gz ##O=# # curl: (22) The requested URL returned error: 404 Not Found Error: Failed to download resource "vim" Download failed: https://homebrew.bintray.com/bottles-tap/vim-8.2.1900.catalina.bottle.tar.gz Warning: Bottle installation failed: building from source. ==> Downloading https://github.com/vim/vim/archive/v8.2.1900.tar.gz Already downloaded: /Users/tamakiii/Library/Caches/Homebrew/downloads/094d05292a53960f72fae76726aee6cb028b92fbdabc0eb56191a4308b5f8821--vim-8.2.1900.tar.gz ==> Reinstalling tamakiii/tap/vim Warning: A newer Command Line Tools release is available. Update them from Software Update in System Preferences or run: softwareupdate --all --install --force If that doesn't show you an update run: sudo rm -rf /Library/Developer/CommandLineTools sudo xcode-select --install Alternatively, manually download them from: https://developer.apple.com/download/more/. ==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.2.1900/share/man --enable-multibyte --with-tlib=ncurses --with-compiledby=Homebrew --enable-csco ==> make ==> make install prefix=/usr/local/Cellar/vim/8.2.1900 STRIP=/usr/bin/true 🍺 /usr/local/Cellar/vim/8.2.1900: 1,953 files, 33.3MB, built in 1 minute 27 seconds
vim
Formula には Bottle がないのでこれで良いですが、設定されているものには --build-from-source
をつける必要がありそうです。せいぜい数台のマシンで動かすものなので Bottle の記述は削るとよさそうです。
また、./configure
や make
の出力がほしいところなので --verbose
をつけるとよさそうです。 --debug
はちょっとうるさかったのでやめました。
$ brew reinstall --force --verbose --build-from-source tamakiii/tap/vim rm /usr/local/bin/ex rm /usr/local/bin/rview rm /usr/local/bin/rvim rm /usr/local/bin/vi rm /usr/local/bin/view rm /usr/local/bin/vim ... /usr/bin/sandbox-exec -f /private/tmp/homebrew20201028-85925-14282ki.sb nice ruby -W0 -I $LOAD_PATH -- /usr/local/Homebrew/Library/Homebrew/build.rb /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap/Formula/vim.rb --verbose tar xof /Users/tamakiii/Library/Caches/Homebrew/downloads/094d05292a53960f72fae76726aee6cb028b92fbdabc0eb56191a4308b5f8821--vim-8.2.1900.tar.gz -C /private/tmp/d20201028-85926-10g8sdh cp -pR /private/tmp/d20201028-85926-10g8sdh/vim-8.2.1900/. /private/tmp/vim-20201028-85926-1g5a3uf/vim-8.2.1900 chmod -Rf +w /private/tmp/d20201028-85926-10g8sdh ==> ./configure --prefix=/usr/local --mandir=/usr/local/Cellar/vim/8.2.1900/share/man --enable-multibyte --with-tlib=ncurses --with-compiledby=Homebrew --enable-cscope --enable-terminal --enable-perlinterp --enable-rubyinterp --enable-python3interp --enable-gui=no --without-x --enable-luainterp --with-lua-prefix=/usr/local/opt/lua --enable-fail-if-missing configure: creating cache auto/config.cache checking whether make sets $(MAKE)... yes checking for gcc... clang checking whether the C compiler works... yes checking for C compiler default output file name... a.out ... /usr/bin/sandbox-exec -f /private/tmp/homebrew20201028-92467-f57b26.sb nice ruby -W0 -I $LOAD_PATH -- /usr/local/Homebrew/Library/Homebrew/postinstall.rb /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-tap/Formula/vim.rb ==> Summary 🍺 /usr/local/Cellar/vim/8.2.1900: 1,953 files, 33.3MB, built in 1 minute 45 seconds
homebrew/homebrew-core の場合
homebrew/homebrew-core
自体も HomeBrew 的には Tap の扱いになっているようです。
$ tree -L 2 /usr/local/Homebrew/Library/Taps /usr/local/Homebrew/Library/Taps ├── homebrew │ ├── homebrew-brewdler │ ├── homebrew-bundle │ ├── homebrew-cask │ ├── homebrew-cask-versions │ ├── homebrew-core │ └── homebrew-services ├── osx-cross │ ├── homebrew-arm │ └── homebrew-avr ├── qmk │ └── homebrew-qmk └── tamakiii ├── homebrew-core └── homebrew-tap 15 directories, 0 files
homebrew/homebrew-core
にコミットしたい場合も、GitHub 上でリポジトリを Fork して tap すれば、自分用の Tap と同様に、変更・ビルド・Pull Request の作成ができそうです。
$ brew tap tamakiii/homebrew-core Updating Homebrew... ==> Auto-updated Homebrew! Updated 1 tap (homebrew/cask). ==> Updated Casks logos rotki springtoolsuite switchhosts wechatwebdevtools $ brew --repo tamakiii/homebrew-core /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-core $ ls -lsa /usr/local/Homebrew/Library/Taps/tamakiii/homebrew-core total 48 0 drwxrwxr-x 13 tamakiii admin 416 10 28 16:03 . 0 drwxrwxr-x 4 tamakiii admin 128 10 28 19:23 .. 0 drwxrwxr-x 14 tamakiii admin 448 10 28 16:56 .git 0 drwxrwxr-x 8 tamakiii admin 256 10 28 16:03 .github 0 drwxrwxr-x 238 tamakiii admin 7616 10 28 16:03 Aliases 8 -rw-rw-r-- 1 tamakiii admin 884 10 28 16:03 CODEOWNERS 8 -rw-rw-r-- 1 tamakiii admin 2960 10 28 16:03 CONTRIBUTING.md 0 drwxrwxr-x 5313 tamakiii admin 170016 10 28 18:19 Formula 8 -rw-rw-r-- 1 tamakiii admin 1334 10 28 16:03 LICENSE.txt 8 -rw-rw-r-- 1 tamakiii admin 706 10 28 16:03 README.md 0 drwxrwxr-x 4 tamakiii admin 128 10 28 16:03 cmd 8 -rw-rw-r-- 1 tamakiii admin 3567 10 28 16:03 formula_renames.json 8 -rw-rw-r-- 1 tamakiii admin 1144 10 28 16:03 tap_migrations.json
自作のソフトウェアを配布したい場合には Formula をインタラクティブに作る機能も用意されているようです。 gabecc.me
バージョンロックの仕組みがイマイチ使いにくかったりで少し思う所もある HomeBrew ですが、今日も多くの人に使われているツールではあるはずです。 昔ほど Formula が壊れることもほぼなくなった気がしますし、相当なゲームチェンジャーが表れない限りは当面現役なんじゃないかと思います。
また make の話してる(2020年9月14日)
私の大好きな Makefile の話が盛り上がっていたのでまとめました。 「やめてね。」って方はお声がけください。
同じ会社にいるけど、真逆の感想を持っている。Makefile読まないと副作用が分からないし、Rakefile/package.jsonだけで済むのに無駄に1つレイヤ増えていて、Makefileできたときからいる人は楽だけど、途中から入った人にとっては学習コストが高い。 https://t.co/EXtmI3xl72
— 神速 (@sinsoku_listy) 2020年9月13日
golangでMakefileを使うのは分かる。
— 神速 (@sinsoku_listy) 2020年9月13日
ただ、RubyやNode.jsのリポジトリなら
$ git clone xxx
$ cd xxx
$ bundle install && rake もしくは npm install && npm test
で環境構築ができることを期待する。
個人的にはmake configureのないMakefileは使い方を間違っているのでは...と思っています。複雑なコマンドを短くするならシェルスクリプトを使う方が妥当で、Makefileを使うのは間違ったツール選定してる印象です。
— 神速 (@sinsoku_listy) 2020年9月13日
Makefileは何か成果物を作るときのフレームワークとしては便利なので、そういう用途で使うのは正しいかなと思います。OpenAPIのドキュメントを生成するのを、
— 神速 (@sinsoku_listy) 2020年9月13日
$ make configure
$ make
でyamlが生成されるとかなら、納得感がある。
社内だとMakefileがタスクランナーとして使われているのが標準みたいなところあるので、仕方がない...。個人的にはMakefile嫌いだけど、消すほどの納得力ある説明もできないので、放置してる感じですね。
— 神速 (@sinsoku_listy) 2020年9月13日
あー、なるほど...。たぶん神速さんとコンテキストあってないかもしれなくて、僕が複雑なMakefileに出会ってないだけかもです。(コマンドフルでベタ打ち環境→makeだったので、そもそも他との比較をできていない)
— 福本 晃之 | Teruhisa Fukumoto (@terry_i_) 2020年9月13日
あー、わたしも「なんでもmakeで」って文化苦手です…
— Hidenori Matsuki (@mazgi) 2020年9月13日
結局ああいうの「書いた人しかわからない」んですよね
ビルドシステムある言語はそれ使ってほしいし、Makefileのなかでdocker runしてるやつとか見たことあって「いやcomposeあるやろ」って思う
そもそも2020年に全環境でmake入ってると思わないし
Makefileの使い方メモ on @Qiita https://t.co/cqVsxPbgGW
— Captain Blue (@captain_blue210) 2020年9月13日
コマンド実行のインタフェースとしてのmakeは本当に優秀だと思う。
— saka (@gaplant_tr5) 2020年9月13日
makeからsbtとかnpm呼び出してるだけなんだけど、git clone した後にやることが、どのリポジトリでもmake叩けば環境できるようになってるっていうのは本当に楽だった。 https://t.co/Se5Jphyo8e
これめっちゃわかります...弊社もそうなってて、なんでも「make で起動」「make initで環境構築」でめちゃクソ楽だと感じた記憶。Makefile自体はC時代からあるもので、意外と歴史深いというのも結構意外でしたが。 https://t.co/c2vEOR3lKp
— 福本 晃之 | Teruhisa Fukumoto (@terry_i_) 2020年9月13日
Makefileの使い方メモ on @Qiita https://t.co/cqVsxPbgGW
— Captain Blue (@captain_blue210) 2020年9月13日
makefileテクニックはかなり邪悪手法にまで踏み込んだし、余り無いTIPS集になったんじゃないかな。今まで見たプロジェクトで一切使われてないけど便利なディレクティブを解説してるし。
— リザウド (@rizaudo) 2020年9月13日
あー、わたしも「なんでもmakeで」って文化苦手です…
— Hidenori Matsuki (@mazgi) 2020年9月13日
結局ああいうの「書いた人しかわからない」んですよね
ビルドシステムある言語はそれ使ってほしいし、Makefileのなかでdocker runしてるやつとか見たことあって「いやcomposeあるやろ」って思う
そもそも2020年に全環境でmake入ってると思わないし
Makefile 便利だと思う派だけど好きじゃないって人もいるんだな。気をつけよう。
— V (@voluntas) 2020年9月13日
うちの会社、エンジニアはOS何使ってもOKなので、環境構築に中々時間をかけることが多い。やれDockerが遅い、MakefileはWinじゃ動かない、.envファイルがなんかおかしい。なんかうまいこといかないもんかね?全環境一発で構築したいものなんだが。
— 🌱やまゆ (@akai_inu) 2020年9月13日
慣れれば慣れるほどmakeに頼りたくなってしまう罠みたいなものがある気がします。何故そうなってしまうのかはわかりませんが。
— ema (@ema_hiro) 2020年9月13日
(他人の書いたモリモリMakefile見てイラッとするのに、同じことを気付くと自分がしてしまっている...みたいな)
makefile、make が使えない環境だと使えないので不便
— バンビちゃん@実際クソザコメンタル (@pink_bangbi) 2020年9月13日
Makefileをbetter shell scriptとして使うの、何もまずいことなかろうに。
— Kazunori Otani (@katzchang) 2020年9月13日
readmeにコマンド書くくらいならmakefileにした方がいいくらい。
— Kazunori Otani (@katzchang) 2020年9月13日
makeはマクロの塊なので、用法容量を守ってお使いください
— Kazunori Otani (@katzchang) 2020年9月13日
makeでループと条件分岐をやりたくなったら地獄のはじまり… https://t.co/mEdb5ds5Ah
— Kazunori Otani (@katzchang) 2020年9月13日
ループはターゲットの列挙で書き直すと見た目はスッキリする。けど、情報密度が上がりすぎることもある。
— Kazunori Otani (@katzchang) 2020年9月13日
多言語を扱う上で、一番大事なのがmakeですよ。単一言語しか使わないのであれば、多分あまり必要ではない。
— Kazunori Otani (@katzchang) 2020年9月13日
なんか俺、make大好きなやつみたいじゃん…
— Kazunori Otani (@katzchang) 2020年9月13日
4年前の発表https://t.co/5xN6XaKCIZ
— Kazunori Otani (@katzchang) 2020年9月13日
Makefileをdocker build&pushのショートカットに使ってるけど、
— epaew (@epaew_dev) 2020年9月13日
buildの成果物(ファイル)に指定すべきものがよく分からないので、
buildとpushの依存関係を指定すべきなのか指定しないほうがいいのかずっと悩んでる
思い立ってググったら見つけた記事明日にでも読もうhttps://t.co/VEHblprsrg
— epaew (@epaew_dev) 2020年9月13日
便利 makefile 用意するよりも普通の shell スクリプトファイル用意するんじゃダメなんだろうか
— バンビちゃん@実際クソザコメンタル (@pink_bangbi) 2020年9月13日
makefile、複雑なやつだとエントリポイントがわからん。コマンドの前にpublicとかprivateとか書けたらいいのかな。タスクランナーとして使うなら。あとはWindowsに入っていれば。
— 渋川よしき (@shibu_jp) 2020年9月13日
まさにこのMakefileいじらないといけなくてブチギレそうになってるんだが????https://t.co/T7D7OfbkRs
— Yoshi Yamaguchi ⌨ Keyboard builder (@ymotongpoo) 2020年9月13日
Makeというのはシェルスクリプトを安全に巻き取る効用が強いんで、ぶっちゃけシェルスクリプトよりかはMakefileで頑張った方が良いよ
— リザウド (@rizaudo) 2020年9月13日
使われている言語が統一されていて、その言語特有のタスクランナーがみんなわかってる、みたいな状況であればそれ使えばいいだろうけど、いろんな技術を使っている状況だったり、これを動かすにはこれとこれと……みたいな感じだとまぁMakefile楽だしそのコンテキストが共有出来ればいいじゃん派です
— ちゅうこ (@y_chu5) 2020年9月13日
ちなみに元のスレッドの趣旨は要約すると「単なるスクリプトでできることをMakefileにするな」なので、それは100%同意。
— ryo①kato シリコンバレーの資格マニア (@ryo1kato) 2020年9月13日
Makefileは依存関係と更新時系列を調べて最小限コマンド(=差分ビルドを)を実行するツールなので、単に決まった手順するだけのことに使うべきじゃあないよね。
makefile便利だよ。自作ツールの実行方法メモしないでもmakefile読めばわかるもの
— Hideaki I (@hide5stm) 2020年9月13日
本来のmakeの使い方としてはファイルを作るような使い方が正しい。だが、タスクランナーとして便利やねん。goやrust(最近はcargo-makeか)あたりでもconfigureのないMakefileが使われてるし
— 武田あやな (@yowatari) 2020年9月13日
あるツールとあるツールの間を受け持つような使い方がmake使ってて好きだな。docker build してタスク定義jsonを生成して、ecspressoでデプロイするみたいなことが、シェルスクリプトよりMakefileのが完結に書けるし、それぞれを独立に実行することもできる
— 武田あやな (@yowatari) 2020年9月13日
make up, make update, make stop, make attach とかはいつもプロジェクトで使ってて、Makefile無い時や既にあるときはこれでOverrideしてるhttps://t.co/zMOYbnDphy
— iberianpig(Kohei Yamada) (@nukumaro22) 2020年9月13日
CIのYAMLにコマンド書き連ねてるんだったら、絶対Makefileのタスクにした方が良いよ
— songmu (@songmu) 2020年9月13日
makeの良い点の一つに「インストール不要」ってのがあって、プロジェクト入ってきた人が、どういうツールが必要か分からなくてもMakefileを見れば分かるし、そのセットアップが実行可能になっている(のが理想
— songmu (@songmu) 2020年9月13日
Makefileが嫌いっていうのは、自動生成されてたり、やりすぎたMakefileに苦しめられてきた人なんだろうな、と思う。
— songmu (@songmu) 2020年9月13日
僕もPerl界出身なので、Makefileってのは自動生成されるもので中身はよくわからないし読むものではないって思ってたけど、全然そんなことなかったんだよな。
— songmu (@songmu) 2020年9月13日
makeとシェルスクリプトでやれることは変わらないし、makeタスクが複雑になったらシェルスクリプトに切り出してMakefileからそれを呼び出せば良いだけの話だけど、タスクのインデックスとして提供されていることに意味がある。
— songmu (@songmu) 2020年9月13日
例えばtools/setup.shを叩けば開発環境が整うのだとしても、プロジェクトに入ってきた人はそんなことわからないので、Makefileに
— songmu (@songmu) 2020年9月13日
setup:
tools/setup.sh
って書いてあれば、make setupでセットアップできるってことがわかる。
ISUCONでも僕が適当なMakefileをリポジトリに突っ込んでおいたら、チームメイトが察してmake deployでガンガンdeployしてくれてたし、必要に応じて勝手に修正してくれて便利だった
— songmu (@songmu) 2020年9月13日
Makefileはむしろ単純だし、単純が故にむしろそれを自動生成させるというアプローチが流行ってしまったことがむしろ地獄の始まりだったのではないか
— songmu (@songmu) 2020年9月13日
(Makefile自体も複雑なことやろうとするととたんに意味不明になるというのもある
make本来のビルドシステムとしての利用用途を望むのであればmtimeに依存した仕組みは流石にそぐわない局面も多いので、今はBazelとかを使うべきでしょうね
— songmu (@songmu) 2020年9月13日
でも、npm devやnpm startでjs界隈も統一しようとしてるところを見ると、makefileが普段使いの言語で書けないという壁は思っているよりでかいのかもしれない。
— すぎちゃん (@koheiSG) 2020年9月13日
Makefile って例えば Vim とかのようなプロジェクトだとたしかに意味不明なんだけど、0から書き始めてみると難しいことなにもないんだよな。俺は CSV の前処理によく使ってた
— 生きてるだけで黒歴史 (@515hikaru) 2020年9月13日
Makefileとshellscriptが話題なので以前書いた記事をhttps://t.co/aM6R1drxwi
— そな太@GraphQLはいいぞ (@sonatard) 2020年9月13日
Makefileばなし何故か持ち上がってる、一番好きな並列処理記述言語です!!!!
— 精神のお墓 (@no_maddo) 2020年9月13日
Makefileは本来はファイルの依存関係を記述して効率的にコンパイルを行うためのものだけど、単純に人間とshellscriptを繋ぐインターフェースとして利用しても便利
— そな太@GraphQLはいいぞ (@sonatard) 2020年9月13日
Makefileの、依存関係でJOBの処理を解決していくというアプローチがたいへん汎用的なので未だにshell scriptをラップするのに便利なんだよな、、、
— 精神のお墓 (@no_maddo) 2020年9月13日
出力ファイルに依存関係があるとMakefileを使いたくなるんだよな。
— 生きてるだけで黒歴史 (@515hikaru) 2020年9月13日
ちょっとした自動化するときはMakefile書く
— 地下アイドル (@Untergrund_idol) 2020年9月13日
makefileはベンダーのサンプルコードそのまま流用とか使ってないマクロびっしり残しとくとか、そういうアグリーなのは本当に良くない。綺麗にしておかないとそれこそ技術的負債まっしぐら。
— kjm (@kj53192539) 2020年9月13日
Makefileは依存関係から「今足りてないもの」だけを紐解いて必要なことだけをする物なので、開発サイクルでは変更したファイルから再構築が必要なものを素早く最低限実行するのに常用してたな。シェルスクリプトとかで同じことやろうとするとだいぶ冗長になるね
— KOIZUKA, Akihiko (@koizuka) 2020年9月13日
Makefile, 最近は .PHONY なターゲットばかりで .PHONY が長い。。
— ymmt (@ymmt2005) 2020年9月13日
今日Makefileなpostをよく見かける。
— shinofara@MF KESSAI (@shinofara) 2020年9月13日
なんでもいいけど、マニュアルのシンプル化とLocalとCIなどで同じ事するなら手順の変更に対してeasyに対応できるといいな。
GNU Make や bash に依存すること自体は問題ないけども、shbang を /bin/sh にしたりせんでくれという所は強く主張したい。あとできれば Makefile じゃなくて GNUmakefile って名前にしてくれれば要らんストレスが減る
— きしもと (@ksmakoto) 2020年9月13日
当たり前だけどMakefileの中で何でもかんでも処理するんではなくて(複雑になってきたらscripts/とかまとめる事が多い)「そのプロジェクトで必要なタスクのリスト」としてのランナーとして置いとくだけでだいぶ意味がある。かつ、ほぼどこでも動くというのも大きい(make叩けばいいんでしょ?ってなる
— アルパカ大明神[▮▮▮▯▯▯▯▯▯▯] (@toritori0318) 2020年9月13日
make のいいところの一つに意味とコンテキストが扱いやすいことがあると思う。アプリケーションの主な操作はMakefileに、コンテキストにスペシフィックなものは https://t.co/Lzx5oFBVlL や https://t.co/srD1FmhEvO に、それらの中で多くの人が「多分こうだろう」と理解しやすい表現で書けるのがよい
— ひさしぶりにツイートしました (@tamakiii) 2020年9月13日
それでも本来の用途とは異なりタスクランナーとして使う以上、多少の補足は必要で、README を多少書く術はセットであるとよりよいとも思う。使わなくなったターゲットを消す基準にもなる。README もなるべく簡素に書くのが良い状態を保つコツな気がする。
— ひさしぶりにツイートしました (@tamakiii) 2020年9月13日
全くだと思うが、
— 非実在naka aki (@naka_aki_spl) 2020年9月13日
*makefileについて知ってる
*適切な命名を知っている。つまりReadableCode節。
というリテラシーが最低条件なので、
そういう新人が降ってくる現場はいいなあ的。
あと環境も、
*ほんとにそのターゲットが動作する
*動作「させて」いい。共同所有権&"許可でなく謝罪"
が必要
手順をMakefileにしておくと、オペレーションの依存関係も明示できるし、ちゃんと書いておけば適切な並列実行も、途中からの(あるいは途中までの)部分実行もできて便利。
— (び) (@bizenn) 2020年9月13日
と言ってたら「Rakefileの方がコード書けて便利ですよ」って若者に言われたことがある。そこ混ぜない方がいいと思う。
江添亮のC++入門を読んでたら、序盤にMakefileをゼロから実用するまでの丁寧な章があって「こんな良いものが手元にあったのか」と感動した。npmプロジェクトでgulpと置き換えられる場所も多いと思う。 https://t.co/vJESanoEzR
— なかざん (@Nkzn) 2020年9月13日
ビルド時の生成ファイルに依存する処理順の管理という、npm文化圏の人間がちょいちょい困る問題は、ある程度makeで解決できると思っている。
— なかざん (@Nkzn) 2020年9月13日
シェルに切り出した処理をnpm scriptsで呼び出す派閥もあるけど、もう一歩踏み込んでMakefileに切り出した処理をnpm scriptsから呼び出すと使い勝手が良さそう
まあMakefileの中にはシェルを書くので、結局シェルなんだけども。
— なかざん (@Nkzn) 2020年9月13日
GNU Make、PowerShell 使ってるマンとしては Makefile の中で sh の機能を呼ばないで、実行ファイルだけ呼んでほしい。sh や bash を明示的に呼んでほしい。
— o̞͑kä̝mo̞͑to̞͑ kä̝zʊ̠kɪ̟ (@kakkun61) 2020年9月14日
makefileとかいうリポジトリのリファレンスガイド
— スーギ・ノウコ自治区 (@pCYSl5EDgo) 2020年9月14日
ありがてえ
わかる。
— Tadayuki Onishi (@kenchan0130) 2020年9月14日
人間は欲深いので、気づいたらMakefileがfatになってくる。そしてMakefile読み込まないとわからなくなる。 https://t.co/Tp6qfmAaVH
Makefileのコメントからドキュメントを作成するhttps://t.co/kHWQjsGASi
— 中野智文 Tomofumi NAKANO (@nakano_tomofumi) 2020年9月14日
Makefileはちょっと勉強したことがあるぐらいだけど、あれは成果物を作るDSLであって.PHONYの意味を理解してから本来はタスクランナーではないと感じた。
— Kenta.Kase (@Kesin11) 2020年9月14日
Voyage のリポジトリに Makefile があるの、前から聞いてたしとても便利だと思ってるけど、自分たちの会社でやろうと思ったことは一度もない(事情が違うので当たり前の話)
— 小笠原みつき / JX通信社 / 71.2㌕ (@YAMITZKY) 2020年9月14日
その代わりJXだとdocker-composeがある
VGがスゴイ会社なのは、Makefile があるからじゃなくて、自分たちの課題を解決するものがあるから、ということです
— 小笠原みつき / JX通信社 / 71.2㌕ (@YAMITZKY) 2020年9月14日
個人的にはMakefileあると結構嫌な気持ちになる。複雑なセットアップが必要な可能性があり、言語公式のランナーで動かないのかなとか考えるから
— 小笠原みつき / JX通信社 / 71.2㌕ (@YAMITZKY) 2020年9月14日
Makefileが力を与えてくれているのかもしれない!
— Aratoon | ハイカラ on niconico (@ara_ta3) 2020年9月14日
ですです。
— すぎちゃん (@koheiSG) 2020年9月14日
そこが多分もともとの発言との差異を生んでいると思ってて、makeはタスクランナーとしても便利だけど多言語環境とモノリスrailsとの違いというか。
それでヘイトの溜まるMakefileの話とかが交差して槍玉に挙げられてる感ww
makefileで複雑な条件分岐するくらいならshell scriptのほうが良いし、shell scriptで複雑な条件分岐するくらいならランタイムが必要になったりコンパイル後サイズが大きくなっても他の言語のほうが良くない?goとか…
— 小橋はこ@🏘️家にいる 🖐️手を洗う (@hako584) 2020年9月14日
って話、20年前からされてる気はする(20年前はgoじゃなくperlとかだったが)
Fastlaneがあるじゃないって言おうと思ったら既に言及してましたねw
— 笹のり@弱王:ジェレイド@ドラクエ10 (@sasa_app) 2020年9月14日
Fastlaneの導入込みで初期構築をMakefileでやってるところも結構ありますよねー
界隈の人たち、定期的に Makefile の話題で盛り上がるのなぜ
— hoto (@hoto17296) 2020年9月14日
しばらくMakefileとシェルスクリプトと格闘した経験から言うと、Makefileは主に以下の3つの目的に留め、それ以外はシェルスクリプトにした方が良いと思ってる。
— てくのたのしー (@techno_tanoC) 2020年9月14日
1. タスクの引数に名前を付ける
2. タスクの引数のデフォルト値を決める
3. 複数のタスクを定義する
念の為言うとやろうと思えばMakefileでもできる。
— てくのたのしー (@techno_tanoC) 2020年9月14日
シェルスクリプトよりMakefileの記述に慣れてる人が集まってるなら良いんだけど、多分多くのプログラマはシェルスクリプトの方が慣れてると思う。
Makefile、仕事のJavaプロジェクトだと見たこと無かったんですが、これは標準の開発PCがWindowsだったからなのか、文化的にMavenのAntタスクでやっちゃうからなのか気になる
— Junki Mano (@laqiiz) 2020年9月14日
文化の違いなんですかね、自作キーボードのキーマッピング焼くのにMakefile大活躍しててなるほどってなりました
— M-Ito (@it_guitar) 2020年9月14日
2018年のアドカレでもnpm scriptsが太って辛いからMakefile使おうぜっていうのがあったんだな "JavaScriptの開発でGNU Makeを使ってみた - Qiita" https://t.co/MEB5lAjq7J
— ハゲワシ; (@tansokuojisan_) 2020年9月14日
Makefile嫌なら何で書くんだろう、と思いながら眺めてる
— sion_cojp (@sion_cojp) 2020年9月14日
不意にMakefileの話題が流れてきて、オラわくわくしてきたぞ
— 地平線 (@golden_eggg) 2020年9月14日
「◯◯さんが書いたMakefileのアイデアをパクらせてもらおう」が最高のエンジニア賛辞の1つ、という時代&環境にいました
— 地平線 (@golden_eggg) 2020年9月14日
Makefileは結構使いますよ。 最近かかわってるところはどこも用意しているイメージ。
— tarappo (@tarappo) 2020年9月14日
Makefileとか言ってると老害だと思ってたら実際はそうじゃなさそうで、いよいよ本当に老害化が進んできたようだ。
— y@su (@yatmsu) 2020年9月14日
Makefileは実行できるREADMEという認識。
— ayustate (@ayustate) 2020年9月14日
簡易的なcliツールでいうと、bashで書くとzshじゃ動かないって言われるし、shellで書くにはfatになるのでmake。
— sion_cojp (@sion_cojp) 2020年9月14日
Makefileが変数ばかりで読みづらくなったりfatになったらGoにすることが多いですね。
あとREADMEに開発環境初期セットアップをつらつら書くよりmake等でコードとして表現させたい
Makefileが1枚なら良いけど、パッケージ毎(コード書いた人毎)にMakefileが散在しているMakefileをメンテしていたりビルドしていた人間からすると、Makefileといわれたら吐き気は正直感じる。
— ぬっきーさん@ガーデニングおじさん (@poponuki) 2020年9月14日
Makefile の嫌われる点はこんな感じ?
— BTO (@bto) 2020年9月14日
- タスクではなく、ファイル生成の定義
- 依存関係の解決がファイル生成の可否
- 先頭がハードタブ
- 行単位のコマンド実行(not shell script)
- 変数が遅延評価
ちょっとコマンド書くぐらいだったらそんなに難しくはないと思う
npm scriptをwrapしてるだけのMakefileが存在するのどうなの
— たけてぃ (@takeokunn) 2020年9月14日
他人が書いたMakefileを読むのはつらいよね…
— keiichiro shikano λ♪ (@golden_lucky) 2020年9月14日
(型システム入門を作ったときに原著者のMakefileを読むのは本当につらかった)
— keiichiro shikano λ♪ (@golden_lucky) 2020年9月14日
Makefileシェル芸はたぶんあまり幸福にはなれないので複雑なのは素直に別スクリプトに分けた方がいいです
— ぞぬ頃し半分子 (@tadsan) 2020年9月14日
いろいろなコマンドのオプションを覚えたくない(し,そもそも覚えられない)のでなんでもMakefileにまかせてる. https://t.co/011qfrPNFb
— dif_engine (@dif_engine) 2020年9月14日
Makefile、 Makefile で済むのにはガンガン活用したいが GNU 拡張とか使いたくなるようなケースの時にちょっと悩む
— にゃおきゃっと (@nyaocat) 2020年9月14日
とはいえMakefileの中身を理解しつつも使わないチームメンバーもいるし、それでいいんだよな〜って気持ち
— Hirotaka Miyagi (@MH4GF) 2020年9月14日
使いたい人が使えばいい、Makefileの中身を理解しやすく保つ必要はあれど
そうですね、ただ複雑なことが出来ないっていうのは利点でもあるかなと。以前に全てをやろうとしている長大なMakefileのメンテで精神をやられたことがあるので……
— はっちん (@hatchinee) 2020年9月14日
Makefileの1つのターゲットの中ではshellscriptやコマンドを1つ叩くこと以外はしたくない
— そな太@GraphQLはいいぞ (@sonatard) 2020年9月14日
ちなみにMakefileはいうほどBetter Shell Scriptじゃないからそれが目的だったらもっと高級な言語にさっさと変えた方がいいです。
— kishikawa katsumi (@k_katsumi) 2020年9月14日
タスクランナーとしてMakeを使うの、いいと思わない人が多いのか
— ウホーイ@iOSDC 2020 9/20(日) 14:40-15:20 Track B (@the_uhooi) 2020年9月14日
iOSDCで便利だよと発表するワイ泣きそう
Rakeやnpmなど、タスクランナーとして使えるツールをさらにラップするのはわかりづらいけど、それがない開発(iOSアプリなど)なら有用だと思う…(半泣き)
Cloudfrare WorkersとかでWASM+WASIの環境が整ってきて、WASMがポータブルな実行形式として人権を獲得し始めたあたり今後Dockerは長期的に見てリッチなMakefileみたいな扱いになるんだろうな
— コミさん (@komi_edtr_1230) 2020年9月14日
Makefile macroはびみょい
— たけてぃ (@takeokunn) 2020年9月14日
Makefileに限らずインデントが意味を持つ言語が嫌いなのでダメです(過激派)
— Atom(アトム) (@FromAtom) 2020年9月14日
今自分のプロジェクトほとんどMakefileなのはどうにかしたほうがいいんだろうけど、Projucerを呼び出すやつとかgradlewを呼び出すやつとかデスクトップとAndroid両方やるやつとかなので、何が適切な解なのかわからんってなる
— Atsushi Eno (@atsushieno) 2020年9月14日
Makefileを読んで問題なさそうなら喜んで Make 使います!
— かびごん小野 (@takoikatakotako) 2020年9月14日
考えたんですが、Make で意図せぬものをインストールされるのが嫌なのかもしれません。
あとは用意された make setup 的なコマンドが完璧ではなく、結局中を読まないといけなかったりするのが嫌なのかもです。(´・ω・`)
俺も割と最近まで好きだったけど、まじでしんどいMakefile見てから考えが変わってしまった
— ユウキ (@yukiyan_w) 2020年9月14日
メンバーに環境を作ってもらう部分のハードルを下げたくてMakefileを使っていた時期があるけど、ろくな事が無かったのでfabricに移行した。
— marvelph (@marvelph) 2020年9月14日
そうですね。僕もMakefileが複雑になるのは危険だと感じて、いた仕方なくシェルスクリプトを併用します。
— KANEKO Ryosuke (@yamaneko1212) 2020年9月14日
この辺を統合できて複雑性も低減できるツールが欲しいですね(作れってか)
めっちゃmakeにハマって何にでもMakefileを書いていた時期があるけど最終的に同じ意見です https://t.co/xEA7qjiqCp
— じょーさん@人生何度でもやり直し (@elf) 2020年9月14日
サクっと読める Makefile もあれば、FreeBSD の ports あたりのような巨大システムになっている Makefile もあるわけで(マニュアルで bsd . port . mk というファイルの説明として The big Kahuna って書いてある)、まぁ両極端だが、あなたが議論してるのはどれ? とまず言う必要がある
— きしもと (@ksmakoto) 2020年9月14日
C/C++とかちゃんとやってないからMakefileでPHONYしか書いたことない...それだけでもめっちゃ便利だと感じた(使い方理解してないからもっと便利に使えそう)
— pyteyon (@pyteyon) 2020年9月14日
makeその通りなんだけど、BSD makeとGNU makeの差異ががが、とか、適度な入門書ががが(C利用前提感が強い)とか、一度使えるようになった人と、これから使おうとするの人の隔絶が大きい
— HATANO Hirokazu (@tcsh) 2020年9月14日
(自分も語れるほどMakefile書いてないし。Sphinx利用で毎日叩いてるけど。)
ビルドツールとしての make は私は使いませんが、いにしえのライブラリを保守する際に、Makefile が重要な手がかりになったことは確かにあります。
— のせなおき (@nosen) 2020年9月14日
僕もMakefile好きです!
— sim update --repo-update (@simorgh3196) 2020年9月14日
fastlaneも入れてますが、fastlaneはシンプルなタスクに分けてMakefileで依存も考慮しつつタスク組み立てたりしてます
環境セットアップだとMakefileはメンテナンスできる人少なめ、シェルもまぁまぁきついけどそれより扱いやすくなると「どこでも使える」が難しくなるような。今だとPython3がそのポジションに近づいてたりするんだろうか。
— masa寿司 (@masa_iwasaki) 2020年9月14日
「Makefileを書くな、vanila shellにしろ」って意見を見かけましたが、「簡単に並列処理ができる」「依存関係を解析して実行してくれる」っていうmakeの利点はとても捨てがたいと思いますよ。
— ノーン (@nkowne63) 2020年9月14日
Makefileで仕上げてある方がスマートな印象を受けますhttps://t.co/I5iuHJiJVjのほうが汎用的なイメージですが
— ヤッチ@Linux好きな英語話せるエンジニア (@8gLHsEmsnsp8RP3) 2020年9月14日
makeの話かなりおもしろいので誰か可能な限り全部意見まとめてほしい (他人任せ)
— r7kamura (@r7kamura) 2020年9月14日
Docker nginx 公式イメージで nginx-debug を使う
Nginx でちょっとでも複雑な設定を書こうとすると、通常のログでは状況を把握しにくい。
より詳細なデバッグログを出すには nginx-debug
バイナリが必要で、通常 nginx start
しているのを nginx-debug start
して、debug level specification
を指定してやる必要がある。
Pre-built Linux packages provide out-of-the-box support for debugging log with the nginx-debug binary (1.9.8) which can be run using commands
To avoid this, either the line redefining the log should be commented out, or the debug level specification should also be added:
docker.io
上のイメージには 1.9.8
からバイナリがあるのが確認できる。
$ docker run -it --rm nginx:1.9.7 whereis nginx-debug nginx-debug: $ docker run -it --rm nginx:1.9.8 whereis nginx-debug nginx-debug: /usr/sbin/nginx-debug
どうも https://github.com/nginxinc/docker-nginx
のリリースは必ずしも Pull Request を作ってリリースしている訳ではないらしく時系列が負いにくくいつからかはわからないが、このコミット以降 docker-entrypoint.sh
の第一引数を参照するようになった模様。
docker-entrypoint.sh
の引数に nginx-debug
を指定すればいいだけなので、こう。ENTRYPOINT
自体を書き換える必要はない。
FROM nginx:1.19.1 COPY ./default.conf /etc/nginx/conf.d/default.conf CMD ["nginx-debug", "-g", "daemon off;"]
デバッグログは常に必要な訳ではないので(むしろ邪魔)、docker build --target
を活用してこう書くことが多い。
FROM nginx:1.19.1 as production-pseudo COPY ./default.conf /etc/nginx/conf.d/default.conf # -- FROM production-pseudo as development # -- FROM development as debug CMD ["nginx-debug", "-g", "daemon off;"]
実際に使っている Nginx のバージョンが古い場合、nginx.org
のリポジトリであれば多少バージョンが古くても nginx-debug
バイナリも含めてパッケージを配布してくれており、これが使える。バージョンを上げられるならこれを機に上げてしまったほうがよいと思う。
FROM debian:10.4 RUN apt-get update && \ apt-get install -y --no-install-recommends \ curl \ gnupg2 \ ca-certificates \ lsb-release \ software-properties-common \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --keyserver-options timeout=10 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 && \ add-apt-repository "deb https://nginx.org/packages/debian/ buster nginx" RUN apt-get update && \ apt-get install -y --no-install-recommends \ nginx=1.16.1-1~buster \ && \ apt-get clean && \ rm -rf /var/lib/apt/lists/*
docker-compose の ${VAR:-default} 記法と .env で開発&本番環境を設計する
docker-compose.yml で、シェルでよくある ${VAR:-default}
記法が使えるのがあまり知られていないようだったので書きます。
www.debuntu.org
サンプルプロジェクトはこちらです github.com
PHP が動く Dockerfile と
# Dockerfile FROM docker.io/php:7.2.29-cli
それを使う docker-compose.yml を用意します。今回はサービスは1つです。
# docker-compose.yml version: "3.7" services: php: build: context: . working_dir: /app volumes: - .:/app
動かすプログラム src/main.php
は環境変数 $MESSAGE
を出力するだけです。
<?php echo $_ENV["MESSAGE"] . PHP_EOL;
Dockerfile で ENV MESSAGE "hello"
として
FROM docker.io/php:7.2.29-cli ENV MESSAGE "hello"
これを実行すると、ENV
した hello が出力されます。
$ docker-compose run --rm php php src/main.php
hello
これは環境変数なので当然シェルも同様です
$ docker-compose run --rm php sh -c 'echo $MESSAGE' hello
docker-compose.yml で environment
に表題の MESSAGE: ${MESSAGE:-holla}
とすると
--- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,6 +3,8 @@ services: php: build: context: . + environment: + MESSAGE: ${MESSAGE:-holla} working_dir: /app volumes: - .:/app
デフォルト値の holla が出力されます
$ docker-compose run --rm php php src/main.php
holla
-e
を指定するとこちらが優先されます
$ docker-compose run --help | grep -- "-e KEY=VAL" run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...] -e KEY=VAL Set an environment variable (can be used multiple times) $ docker-compose run --rm -e MESSAGE=ciao php php src/main.php ciao
.env
を docker-compose が勝手に読むので、状態を .env
に保持しておけます
$ echo "MESSAGE=haisai" > .env $ docker-compose run --rm php php src/main.php haisai
さて、ここで開発用にgitやvimを入れたくなった気持ちになってみます。
--- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,10 @@ FROM docker.io/php:7.2.29-cli +RUN apt-get update && \ + apt-get install -y \ + vim \ + git \ + && \ + apt-get clean + ENV MESSAGE "hello"
本番稼働時は要らないですよね
$ docker-compose build Building php Step 1/4 : FROM docker.io/php:7.2.29-cli ---> e7d2518687da Step 2/4 : ENV MESSAGE "hello" ---> Using cache ---> 51c63dafa792 Step 3/4 : FROM production-pseudo AS development ---> 51c63dafa792 Step 4/4 : RUN apt-get update && apt-get install -y vim git && apt-get clean ---> Using cache ---> 964a4048e6ab
そんなときは target build stages の出番です。
production-pseudo
はまだ本番稼働していない疑似本番環境を表す語として使っています。
FROM docker.io/php:7.2.29-cli AS production-pseudo RUN # ここに本番で要るものだけインストールする # -- FROM production-pseudo AS development RUN apt-get update && \ apt-get install -y \ vim \ git \ && \ apt-get clean
これで TARGET=production-pseudo
時はvimやgitをインストールしなくなりました
$ docker-compose build Building php Step 1/2 : FROM docker.io/php:7.2.29-cli AS production-pseudo ---> e7d2518687da Step 2/2 : ENV MESSAGE "hello" ---> Using cache ---> 51c63dafa792 Successfully built 51c63dafa792 Successfully tagged docker-compose-variable_php:latest
TARGET=development
時はインストールされます
$ echo "TARGET=development" > .env $ docker-compose build Building php Step 1/4 : FROM docker.io/php:7.2.29-cli AS production-pseudo ---> e7d2518687da Step 2/4 : ENV MESSAGE "hello" ---> Using cache ---> 51c63dafa792 Step 3/4 : FROM production-pseudo AS development ---> 51c63dafa792 Step 4/4 : RUN apt-get update && apt-get install -y vim git && apt-get clean ---> Running in 36bcf0f189fe $ docker-compose run --rm php which git /usr/bin/git
これに VSCode の Remote Containers 拡張用を合わせて使うと相性が良いです。
FROM development AS debug
として XDebug をインストールする、といった使い方もできます(それなりに重いので)。
が、話が長くなるのでこれについてはまた次回書きます。
ちなみに今回、 .env
を作ったりする docker.mk
はこの様になりました
.PHONY: install install-dev development clean TARGET := production-pseudo install: \ .env \ build install-dev: \ development \ install development: $(eval TARGET := development) .env: touch $@ echo "TARGET=$(TARGET)" >> $@ build: docker-compose build clean: rm -rf .env