Hacker News 의견
  • 1985년에 Boston University Graphics 랩에서 한 사람이 Makefile을 이용해 애니메이션용 3D 렌더러를 만들던 모습을 직접 본 경험이 있음. 그 사람은 Lisp 프로그래머로, 초기 프로시저 생성 및 3D 액터 시스템을 진행 중이었고, 10줄 정도로 구성된 정말 우아한 Makefile을 만듦. 단순한 파일 날짜 의존성으로 수백 개의 애니메이션을 자동 생성하는 구조였음. 각 프레임의 3D 형태를 Lisp로 만들고, Make가 프레임을 생성하는 방식이었음. 1985년 당시 3D와 애니메이션을 당연하게 여긴 요즘과 달리 모두가 놀라워하는 상황이었고, 그가 이후 Iron Giant와 Coraline의 3D 렌더러를 담당했던 Brian Gardner라는 점 기억

    • 혹시 이 사람 3d-consultant.com/bio.html에 나오는 사람인지 궁금증 표현

    • Coraline이라는 영화를 말한 거 맞는지 확인

  • Make를 쓸 때 잘 알려지지 않은 유용한 플래그 몇 가지 소개

    • --output-sync=recurse -j10: 의미는 각 타겟 작업이 끝날 때까지 stdout/stderr를 모아서 출력하는 플래그로, 그렇지 않으면 로그가 섞여서 분석이 어려움
    • 바쁜 시스템이나 다중 사용자 환경에서는 -j 대신 --load-average를 활용하여 병렬 처리 시 시스템 부하를 조절할 수 있음 (make -j10 --load-average=10)
    • 빌드 타겟 스케줄을 무작위로 섞는 --shuffle 옵션은 CI 환경에서 Makefile 내 의존성 문제를 잡아내는 데 유익
    • make의 다양한 옵션을 공식적으로 정리해 텍스트나 문서 형태로 프로그램에 포함시키면 사용 접근성이 높아진다는 아이디어 언급

    • 본인이 자주 쓰는 옵션은 전체 강제 빌드에 사용하는 -B 플래그 설명

    • ‘make -j’로 인해 도스 머신에서 발생한 문제를 자주 봤기 때문에 그 현상을 버그로 인식

    • 바쁜 시스템이나 다중 사용 환경에서 병렬화 문제는 OS 스케줄러가 처리해야 하는 일 아닌지 질문

    • 유용한 플래그지만 이 옵션들은 포터블하지 않기 때문에, 본인만을 위한 비공개 프로젝트 외에는 쓰지 말 것을 권장

  • .PHONY를 사용하지 않는다는 이유로 튜토리얼에서 건너뛰는 건 약한 변명이란 생각. 툴을 제대로 쓰는 방법을 가르치는 게 맞다는 의견

    • 팀에서는 Make를 태스크 러너로 사용하면서 모든 레시피에 .PHONY를 추가 및 유지한 것 때문에 논쟁을 겪음
    • Clark Grubb의 Makefile 스타일 가이드(clarkgrubb.com/makefile-style-guide) 추천
    • .PHONY 선언을 레시피별로 하는 것과 파일 상단에 한 번에 모으는 것 사이에서 다양한 스타일 경험 공유 및 linter로 강제했으면 좋겠다는 바람
    • 읽어본 결과 괜찮은 문서지만 몇 가지 동의하지 않는 점 있음
      • -o pipefail을 맹목적으로 적용하는 건 문제이고, 파이프에서 grep 등을 쓸 때 깨질 수 있으니 상황별로 적용할 것 추천
      • 비파일 타겟에 .PHONY를 마크하는 게 엄밀하긴 하지만 거의 불필요하고 Makefile만 장황해져서 필요시만 적용이 낫다는 관점
      • 여러 개의 아웃풋 파일을 만드는 레시피는 예전에는 더미 파일을 썼지만, 최근 GNU Make 4.3부터 그룹 타겟 공식 지원(여기서 확인)이 가능
  • Make는 대형 C 코드베이스의 빌드에 특화된 툴이라는 주장

    • 누군가 프로젝트별 잡 러너(업무 실행기)로 즐겨쓰는데, Make는 잡 러너로서는 적합하지 않고 조건문 같은 것도 어렵게 만드는 구조임
    • Terraform 같은 도구와 래핑하려다 실패한 경우도 본 경험
    • Make는 잡 러너라기보다 선형 쉘 스크립트를 선언형 의존성 형태로 변환하는 범용 쉘 도구라는 의견

    • C 코드베이스만의 빌드 툴로서 Make를 보는 관점은 더 이상 맞지 않다는 입장. 지난 20년간 더 견고하고 명확한 빌드 시스템이 개발된 현실을 언급. 업데이트 필요성 제기

    • 좋은 잡 러너에 대한 질문. (본인이 잡 러너 의미 혼동했다는 사과 추가)

  • Makefile이 복잡해지는 부분을 현대적으로 대체해주는 툴로 just 추천

    • just는 shell 스크립트 목록 대체에는 좋지만, ‘재실행이 필요한 룰만 실행’하는 Make의 본질적인 기능은 대체하지 못함

    • 그 밖에 대안으로

    • 대안 도구들은 자신을 Make 대체라고 하지만 본인은 완전히 다르고 비교 자체가 어렵다고 생각. Make의 핵심은 산출물 생성과 이미 빌드한 것의 미재빌드에 있음. 반면 just는 단순 커맨드 실행기 역할

    • Make를 명령 실행기로 쓸 때의 장점은 거의 모든 곳에 설치되어 있는 표준 도구란 안정성. 대안들이 더 잘 만들어졌어도 별도 설치 부담이 있어 굳이 쓸 필요성을 못 느낌

    • Task는 내가 C로 하는 간단한 취미 프로젝트엔 잘 쓰고 있지만, 대형 프로젝트에도 적합한진 아직 판단 어려움(Task 공식 홈페이지)

  • 최근 CMake가 Makefile이 C++20 모듈 지원에는 적합하지 않다고 보고 ninja를 기본으로 택했다는 점 흥미로움(CMake 가이드)

    • 실제로는 타겟 의존성을 정적으로 정의하기가 불가능에 가까워서 clang-scan-deps 같은 도구로 동적으로 분석하는 방식 채택(기술 슬라이드)
    • 실제로 이 제약은 CMake 쪽 결정이거나 Makefile generator에 지원자가 없는 문제라 생각. ninja도 C++ 모듈 직접 지원하지 못하고(관련 이슈), ninja는 오히려 Make보다 기능이 적고 모든 의존성을 정적으로 명시해야 한다는 문제 지적

    • 모듈 도입 자체가 복잡하고 혼란스럽다는 의견

  • tup 사용 경험이 있는지 질문. (공식 문서)

    • tup은 파일 시스템 접근을 기반으로 자동으로 의존성을 파악해 어떤 컴파일러/툴에도 적용 가능한 빌드 시스템임
  • 본인이 Task라는 Make 대안 툴의 창시자이자 메인테이너임을 소개. 8년 넘게 개발 중이고 계속 발전함

    • just 역시 또 다른 Make 대안으로 추천(just GitHub)

    • 재미있는 우연으로, 본인은 Task를 자주 쓰고 오늘 아침에도 이슈 올림

  • 이 튜토리얼에는 위험하고 미묘한 문제가 있음

    • MAKEFLAGS에서 옵션 파싱 시, 긴 옵션이나 빈 짧은 옵션 다루려면 다음처럼 해야 함
      ifneq (,$(findstring t,$(firstword -$(MAKEFLAGS))))
    • OS X 기본 제공 구버전 make 호환이 필요하다면 상당수 기능이 미비하거나 미묘하게 다름
    • 이외의 문제는 대부분 오타나 최선의 스타일 위반이므로 생략
    • 참고로 load는 guile보다 포터블하며, 크로스 컴파일 환경에서는 컴파일러 지정을 정확히 해야 함
    • Paul’s Rules of Makefiles(여기)와 GNU make 매뉴얼(여기), 관련 매뉴얼을 꼭 읽어볼 것 추천
    • 간단한 데모용 Makefile 프로젝트도 운영 중(데모 github)
  • 각 GitHub 레포에 항상 Makefile을 포함하는 습관

    • 매번 명령어를 까먹기 쉬워서 Makefile로 저장하면 손쉽게 복잡한 Step도 추가해둘 수 있고, make만 돌리면 따로 기억하지 않아도 프로젝트별 기대하는 동작 바로 실행 가능