Cmake против создания образцов кодов?
Мне было интересно, есть ли какой-нибудь пример кода для Makefile
с (make
) а также CMakeLists.txt
(cmake
) что оба делают одно и то же (единственное отличие состоит в том, что один написан на make
а другой в cmake
).
Я пытался найти 'cmake vs make', но я не нашел ни одного сравнения кода. Было бы действительно полезно понять различия, даже если бы только для простого случая.
3 ответа
Следующий 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 $@
%.o: %.cpp
$(CPP) $(CFLAGS) $(INCDIR) -fPIC $< -o $@
Вот 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 или VC++ или MinGW + Msys на Windows). Система сборки может быть передана в CMake в качестве параметра; тем не менее, CMake делает разумный выбор по умолчанию в зависимости от конфигурации вашей системы. Во-вторых, вы выполняете фактическую сборку в выбранной системе сборки.
Исходники и инструкции по сборке доступны по адресу https://github.com/rhoelzel/make_cmake.
Возьмите какое-нибудь программное обеспечение, которое использует CMake в качестве своей системы сборки (в качестве примера можно выбрать множество проектов с открытым исходным кодом). Получить исходный код и настроить его с помощью CMake. Читайте получившиеся make-файлы и наслаждайтесь.
Следует иметь в виду, что эти инструменты не отображаются один на один. Наиболее очевидное отличие заключается в том, что CMake сканирует зависимости между различными файлами (например, заголовок C и исходные файлы), тогда как make оставляет это авторам make-файлов.
Если этот вопрос о образце Makefile
выход из CMakeList.txt
затем проверьте исходники cmake-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) против создания правил
В Makefile
rules and recipes
используются вместо functions
, В дополнение к function
-подобная особенность, rules and recipes
обеспечить цепочки. Мой минималистичный Makefile
будет выглядеть следующим образом,
-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. Некоторые неявные переменные также актуальны здесь.
Обратите внимание, что Makefile
предоставляет детали recipe
показ how
сборка может быть сделана. Можно написать executable.mk
сохранить детали, определенные в одном файле. Таким образом, make-файл может быть уменьшен, как я показал ранее.
Внутренние переменные в CMake
а также Make
Сейчас немного продвинулись, в CMake
мы можем установить флаг компилятора следующим образом:
set(CMAKE_C_FLAGS "-Wall")
Пожалуйста, узнайте больше о CMake
переменные по умолчанию в CMakeCache.txt
файл. CMake
код выше будет эквивалентен Make
код ниже,
CFLAGS = -Wall
Обратите внимание, что CFLAGS
является внутренней переменной в Make
, так же, CMAKE_C_FLAGS
является внутренней переменной в CMake
,
добавление include и путь к библиотеке в CMake
Мы можем сделать это в cmake
используя функции.
target_include_directories(testapp PRIVATE "myincludes")
list(APPEND testapp_LIBRARIES
mytest mylibrarypath
)
target_link_libraries(testapp ${testapp_LIBRARIES})
Против добавления include и пути к библиотеке в Make
Мы можем добавить include и библиотеки, добавив строки, подобные следующим,
INCLUDES += -Imyincludes
LIBS += -Lmylibrarypath -lmytest
Обратите внимание, что приведенные выше строки могут быть сгенерированы из инструментов auto-gen или pkg-config. (хотя Makefile не зависит от инструментов автоконфигурации)
CMake настроить / твик
Обычно можно генерировать некоторые config.h
файл так же, как auto-config
инструменты с помощью configure_file
функция. Можно сделать больше трюков при написании пользовательских функций. И, наконец, мы можем выбрать конфигурацию, как показано ниже,
cmake --build . --config "Release"
Можно добавить некоторые настраиваемые параметры, используя option
функция.
Makefile настроить / настроить
Если каким-то образом нам нужно скомпилировать его с некоторым отладочным флагом, мы можем вызвать make
лайк,
make CXXFLAGS=NDEBUG
Я думаю, что внутренние переменные, Makefile-rules
а также CMake-functions
Хорошее начало для сравнения, удачи в копании.