코드를 컴파일하기 위해 Makefile과 CMake를 사용하는 것의 차이점


288

C / C ++에서 코드를 작성하고 (GNU) Makefile을 사용하여 코드를 컴파일합니다. CMake와 동일한 작업을 수행하고 MakeFile을 얻을 수 있습니다. 그러나 Makefile과 CMake를 사용하여 코드를 컴파일하는 것의 차이점은 무엇입니까?


2
cmake는 또한 닌자를 사용할 파일을 생성 할 수 있습니다
BЈовић

답변:


403

Make (또는 Makefile)는 빌드 시스템입니다. 컴파일러와 기타 빌드 도구를 사용하여 코드를 빌드합니다.

CMake는 빌드 시스템 생성기입니다. Makefile, Ninja 빌드 파일, KDEvelop 또는 Xcode 프로젝트, Visual Studio 솔루션을 생성 할 수 있습니다. 동일한 시작 지점에서 동일한 CMakeLists.txt 파일. 따라서 플랫폼 독립적 인 프로젝트를 가지고 있다면 CMake는 시스템 독립적 인 빌드를 만드는 방법입니다.

GNU Make가 맹세하는 Visual Studio 및 Unix 개발자에 익숙한 Windows 개발자가있는 경우 CMake를 사용하는 것이 좋습니다.

프로젝트를 다중 플랫폼으로 사용하거나 널리 사용하려는 경우 항상 CMake (또는 다른 빌드 시스템 생성기이지만 CMake가 개인적으로 선호 됨)를 사용하는 것이 좋습니다. CMake 자체는 종속성 감지, 라이브러리 인터페이스 관리 또는 CTest, CDash 및 CPack과의 통합과 같은 멋진 기능도 제공합니다.

빌드 시스템 생성기를 사용하면 프로젝트를 미래에 대비할 수 있습니다. GNU-Make 만 사용하더라도 나중에 다른 플랫폼 (Windows 또는 내장 된 플랫폼)으로 확장하거나 IDE를 사용하려는 경우 어떻게해야합니까?


5
@rish 네, 요점입니다. 그러나 Makefile보다 Linux에서 프로그래밍하는 방법이 더 많다는 점에 유의하십시오 (예 : QtCreator, KDEvelop, Ninja 참조). 이들 각각에 대해 "프로젝트를 만들고 Makefile과 동기화 상태를 유지"하거나 "CMake를 다시 실행"합니다. 그리고 답변에서 언급했듯이 CMake에는 종속성 검색 (예 :) find_package()또는 테스트 / 패키징 지원 과 같은 다른 기능도 있습니다.
Angew는 더 이상 SO

3
CMake가 비재 귀적 메이크 파일을 만들 수 없다는 것을 읽었습니다. 아직도 그래요?
Maxim Egorushkin

1
@Angew 비 재귀 는 완전한 프로젝트 종속성 트리로 make가 한 번 호출되는 경우입니다. 최상위 레벨 makefile이 특정 순서로 하위 프로젝트 makefile을 호출 할 때 재귀 와 달리 .
Maxim Egorushkin

3
이것은 CMake의 중요한 약점입니다. GNU make에는 주름이 있지만, 배우는 데 시간이 걸리면 매우 강력하고 다목적이며 엄청난 양의 플랫폼에서 작동합니다. 분석 할 완전한 의존성 트리가없는 것은 구글이 '재귀 적으로 유해한 것으로 간주한다'는 중대한 결함이다.
Erik Alapää

1
@ ErikAlapää 나는 기사를 자세히 읽을 것이지만, 언뜻보기에 재귀 깊이가 데이터 중심 인 재귀 적 make에 대해 이야기하는 것처럼 보입니다 (즉, 소스 디렉토리 깊이 등에 의존합니다). CMake의 경우는 그렇지 않습니다. 프로젝트 구조에 관계없이 make 호출의 총 깊이는 항상 3입니다. 일부 비트는 모두 하나가 아닌 서브 메이크 파일에 위임되지만 프로젝트 구조는 어떤 식으로도 반영 되지 않습니다 . 또한, 서브 메이크 파일은 실제로 "자체 포함"되지 않으므로 오버 / 언더 종속성 문제가 발생하지 않습니다.
문헌 : Angew는 더 이상 자랑 SO의없는

39

CMake가 "빌드 생성기"라는 말은 일반적인 오해입니다.

기술적으로 잘못된 것은 아닙니다. 작동 방식 만 설명하지만 작동 방식은 설명하지 않습니다.

질문의 맥락에서 그들은 똑같은 일을합니다 : 많은 C / C ++ 파일을 가져 와서 바이너리로 바꿉니다.

그렇다면 실제 차이점은 무엇입니까?

  • CMake는 훨씬 더 높은 수준입니다. 빌드 코드를 훨씬 적게 작성하지만 범용 빌드에도 사용할 수있는 C ++를 컴파일하도록 조정되었습니다. make내장 C / C ++ 규칙도 있지만 대부분 쓸모가 없습니다.

  • CMake두 단계의 빌드를 수행합니다 그것의 낮은 수준의 빌드 스크립트를 생성 ninja하거나 make다른 많은 발전기 나, 그리고 당신은 그것을 실행합니다. 일반적으로 쌓여있는 모든 셸 스크립트 조각 Makefile은 생성 단계에서만 실행됩니다. 따라서 CMake빌드 속도가 훨씬 빨라질 수 있습니다.

  • 의 문법은 make의 것보다CMake 외부 도구를 지원하기가 훨씬 쉽습니다 .

  • make아티팩트를 빌드 하면 빌드 된 방식을 잊어 버립니다. 어떤 소스에서 만들어졌으며 어떤 컴파일러 플래그입니까? CMake그것을 추적하고 make당신에게 맡깁니다. 라이브러리 소스 중 하나는 이전 버전 이후 제거 된 경우 Makefile, make그것을 다시하지 않을 것이다.

  • 최신 CMake(버전 3.something으로 시작)은 "대상"간의 종속성 측면에서 작동합니다. 대상은 여전히 ​​단일 출력 파일 (슬프게도)이지만 전 이적 (CMake 용어에서 "공개"/ "인터페이스") 종속성을 가질 수 있습니다. 이러한 전이 종속성은 종속 패키지에 노출되거나 종속 패키지에서 숨겨 질 수 있습니다. CMake디렉토리도 관리합니다. 를 사용하면 make파일 별 및 디렉토리 별 관리 수준을 유지할 수 있습니다.

make플래그 파일을 사용하여 마지막 두 간격을 처리하는 데 무언가를 코딩 할 수 있지만 사용자는 스스로해야합니다. make포함 않습니다 튜링 완전한 언어 (심지어이, 때로는 세 계산 계략을 ), 그들 모두 끔찍하다.

솔직히 말해서, 이것은 무엇 CMakemake그들의 언어는 꽤 끔찍한 - 공통점

  • 그들은 유형이 없습니다.
  • 배열이없고 공백으로 구분 된 문자열 만 있으므로 지옥에서 벗어날 수 있습니다.
  • 일반적으로 전역 변수를 설정하여 인수를 함수에 전달합니다. (이것은 현대 CMake에서 다루어지고 있습니다-변수는 이제 네임 스페이스를 가질 수 있습니다. 대상은 속성의 네임 스페이스입니다)
  • 정의되지 않은 변수를 참조하는 것은 기본적으로 자동 무시됩니다.

시작하기.

그러나 CMake훨씬 적은 수의 코드 줄을 작성하십시오.


1
여기에 몇 가지 좋은 정보가 있지만 한 가지 언급은 완전히 잘못되었습니다. cmake에는 많은 빌드 시스템 작업에 중요한 적절한 LIST 함수가 있기 때문에 LIST 유형이 있습니다. cmake.org/cmake/help/git-master/command /list.html
해결

나는 그것을 "완전히"잘못이라고 부르지 않을 것이지만 정정 해 주셔서 감사합니다.
Victor Sergienko
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.