0x01 Why CMake?
在初学C语言时我们会了GCC基本编译命令:
gcc -o main main.c && chmod +x main
./main # Hello World!
突然有了一个中型的小程序,大约有10个左右文件参与。于是转用Makefile定义每个文件之间的依赖:
CFLAGS=-static -Wall -g -I/usr/local/uriparser/include/uriparser -I./vendor/buffer/src
LDFLAGS=-L/usr/local/uriparser/lib -luriparser -L./vendor/buffer/build -lbuffer
SOURCES=$(wildcard src/**/*.c src/*.c)
OBJECTS=$(patsubst %.c,%.o,$(SOURCES))
TARGET=bin/http
all: $(TARGET)
$(TARGET): build $(OBJECTS)
$(CC) $(LDFLAGS) -o $@ $(OBJECTS)
build:
@mkdir -p bin
dev:CFLAGS+=-DNDEBUG
dev: all
clean:
rm -rf bin/http src/*.o *.dSYM
再后来,程序越来越大。为了模块管理方便,以模块内Makefile为单位,想多模块协作。$(TARGET): build $(OBJECTS) $(CC) $(LDFLAGS) -o $@ $(OBJECTS)这些语句不再能够一句描述清楚各模块的关系。于是来到工程构建工具链最顶端CMake。
cmake_minimum_required(VERSION 3.5)
# Set the project name
project (protobuf_example)
# find the protobuf compiler and libraries
find_package(Protobuf REQUIRED)
# check if protobuf was found
if(PROTOBUF_FOUND)
message ("protobuf found")
else()
message (FATAL_ERROR "Cannot find Protobuf")
endif()
# Generate the .h and .cxx files
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS AddressBook.proto)
# Print path to generated files
message ("PROTO_SRCS = ${PROTO_SRCS}")
message ("PROTO_HDRS = ${PROTO_HDRS}")
# Add an executable
add_executable(protobuf_example
main.cpp
${PROTO_SRCS}
${PROTO_HDRS})
target_include_directories(protobuf_example
PUBLIC
${PROTOBUF_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR}
)
# link the exe against the libraries
target_link_libraries(protobuf_example
PUBLIC
${PROTOBUF_LIBRARIES}
)
不说简单,但至少结构明了。这种简明的结构使得cmake地位和实际上VistualStudio的.sln一样,均具有以便捷成本构建大型程序的管理能力。
0x02 通用C/C++程序
cmake_minimum_required(VERSION 3.22)
project(clion)
set(CMAKE_CXX_STANDARD 11)
include_directories(include)
add_executable(clion main.cpp)
0x03 安卓Native
gradle指定CMakelist.txt文件位置,随后即可开始开发
// app.gradle
android {
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt"
}
}
}
// CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
include_directories(include)
add_library(mytest SHARED mytest.cpp)
target_link_libraries(mytest android log)
// 随后mytest.cpp和之前Android.mk体系一样正常开发即可