Cmake против кода образца?

Мне было интересно, есть ли какой-нибудь пример кода для Makefile (make) и CMakeLists.txt (cmake), которые делают то же самое (единственное отличие состоит в том, что он написан в make и другой в cmake).

Я пробовал искать "cmake vs make", но никогда не обнаружил никаких кодовых сравнений. Было бы очень полезно понять различия, даже если бы это был простой случай.

Ответ 1

Следующий файл Makefile создает исполняемый файл с именем prog из источников prog1.c, prog2.c, prog3.c and main.c. prog связан с libmystatlib.a и libmydynlib.so, которые также построены из источника. Кроме того, prog использует библиотека libstuff.a в stuff/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 [email protected] 
%.o: %.cpp
    $(CPP) $(CFLAGS) $(INCDIR) -fPIC  $< -o [email protected] 

Вот CMakeLists.txt, который делает (почти) то же самое, с некоторыми комментариями, чтобы подчеркнуть сходство с Makefile:

#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) и многие другие. Тем не менее, более неясные настройки могут быть реализованы вручную в CMake так же, как и в Makefile (с помощью COMPILE_FLAGS и аналогичные свойства). Конечно, CMake действительно начинает сиять, когда третья сторона библиотеки (например, OpenGL) включены в переносимую манеру.

  • Процесс сборки имеет один шаг, если вы используете Makefile, а именно: введите make в командной строке. Для CMake есть два шага: во-первых, вам нужно настроить среду сборки (либо набрав cmake <source_dir> в каталоге сборки, либо запустив некоторый клиент GUI). Это создает Makefile или что-то эквивалентное, в зависимости от выбранной вами системы сборки (например, make в Unixes или VС++ или MinGW + Msys в Windows). Система сборки может быть передана CMake в качестве параметра; однако CMake делает разумные варианты по умолчанию в зависимости от конфигурации вашей системы. Во-вторых, вы выполняете фактическую сборку в выбранной системе сборки.

Источники и инструкции по созданию доступны в https://github.com/rhoelzel/make_cmake.

Ответ 2

Захватите некоторое программное обеспечение, которое использует CMake как свою систему builds (в ​​качестве примера представлено множество проектов с открытым исходным кодом). Получите исходный код и настройте его с помощью CMake. Прочитайте полученные файлы и наслаждайтесь.

Следует помнить, что эти инструменты не сопоставляются друг с другом. Наиболее очевидным отличием является то, что CMake сканирует зависимости между разными файлами (например, заголовок C и исходные файлы), тогда как make оставляет это авторам файлов.