我喜欢 Makefile I Like Makefiles

原始链接: https://switowski.com/blog/i-like-makefiles/

Makefile 是类 Unix 操作系统中常用的通用自动化工具,用于简化各种软件项目的构建、测试和部署过程。 它们的吸引力在于它们在多个项目中的简单性和一致性,以及无论使用何种底层技术都能够执行预定义的命令集。 Makefile 通常定义任务(目标),例如“dev”、“build”、“watch”和“deploy”。 这些任务执行启动开发服务器、编译代码、监视文件修改和发布已完成的项目等操作。 通过使用单个“make”命令,用户可以快速设置和运行这些任务,而无需记住每个单独工具或项目的复杂细节。 虽然与 Docker 或 Gulp 等现代构建工具相比,Makefile 可能显得很基本,但由于它们与多种工具和环境兼容,因此它们提供了灵活性,同时需要最少的设置和更少的依赖项。 由于其悠久的历史、易于学习和跨平台的广泛可用性,它们仍然很受欢迎。

Makefiles are a versatile automation tool commonly used in Unix-like operating systems to simplify building, testing, and deployment processes for various software projects. Their appeal lies in their simplicity and consistency across multiple projects, as well as their ability to execute predefined sets of commands regardless of the underlying technology being used. Makefiles typically define tasks (targets) such as 'dev', 'build', 'watch', and 'deploy'. These tasks perform actions like starting development servers, compiling code, watching for file modifications, and publishing completed projects. By using a single 'make' command, users can quickly set up and run these tasks without needing to memorize intricate details for every individual tool or project. While Makefiles may appear basic compared to modern build tools like Docker or Gulp, they offer flexibility due to their compatibility with multiple tools and environments while requiring minimal setup and fewer dependencies. They also remain popular due to their long history, ease of learning, and wide availability across platforms.


I like makefiles. I first used a makefile more than ten years ago. Even back then, it looked like some ancient technology used by the graybeard Linux wizards. Years passed, and new build tools came and went, but I kept seeing makefiles still used here and there. I got used to them because they were part of some projects I joined. At some point, I started to like them. Today, they are often the first automation tool I use when I start a new project.

The reason I like makefiles is that they often follow an unwritten convention of implementing the same set of commands to get you up and running. When I find a project I know nothing about, and I see a Makefile file inside, chances are that I can run make or make build followed by make install, and I will get this project built and set up on my computer. Or at least I will get information on other steps I need to include.

I try to apply the same rule in my projects. If I open a folder with one of my old projects and run make dev, this will perform all the necessary steps to build the project and spin up a dev server. That's convenient because throughout the years, I used many different technologies, and each had different commands to build or deploy a project. I have old projects written in Jekyll, Hugo, 11ty, and all sorts of different Python web frameworks. With makefiles, when I come back to a project I haven't touched for months (or years), I don't have to remember the command to start a dev server with, let's say, Jekyll. I just run make dev, and this, in turn, fires up the corresponding Bundler commands. Even if I use tools like Docker or gulp in my project, I still use makefiles to orchestrate those tools. For example, I often write a make build command that builds all the necessary Docker images, passing additional parameters specific to a given project.

My makefiles are simple. I don't use conditional statements, flags or any other fancy features. Most of the tasks (they are technically called targets, but I always call them tasks in my head) consist of one or more shell commands. I could write bash scripts with a couple of functions instead, but makefiles are easier and faster to write.

Some common tasks that most of my personal projects contain include:

  • dev to start the development server
  • build to build the project (if a build step is necessary)
  • deploy to deploy/publish the project

And that's really it. Sometimes, I include additional tasks like watch to automatically rerun the build task when I change any of the source files. But many of my projects can be managed with just two or three Make commands.

This blog that you're reading right now has a simple makefile with just one target:

dev:
npm run dev

And a more advanced project of mine uses the following makefile to run the dev server, watch for changes, build, encrypt and deploy the website:


dev:
bundle exec jekyll serve --unpublished -w --config _config.yml,_config-dev.yml --livereload


build:
npm run gulp build


watch:
npm run gulp watch -- --wip


deploy:
JEKYLL_ENV=production bundle exec jekyll build; \
make encrypt; \
netlify deploy --prod


encrypt:
npx staticrypt _site/*.html -r -d _site

In both of the above examples, I'm ignoring the existence of phony targets, which you might want to add if you have a file called dev, build, watch, deploy, or encrypt, as many kind readers on Hacker News suggested. Otherwise, this Makefile won't work as expected.

GNU Make (the software that runs makefiles) is quite ubiquitous. If you're on Linux, you probably already have it installed. Even on my MacBook, I don't remember installing it explicitly. It must have come with some other tools that I installed in the past. Make is simple and doesn't require as many additional dependencies as some other build tools. This can be useful if you need a tool that will work in a restricted environment where installing additional packages is difficult or impossible for security reasons. Make will probably be already present in that environment. And if not, you can just take the commands from the makefile and run them manually in the shell. If gulp is not available on your server, you can't really take the JavaScript code and paste that into the terminal.

I'm not against other build tools. I like other build tools too. I'm excited when I find a new one that is better and faster than the one I was using before. But I will still use Make to orchestrate them because it gives me a set of familiar commands to manage all sorts of different setups with different tools.

相关文章
联系我们 contact @ memedata.com