Search
🌍

bb2. title: CMake와 같은 높은 추상의 도구들이 나타나기 전에는, 빌드관계를 정의하고 간단한 변수를 선언할 수 있는 스크립트 수준의 간단명료한 Makefile이 있었다.

생성
🚀 prev note
🚀 next note
♻️ next note
bb2.1. title: Makefile 은 그냥 타겟(Target), 의존성(Dependencies), 레시피(Recipe)로 빌드 규칙을 정의하여 증분 빌드(‣)가 가능하도록 하는 도구이다.
bb2.2.2. title: 크고 복잡하게 정의된 추상화 수준에 엄청난 삽질을 때려박아 하나의 더 나은 추상화 수준으로 만드는 것도 추상화이고, 크고 복잡하게 정의된 추상화 수준을 작은 단위로 분해하는 것도 추상화이다. 이런 재추상화는 문제를 다시 정의하는 것이다. 문제가 잘 정의되면 패러다임의 변화를 가져온다.
bb2_1. title: CMake는 Make보다 훨씬 정교하지만 컴파일 결과물을 독립된 디렉토리에 가두고 다른 CMake파일에서 불러오는 일은 여전히 어렵다. 여러 프로젝트에서 동시에 사용하는 패키지가 시스템 경로에 설치되는 것이 자연스러운 워크플로이기 때문이다. 이 문제를 해결하기 위해 시스템 차원의 가상환경인 도커가 사용될 수 있다.
a0_4.1. title: 제텔카스텐 엔트리포인트 메모는 추상화된 생각 덩어리이다. 원리는 소프트웨어공학의 기본 원칙의 아이디어와 동일하다.
14 more properties
CMake 와 같은 높은 추상의 도구들이 나타나기 전에는 Makefile이라는 존재가 있었다(참고6). 많은 라이브러리는 빌드 및 설치를 단순화하기 위해 소스코드와 Makefile로 구성되었다. 덕분에 make, make install 로 소스코드를 간편하게 컴파일 및 설치할 수 있었다.
프로젝트는 시간이 갈수록 커지기 마련이다. 문제는 프로그램을 구동할 시스템도 다양해진다는 것이다. Makefile 작성도 덩달아 복잡해졌다(참고10). 운영체제, 아키텍처에 따라 빌드와 설치를 위해 Makefile에 명세되어야 하는 명령은 조금씩 다를 것이다. 간단히 생각해 보아도, 운영체제나 CPU 아키텍처마다 사용가능한 컴파일러가 다르고, 명령어의 종류나 파일 디렉토리 구조도 다를 것이다. 하나의 Makefile에 모든 경우의 수를 고려하여 작성해 넣는 것은 말이 안 되는 일이었다.
이 문제를 해결하기 위해 Makefile을 추상화하는 Makefile.in이라는 템플릿 파일과 configure 파일이 등장했다(참고9). 이제 ./configure && make && make install과 같이 변화한 것이다(참고1,참고2,참고3:Makefile의 원칙). ./configure 을 실행하면 운영체제나 CPU의 아키텍처에 맞도록 Makefile.in 템플릿에 운영체제나 CPU 아키텍처에 종속적인 적절한 값들이 할당되어 Makefile이 생성되는 방식이었다(참고9,참고12). 과거에는 이렇게 Makefile의 복잡성을 극복하기 위해 소스코드 배포자가 못생긴 Makefile.in 같은 파일이나 configure 같은 명령어들을 작성해야 하는 고통스러운 시간이 있었다.
이러한 문제를 해결하기 위해 Automake이라는 또다른 도구가 생겨나기도 했다. 이 도구는 configure 파일과 Makefile.in 템플릿 파일을 자동으로 생성한다. Automake은 복잡하고 더러운 configure 파일과 Makefile.in 파일을 configure.ac (autocompile), Makefile.am (automake) 파일로 다시한번 추상화한다(참고12). configure.ac 파일과 Makefile.am 파일은 읽고 쓰기가 훨씬 편하다(참고11).
이런 과정을 거치며 발전하다 보니 추상화 수준이 굉장히 더러워졌다. 다양한 플랫폼에 대해서 이 모든 문제들을 보다 나은 방식으로 추상화할, 하나의 명령어만으로 전체 빌드 과정을 제어하기 위해 등장한 방법이 CMake이다. 쉽게 말하면 CMake는 어느 운영체제 혹은 CPU에서나 CMakeLists.txt 이라는 이름의 파일만 가지고(당연히 CMakeLists.txt는 운영체제 혹은 CPU에 따라 파일의 내용이 달라질 필요가 없다) 컴파일 및 인스톨이 가능한 Makefile 생성을 돕는 프로그램이다(참고4).
Makefile은 UNIX계열 운영체제에서 사용하는 빌드 시스템이다. 빌드 시스템은 운영체제, 컴파일러, 하드웨어 아키텍처 등마다 제각기 다르다. 앞서 글에 상기한대로 UNIX계열 운영체제에서는 Make를 사용하므로 Makefile을 생성하지만, Ninja 등 다른 빌드시스템을 사용한다면 결과물은 Makefile이 아닐 것이다(참고13,참고16,참고18,참고19).
CMake는 빌드 관련 파일들을 모두 build디렉토리에 보관도록 유도하고(참고5), 빌드 결과물을 저장할 디렉토리를 쉽게 명시할 수 있게 한다(참고14,참고17). 그 결과, 이런 빌드 관련 파일 고립 설정을 일일히 명세해야 하는 Makefile에 비해 소스코드가 보관된 디렉터리나 함부로 건드려서는 안되는 중요한 디렉토리들을 더럽히지 않도록 만들기가 훨씬 용이해졌다.
빌드_디렉토리$ cmake ../cmake_빌드를_제공하는_라이브러리의_디렉토리/
Bash
복사
Configure & Generate (참고19,참고20)
빌드_디렉토리$ make -j{n} && make install
Bash
복사
Build
parse me : 언젠가 이 글에 쓰이면 좋을 것 같은 재료들.
1.
None
from : 과거의 어떤 생각이 이 생각을 만들었는가?
1.
@9/27/2023 앞의 글에 나와 있던 내용을 가져와 보완함.
2.
Makefile로부터 CMake로 발전해 가는 과정은 추상화 과정을 잘 보여주는 사례이다.
3.
환경 변수에 명시된 디렉토리들은 함부로 건드리면 안되는 중요한 디렉토리들이다.
supplementary : 어떤 새로운 생각이 이 문서에 작성된 생각을 뒷받침하는가?
opposite : 어떤 새로운 생각이 이 문서에 작성된 생각과 대조되는가?
1.
None
to : 이 문서에 작성된 생각이 어떤 생각으로 발전되고 이어지는가?
참고 : 레퍼런스