[makefile] Cmake 대 make 샘플 코드?

모든 샘플 코드가 있다면 궁금 해서요 Makefile의 ( make) 및 CMakeLists.txt( cmake) 모두 (유일한 차이점은 하나에 기록되어있는 같은 일을한다는 make와 다른 cmake).

‘cmake vs make’를 찾아 보았지만 코드 비교를 찾지 못했습니다. 단순한 경우라도 차이점을 이해하는 것이 정말 도움이 될 것입니다.



답변

다음 Makefile은 prog소스에서 이름이 지정된 실행 파일을 빌드 합니다
prog1.c, prog2.c, prog3.c and main.c. prog에 연결되어 libmystatlib.a
libmydynlib.so모두 또한 소스에서 내장되어있다. 또한, prog라이브러리 사용 libstuff.astuff/lib와의 헤더를 stuff/include. Makefile은 기본적으로 릴리스 대상을 빌드하지만 디버그 대상도 제공합니다.

#Makefile
CC = gcc
CPP = g++
RANLIB = ar rcs
RELEASE = -c -O3
DEBUG = -c -g -D_DEBUG
INCDIR = -I./stuff/include
LIBDIR = -L./stuff/lib -L.
LIBS = -lstuff -lmystatlib -lmydynlib
CFLAGS = $(RELEASE)

PROGOBJS = prog1.o prog2.o prog3.o

prog: main.o $(PROGOBJS) mystatlib mydynlib
    $(CC) main.o $(PROGOBJS) $(LIBDIR) $(LIBS) -o prog
debug: CFLAGS=$(DEBUG)
debug: prog

mystatlib: mystatlib.o
    $(RANLIB) libmystatlib.a mystatlib.o
mydynlib: mydynlib.o
    $(CPP) -shared mydynlib.o -o libmydynlib.so

%.o: %.c
    $(CC) $(CFLAGS) $(INCDIR) $< -o $@
%.o: %.cpp
    $(CPP) $(CFLAGS) $(INCDIR) -fPIC  $< -o $@

다음은 CMakeLists.txtMakefile의 유사점에 밑줄을 긋는 몇 가지 주석과 함께 (거의) 똑같은 작업을 수행합니다.

#CMakeLists.txt
cmake_minimum_required(VERSION 2.8)                    # stuff not directly
project(example)                                       # related to building

include_directories(${CMAKE_SOURCE_DIR}/stuff/include) # -I flags for compiler
link_directories(${CMAKE_SOURCE_DIR}/stuff/lib)        # -L flags for linker

set(PROGSRC prog1.c prog2.c prog3.c)                   # define variable

add_executable(prog main.c ${PROGSRC})                 # define executable target prog, specify sources
target_link_libraries(prog mystatlib mydynlib stuff)   # -l flags for linking prog target

add_library(mystatlib STATIC mystatlib.c)              # define static library target mystatlib, specify sources

add_library(mydynlib SHARED mydynlib.cpp)              # define shared library target mydynlib, specify sources
#extra flags for linking mydynlib
set_target_properties(mydynlib PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
#alternatively:
#set_target_properties(mydynlib PROPERTIES COMPILE_FLAGS "-fPIC")

이 간단한 예에서 가장 중요한 차이점은 다음과 같습니다.

  • CMake는 어떤 종류의 소스에 사용할 컴파일러를 인식합니다. 또한 각 대상 유형에 대해 올바른 명령 시퀀스를 호출합니다. 따라서, 같은 명령의 명시 적 지정이없는 $(CC) ..., $(RANLIB) ...등등은.

  • 헤더 파일, 라이브러리 등을 포함하는 모든 일반적인 컴파일러 / 링커 플래그는 플랫폼 독립적 / 빌드 시스템 독립적 명령으로 대체됩니다.

  • 디버깅 플래그는 변수 CMAKE_BUILD_TYPE를 “Debug”로 설정하거나 프로그램을 호출 할 때 CMake에 전달하여 포함됩니다 cmake -DCMAKE_BUILD_TYPE:STRING=Debug..

  • CMake는 또한 ‘-fPIC’플래그 ( POSITION_INDEPENDENT_CODE속성을 통해 ) 및 기타 여러 플랫폼의 독립적 인 포함을 제공합니다 . 그래도 더 모호한 설정은 Makefile뿐만 아니라 CMake에서도 직접 구현할 수 있습니다 ( COMPILE_FLAGS
    및 유사한 속성 사용). 물론 CMake는 타사 라이브러리 (예 : OpenGL)가 이식 가능한 방식으로 포함될 때 실제로 빛을 발합니다.

  • Makefile을 사용하는 경우 빌드 프로세스에는
    make
    명령 줄에 입력하는 한 단계가 있습니다 . CMake의 경우 두 단계가 있습니다. 먼저 빌드 환경을 설정해야합니다 ( cmake <source_dir>빌드 디렉토리 에 입력 하거나 일부 GUI 클라이언트를 실행하여). 이렇게하면 선택한 빌드 시스템에 따라 Makefile 또는 이와 동등한 것이 생성됩니다 (예 : Unixes의 경우 make, Windows의 경우 VC ++ 또는 MinGW + Msys). 빌드 시스템은 매개 변수로 CMake에 전달할 수 있습니다. 그러나 CMake는 시스템 구성에 따라 합리적인 기본 선택을합니다. 둘째, 선택한 빌드 시스템에서 실제 빌드를 수행합니다.

소스 및 빌드 지침은 https://github.com/rhoelzel/make_cmake 에서 사용할 수 있습니다 .


답변

빌드 시스템으로 CMake를 사용하는 일부 소프트웨어를 가져옵니다 (예로 선택할 수있는 많은 오픈 소스 프로젝트가 있습니다). 소스 코드를 가져 와서 CMake를 사용하여 구성합니다. 결과 메이크 파일을 읽고 즐기십시오.

이러한 도구는 일대일로 매핑되지 않는다는 점을 명심해야합니다. 가장 분명한 차이점은 CMake는 서로 다른 파일 (예 : C 헤더 및 소스 파일) 간의 종속성을 스캔하는 반면 make는이를 makefile 작성자에게 맡긴다는 것입니다.


답변

이 질문이 파일 의 샘플 Makefile출력에 관한 것이라면 CMakeList.txtcmake-backend 소스를 확인하고 그러한 Makefile. @Roberto의 회신에 추가하지 않으면 세부 정보를 숨기고 간단하게 만들려고합니다.

CMake 함수

Make규칙 및 레시피를위한 유연한 도구 이지만 CMake구성 기능도 추가하는 추상화 계층입니다.

내 평야 CMakeLists.txt는 다음과 같이 보일 것입니다.

cmake_minimum_required(VERSION 2.8)
project(example)
file(GLOB testapp_SOURCES *.cc)
add_executable(testapp ${testapp_SOURCES})

빌드 를 CMake숨길 how수 있습니다. 우리 what는 입력과 출력 만을 지정했습니다 .

CMakeLists.txt에 정의 된 함수 호출 목록 이 포함됩니다 cmake.

(CMake 기능) Vs Make 규칙

에서 대신 사용된다 . 유사 기능 외에도 체인을 제공하십시오. 내 미니멀리즘 은 다음과 같이 보일 것입니다.Makefilerules and recipesfunctionsfunctionrules and recipesMakefile

-include "executable.mk"
TARGETS=testapp.bin
all:${TARGETS}

(가) 동안 executable.mk다음과 같이 표시됩니다,

SOURCES=$(wildcard *.cpp)
OBJECTS=$(SOURCES:.cpp=.o)
DEPS=$(SOURCES:.cpp=.d)

%.bin:$(OBJECTS)
    $(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LIBS)

.PHONY: all clean

clean:
    $(RM) $(OBJECTS) $(DEPS) $(TARGETS)

-include $(DEPS)

처음부터 Makefile다음과 같이 시작하겠습니다 .

all: testapp.bin

testapp.bin:sourcea.o sourcb.o
    $(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(LIBS)

.PHONY: all clean

clean:
    $(RM) $(OBJECTS) testapp.bin

여기 에서이 스 니펫을 가져와 수정했습니다. 일부 암시 적 규칙이이 파일에 추가되며 이는 makefile-documentation에서 찾을 수 있습니다. 일부 암시 적 변수도 여기에 관련됩니다.

참고, Makefile세부 사항 제공 recipe보여주는 how빌드가 수행 할 수 있습니다. executable.mk하나의 파일에 정의 된 세부 사항을 유지하기 위해 쓸 수 있습니다. 이런 식으로 앞에서 보여준 것처럼 makefile을 줄일 수 있습니다.

CMake및 내부 변수Make

이제 조금 발전해 CMake가면서 다음과 같이 컴파일러 플래그를 설정할 수 있습니다.

set(CMAKE_C_FLAGS "-Wall")

파일의 CMake기본 변수에 대해 자세히 알아보십시오 CMakeCache.txt. CMake상기 코드에 해당 할 것이다 Make아래 코드

CFLAGS = -Wall

CFLAGS의 내부 변수 Make와 동일한 방법으로, CMAKE_C_FLAGS내부 변수이다 CMake.

CMake에 포함 및 라이브러리 경로 추가

cmake함수 를 사용하여 할 수 있습니다 .

target_include_directories(testapp PRIVATE "myincludes")
list(APPEND testapp_LIBRARIES
    mytest mylibrarypath
)
target_link_libraries(testapp ${testapp_LIBRARIES})

Make에 포함 및 라이브러리 경로 추가 대

다음과 같은 줄을 추가하여 포함 및 라이브러리를 추가 할 수 있습니다.

INCLUDES += -Imyincludes
LIBS += -Lmylibrarypath -lmytest

위의 행은 자동 생성 도구 또는 pkg-config에서 생성 할 수 있습니다. (Makefile은 자동 구성 도구에 종속되지 않음)

CMake 구성 / tweek

일반적으로 기능 을 사용하여 도구 config.h처럼 일부 파일 을 생성 할 수 있습니다. 사용자 정의 함수를 작성하는 더 많은 트릭을 수행 할 수 있습니다. 마지막으로 다음과 같은 구성을 선택할 수 있습니다.auto-configconfigure_file

cmake --build . --config "Release"

option기능을 사용하여 몇 가지 구성 가능한 옵션을 추가 할 수 있습니다 .

Makefile 구성 / 조정

어떤 식 으로든 디버그 플래그로 컴파일해야한다면 다음 make과 같이 호출 할 수 있습니다 .

make CXXFLAGS=NDEBUG

나는 내부 변수를 생각 Makefile-rules하고 CMake-functions더 파고와 비교, 행운을 위해 좋은 시작이다.


답변