Cmake学习笔记(一),Windows/linux 环境搭建配置,入门及示例代码

Cmake为跨平台创建工程的,很多开源的项目,都采用Cmake来编译,opencv,libjpeg,QT部分等,非常有必要学习一下了,Cmake简单的关系图

cmake / qmake
Windows:.sln 工程文件
Linux:Makefile
可执行程序

对cmake和qmake来说,他们用普通语法让用户来添加编译选项,cmake对应CMakeList,qmake对应.pro文件

cmake
CMakeList.txt
qmake
.pro

参考资料:https://blog.csdn.net/dbzhang800/article/details/6314073

郑重感谢此文博主,本文后半部分是将其笔记(1)进行C++文件的实现和所用API的梳理,简单解释了几个没有详细说的API,还有小的疏忽bug,顺便给修复了

Cmake安装和配置

Cmake最重要就是跨平台的使用了,统一套代码,在不同的平台下,生成工程文件,在Windows下生成的即使Visual Studio 工程,在linux下即生成MakeFile,方便在不同平台下管理代码

linux

在linux下,现在主流的操作系统的源里都包含,cmake,直接安装即可,安装,ccmake后面跟个参数,即CMakeList.txt所在文件夹(linux 下严格区分大小写,这点和windows 不同一定要注意),执行后就能生成Makefile 。以最简单的HelloWord为例,因为主要目的是为了学习Cmake,后续就不再写linux示例,所有试验均以windows的GUI的操作为准
我只写了一个CmakeHelloWord.cpp

// An highlighted block
#include <stdio.h>
#include <tchar.h>

int main()
{
	printf("Hello World!\n");
	return 0;
}

CMakeList.txt:

// An highlighted block
project(HELLO)
set(SRC_LIST CmakeHelloWord.cpp)
add_executable(hello ${SRC_LIST})

执行 came + list所在路径,就可以的倒Makefile
Makefile(读起来费劲,知道咋回事得了。。。):

// An highlighted block
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 2.8

# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target

#=============================================================================
# Special targets provided by cmake.

# Disable implicit rules so canonical targets will work.
.SUFFIXES:

# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =

.SUFFIXES: .hpux_make_needs_suffix_list

# Suppress display of executed commands.
$(VERBOSE).SILENT:

# A target that is always out of date.
cmake_force:
.PHONY : cmake_force

#=============================================================================
# Set environment variables for the build.

# The shell in which to execute make rules.
SHELL = /bin/sh

# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake

# The command to remove a file.
RM = /usr/bin/cmake -E remove -f

# Escaping for special characters.
EQUALS = =

# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /home/irisking/桌面/CmakeTest/1HelloWord/CmakeHelloWord

# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /home/irisking/桌面/CmakeTest/1HelloWord

#=============================================================================
# Targets provided globally by CMake.

# Special rule for the target edit_cache
edit_cache:
	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running interactive CMake command-line interface..."
	/usr/bin/cmake -i .
.PHONY : edit_cache

# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast

# Special rule for the target rebuild_cache
rebuild_cache:
	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
	/usr/bin/cmake -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache

# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast

# The main all target
all: cmake_check_build_system
	$(CMAKE_COMMAND) -E cmake_progress_start /home/irisking/桌面/CmakeTest/1HelloWord/CMakeFiles /home/irisking/桌面/CmakeTest/1HelloWord/CMakeFiles/progress.marks
	$(MAKE) -f CMakeFiles/Makefile2 all
	$(CMAKE_COMMAND) -E cmake_progress_start /home/irisking/桌面/CmakeTest/1HelloWord/CMakeFiles 0
.PHONY : all

# The main clean target
clean:
	$(MAKE) -f CMakeFiles/Makefile2 clean
.PHONY : clean

# The main clean target
clean/fast: clean
.PHONY : clean/fast

# Prepare targets for installation.
preinstall: all
	$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall

# Prepare targets for installation.
preinstall/fast:
	$(MAKE) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast

# clear depends
depend:
	$(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend

#=============================================================================
# Target rules for targets named hello

# Build rule for target.
hello: cmake_check_build_system
	$(MAKE) -f CMakeFiles/Makefile2 hello
.PHONY : hello

# fast build rule for target.
hello/fast:
	$(MAKE) -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/build
.PHONY : hello/fast

CmakeHelloWord.o: CmakeHelloWord.cpp.o
.PHONY : CmakeHelloWord.o

# target to build an object file
CmakeHelloWord.cpp.o:
	$(MAKE) -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/CmakeHelloWord.cpp.o
.PHONY : CmakeHelloWord.cpp.o

CmakeHelloWord.i: CmakeHelloWord.cpp.i
.PHONY : CmakeHelloWord.i

# target to preprocess a source file
CmakeHelloWord.cpp.i:
	$(MAKE) -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/CmakeHelloWord.cpp.i
.PHONY : CmakeHelloWord.cpp.i

CmakeHelloWord.s: CmakeHelloWord.cpp.s
.PHONY : CmakeHelloWord.s

# target to generate assembly for a file
CmakeHelloWord.cpp.s:
	$(MAKE) -f CMakeFiles/hello.dir/build.make CMakeFiles/hello.dir/CmakeHelloWord.cpp.s
.PHONY : CmakeHelloWord.cpp.s

# Help Target
help:
	@echo "The following are some of the valid targets for this Makefile:"
	@echo "... all (the default if no target is provided)"
	@echo "... clean"
	@echo "... depend"
	@echo "... edit_cache"
	@echo "... hello"
	@echo "... rebuild_cache"
	@echo "... CmakeHelloWord.o"
	@echo "... CmakeHelloWord.i"
	@echo "... CmakeHelloWord.s"
.PHONY : help

Windows

从官网下载,安装包,安装成功后(有时因为权限问题,需要cmd管理安装),使用GUI界面,配置好顶端的

Where is the source code:需要配置,源码所在路径,即根 CMakeList所在路径

Where to build the binaries:配置希望生成的工程所在位置
在这里插入图片描述
然后依次点击Configure ,选择需要生成的VS版本,点击Generate即可生产VS工程文件

示例工程

该系列工程,参考顶端参考资料链接,将其中代码自己实现了一遍,前面讲过的API后面不再重复

HelloWord

CmakeHelloWord.cpp:

// An highlighted block
#include <stdio.h>
#include <tchar.h>

int main()
{
	printf("Hello World!\n");
	return 0;
}

CMakeList.txt:

// An highlighted block
project(HELLO)
set(SRC_LIST CmakeHelloWord.cpp)
add_executable(hello ${SRC_LIST})

project:用来设置解决方案的名称 .sln
set:Cmake语法,将变量SRC_LIST 设置为CmakeHelloWord.cpp .vs@!#@$#
add_executable:在解决方案‘HELLO’下,建立一个应用程序工程hello,所需文件是SRC_LIST

将HelloWord拆成三个文件

Hello.cpp:

#include <stdio.h>
#include "hello.hpp"

void hello(const char * name)
{
    printf ("Hello %s!\n", name);
}

Hello.hpp:

#ifndef MSK_HELLO_
#define MSK_HELLO_
void hello(const char* name);
#endif //MSK_HELLO_

CmakeHelloWord.cpp:

// An highlighted block
#include "hello.hpp"

int main()
{
	hello("World");
	return 0;
}

CMakeList.txt:

// An highlighted block
project(HELLO)
set(SRC_LIST CmakeHelloWord.cpp Hello.cpp)
add_executable(hello ${SRC_LIST})

与测试一没有什么区别,无非是SRC_LIST增加了一个文件Hello.cpp

HelloWord方法封装成一个静态库

CMakeList.txt:

project(HELLO) 
set(LIB_SRC Hello.cpp) 
set(APP_SRC CmakeHelloWord.cpp) 
add_library(libhello ${LIB_SRC}) 
add_executable(hello ${APP_SRC}) 
target_link_libraries(hello libhello)
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

如果想改变生成的文件名,可以增加:

set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

add_library:解决方案下,增加一个静态库工程
target_link_libraries:是hello依赖libhello库
set_target_properties:更改生成文件名,即VS里,属性->常规->目标文件名,有个比较神奇的地方是,set_target_properties也会修改,app里依赖的动态库文件名
OUTPUT_NAME 也可以改为PREFIX,用来增加前缀

拆分源码路径

在源文件目录,应用所需源码放在src文件夹,库所需文件夹放在libhello

最外层目录的CMakeList.txt

project(HELLO)
add_subdirectory(src)
add_subdirectory(libhello)

src中的CMakeList.txt

include_directories(${PROJECT_SOURCE_DIR}/libhello)
set(APP_SRC CmakeHelloWord.cpp) 
add_executable(hello ${APP_SRC})
target_link_libraries(hello libhello)

libhello中的CMakeList.txt

set(LIB_SRC hello.cpp)
add_library(libhello ${LIB_SRC})
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

add_subdirectory:按顺序执目录里的CMakeList

修改文件输出路径

一种办法是修改根目录的 CMakeList.txt 文件

project(HELLO)
add_subdirectory(src bin)
add_subdirectory(libhello lib)

另一种方法是,修改各自工程的CMakeList文件

include_directories(${PROJECT_SOURCE_DIR}/libhello)
set(APP_SRC CmakeHelloWord.cpp) 
add_executable(hello ${APP_SRC})
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
target_link_libraries(hello libhello)
set(LIB_SRC hello.cpp)
add_library(libhello ${LIB_SRC})
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

EXECUTABLE_OUTPUT_PATH
LIBRARY_OUTPUT_PATH
CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG
CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG
这几个之间有区别,下次单独说

修改为动态库

只需要在add_library命令中加入一个SHARED参数:

add_library(libhello SHARED ${LIB_SRC})

修改 hello.hpp 文件

#ifndef MSK_HELLO_
#define MSK_HELLO_
#if defined _WIN32 
	#if LIBHELLO_BUILD 
		#define LIBHELLO_API __declspec(dllexport) 
	#else 
		#define LIBHELLO_API __declspec(dllimport) 
	#endif 
#else 	
	#define LIBHELLO_API 
#endif

LIBHELLO_API void hello(const char* name);
#endif //MSK_HELLO_

修改 libhello/CMakeList.txt 文件

set(LIB_SRC hello.cpp)
add_definitions("-DLIBHELLO_BUILD")
add_library(libhello SHARED ${LIB_SRC})
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

add_definitions:增加预处理的宏定义,相当于,VS里的预编译头

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值