Cmake vs制作示例代码?

jlo*_*jlo 111 makefile cmake

我想知道是否有任何示例代码MakefileS( make)和CMakeLists.txt(cmake),这两个做同样的事情(唯一的区别在于,一个是写在make和其他的cmake).

我试着寻找'cmake vs make',但我从来没有找到任何代码比较.理解这些差异真的很有帮助,即使只是为了一个简单的案例.

Rob*_*rto 115

以下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 $@ 
Run Code Online (Sandbox Code Playgroud)

这是一个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")
Run Code Online (Sandbox Code Playgroud)

在这个简单的例子中,最重要的区别是:

  • CMake识别哪些编译器用于哪种源.此外,它为每种类型的目标调用正确的命令序列.因此,没有像$(CC)...,$(RANLIB)等命令的明确规范.

  • 处理包含头文件,库等的所有常用编译器/链接器标志被独立于平台/构建系统的命令所取代.

  • 通过将变量CMAKE_BUILD_TYPE设置为"Debug",或者在调用程序时将其传递给CMake,可以包含调试标志:$(CC) ....

  • CMake还提供平台独立包含'-fPIC'标志(通过POSITION_INDEPENDENT_CODE属性)和许多其他标志.尽管如此,更多模糊的设置可以在CMake中手动实现,也可以在Makefile中实现(通过使用$(RANLIB) ... 和类似的属性).当然,当第三方库(如OpenGL)以可移植的方式包含时,CMake真正开始闪耀.

  • 如果使用Makefile,则构建过程只有一步,即CMAKE_BUILD_TYPE在命令行键入.对于CMake,有两个步骤:首先,您需要设置构建环境(通过键入cmake -DCMAKE_BUILD_TYPE:STRING=Debug构建目录或运行某些GUI客户端).这会创建一个Makefile或类似的东西,具体取决于您选择的构建系统(例如,在Unix上使用或在Windows上使用VC++或MinGW + Msys).构建系统可以作为参数传递给CMake; 但是,CMake根据您的系统配置做出合理的默认选择.其次,您在选定的构建系统中执行实际构建.

有关源和构建说明,请访问https://github.com/rhoelzel/make_cmake.

  • Makefile是不是太复杂了?通过使用`CPPFLAGS`而不是`INCDIR`,可以使用内置规则,并且编译器的显式调用将是多余的.类似地,对于ar的处理,内置规则也可以覆盖它.另外,为什么要明确设置`CPP`和`CC`?它们已经通过`make`设置为良好的值,它们是预定义的变量.`make`也识别哪种编译器用于哪种源,内置规则很多. (2认同)

Tad*_*ski 6

获取一些使用CMake作为其构建系统的软件(有很多开源项目可供选择).获取源代码并使用CMake进行配置.阅读生成的makefile并享受.

有一点要记住,这些工具不是一对一映射的.最明显的区别是CMake扫描不同文件(例如C头文件和源文件)之间的依赖关系,而make则将其留给makefile作者.