IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> c/c++编译:使用CMAKE进行跨平台开发 -> 正文阅读

[C++知识库]c/c++编译:使用CMAKE进行跨平台开发


前言

本文介绍跨平台cmake的编写,主要是linux和windows用cmake对项目的编译。这是一个通用模板,能够应用到更加复杂的项目中,项目例子用https://blog.csdn.net/qq_36472340/article/details/126395749?spm=1001.2014.3001.5502这篇文章。

一、CMakeList.txt如何高效组织项目

一个简洁的工程,一般把源码放在一个目录src,将编译结果放在一个目录build,将头文件、库、可执行文件放在一个目录install。为了高效组织项目,CMakeList.txt应该如下图分布:
在这里插入图片描述

二、常用的CMAKE编译命令

1.cmake_minimum_required (VERSION 2.8) 指定cmake的最低版本,比指定的cmake版本低则不会编译。
2.PROJECT(test) 指定工程名称,MSVC编译时生成test.sln项目,其他编译器没有体现
3.ADD_DEFINITIONS(-DEXPORTS) 添加宏
4.CMAKE_C_FLAGS、指定gcc编译选项;CMAKE_CXX_FLAGS指定g++编译选项
5. CMAKE_C_COMPILER 指定编译所用的c编译器;CMAKE_CXX_COMPILER指定c++编译器。通过设置这两个参数能够实现任何平台上的交叉编译。如果不设置,则会默认选择编译器,我的平台下:linux平台/usr/bin/cc;windows用vsual c++编译C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe。
6.ADD_SUBDIRECTORY(src) 包含的子目录,之前设置的东西在整个src当中都生效。
7. INCLUDE_DIRECTORIES() 添加头文件相当于gcc中的 -I。
8. *FILE(GLOB_RECURSE SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} .c) 将cmakelist.txt所在目录下的所有.c文件赋给SRC_LIST。
9. aux_source_directory(dir,var) 包含目录下的所有源文件,可以与8相互交换。
10. ADD_LIBRARY(${SHARED_NAME} SHARED ${SRC_LIST} ${HEADER_LIST}) 生成动态库,没有SHARED则生成静态库。
11. LINK_DIRECTORIES 添加库文件收缩路径,相当于-L。引用工程中生成的库不需要该命令,引用第三方库需要加上该命令。
12. TARGET_LINK_LIBRARIES 链接动态库,相当于gcc中的-l。
13. **LINK_LIBRARYS(“…/…/shared.so”)添加依赖库文件,相当于-I, 需要全路径,并且只能用于add_executable之前。
14. ADD_EXECUTABLE 编译可执行文件。
15. INSTALL(TARGETS ${SHARED_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/) 安装库或者可执行文件。
** INSTALL(FILES add.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/)
安装文件到指定目录下,编译完成后才会执行INSTALL操作,不能在编译过程中引用安装目录中的库或者头文件。
INSTALL(DIRECTORY …)安装目录。
16.CMAKE常用变量:LIBRARY_OUTPUT_PATH指定库文件输出路径;EXEC_OUTPUT_PATH指定可执行文件输出路径,可以替代INSTALL;CMAKE_CUREENT_SOURCE_DIR cmakelist所在目录;CMAKE_INSTALL_PREFIX目标文件安装目录。$ENV{NAME}系统环境变量。
注意: CMAKE中的命令大小写均可。

三、CMakeList.txt脚本的编写

从最外层目录一直到最里面的CMakeList.txt脚本如下:

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)
#指定工程名称
PROJECT(test)
#通过不同的编译器进行参数设置,visual studio编译器为MSVC
if("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
    if("${CMAKE_OS_ARCH}" STREQUAL "x86")
        SET(CMAKE_C_FLAGS_DEBUG "-m32 -D_GNU_SOURCE -O0 -g -ggdb -Wall")
        SET(CMAKE_C_FLAGS_RELEASE "-m32 -D_GNU_SOURCE -O2 -Wall -DNDEBUG")
    elseif("${CMAKE_OS_ARCH}" STREQUAL "X64")
        SET(CMAKE_C_FLAGS_DEBUG "-fPIC -m64 -D_GNU_SOURCE -O0 -g -ggdb -Wall")
        SET(CMAKE_C_FLAGS_RELEASE "-fPIC -m64 -D_GNU_SOURCE -O2 -Wall -Wl,-Bsymbolic -Wl,-Bsymbolic-functions -DNDEBUG")
    endif()
elseif("CMAKE_C_COMPILER_ID" STREQUAL "MSVC")
    SET(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -D_CRT_SECURE_NO_WARNINGS=1 /Zi /Od /Ob0 /RTC1 /MDd /W4 /utf-8")
    SET(CMAKE_C_FLAGS_RELEASE "$ENV{CFLAGS} -D_CRT_SECURE_NO_WARNINGS=1 /Ob2 /MD /W4 /utf-8")
endif()
#设置编译器选项
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
    SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_DEBUG})
elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS_RELEASE})
endif()
#windows平台导出函数需要加宏
if("${CMAKE_OS_TYPE}" STREQUAL "windows")
    ADD_DEFINITIONS(-DEXPORTS)
    ADD_DEFINITIONS(-DWIN32)
endif()
#添加src子目录,上面的设置在src当中都生效
ADD_SUBDIRECTORY(src)
#添加头文件和子目录
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/shared")
ADD_SUBDIRECTORY(shared)

INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/static")
ADD_SUBDIRECTORY(static)

ADD_SUBDIRECTORY(main)

shared目录下

#获取当前目录下所有的.c和.h文件
FILE(GLOB_RECURSE SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)
FILE(GLOB_RECURSE HEADER_LIST RELATIVE $(CMAKE_CURRENT_SOURCE_DIR) *.h)
#设置动态库的名字
SET(SHARED_NAME shared)
#生成动态库
ADD_LIBRARY(${SHARED_NAME} SHARED ${SRC_LIST} ${HEADER_LIST})
#安装头文件和库目录
INSTALL(TARGETS ${SHARED_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/)
INSTALL(FILES add.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/)

static目录下

FILE(GLOB_RECURSE SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)
FILE(GLOB_RECURSE HEADER_LIST RELATIVE $(CMAKE_CURRENT_SOURCE_DIR) *.h)

SET(STATIC_NAME static)
#编译静态库
ADD_LIBRARY(${STATIC_NAME}  ${SRC_LIST} ${HEADER_LIST})

INSTALL(TARGETS ${STATIC_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/)
INSTALL(FILES multi.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/)

main目录下

FILE(GLOB_RECURSE SRC_LIST RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.c)
SET(EXE_NAME main)
ADD_DEFINITIONS(-DDEBUG)
#编译可执行文件
ADD_EXECUTABLE(${EXE_NAME} ${SRC_LIST})
#编译出的库,不用指定库的路径,直接写出需要链接的库即可
TARGET_LINK_LIBRARIES(${EXE_NAME} shared static)
INSTALL(TARGETS ${EXE_NAME} DESTINATION  ${CMAKE_INSTALL_PREFIX}/bin/)

四、运行cmake windows脚本的编写

@echo off

set OS_TYPE=windows
set OS_ARCH=x86
set WIN_PLAT=Win32
set COMPILE_TYPE=Release
set INSTALL_DIR=%cd%/install
@REM 解析编译选项
:loop
     set arg=%1
	 if %arg%! == ! goto end
     if %arg% == -a (
         set OS_ARCH=%2
         set WIN_PLAT=%2
         shift
     ) else if %arg% == -d (
         set COMPILE_TYPE=Debug
     ) else if %arg% == -i (
         set INSTALL_DIR =%2
         shift
     ) else if %arg% == -h (
		 call:usage
		 goto:eof
	 ) else (
         echo unknow param!
     )
     shift
     goto loop
:end
@REM 设置cmake的安装目录
set INSTALL_PREFIX=%INSTALL_DIR%/%OS_TYPE%/%OS_ARCH%/%COMPILE_TYPE%/
echo %INSTALL_PREFIX%
@REM 设置cmake的编译变量
set cmd=cmake .. -DCMAKE_INSTALL_PREFIX=%INSTALL_PREFIX% -DCMAKE_OS_TYPE=%OS_TYPE% -DCMAKE_BUILD_TYPE=%COMPILE_TYPE%  -DCMAKE_OS_ARCH=%OS_ARCH%
@REM visual studio 2019 编译平台的设置
if %OS_ARCH% == x86 (
      set cmd=%cmd% -G "Visual Studio 16 2019" -A Win32
 ) else (
    set cmd=%cmd% -G "Visual Studio 16 2019" -A x64
)
@REM 构建visual studio 项目
cd %cd%/build
 %cmd%
@REM  删掉缓存,下一次编译才能够重新构建工程
 del /q/a/f CMakeCache.txt
cd ..
@REM 编译visual studio项目
 set build_project=MSBuild %cd%\build\INSTALL.vcxproj /t:Rebuild  /p:Configuration=%COMPILE_TYPE% /p:Platform=%WIN_PLAT%

%build_project%
goto:build_end

:usage
    echo "-a  set OS_ARCH"
    echo "-d  set COMPILE_TYPE"
    echo "-i  set INSTALL_DIR"
goto:eof

:build_end
	echo build over

脚本使用: build.bat -a x86 -d 编译x86平台下的Debug版本。
build.bat -a x64 编译x64平台下的release版本。
-G “Visual Studio 16 2019” -A Win32 这个是使用visual studio 2019编译x86时的设置,不同的版本设置不一样,可以在这个链接下面查看https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2016%202019.html
工程构建后build目录如下:
在这里插入图片描述
编译后动态库的输出目录为./build/shared/debug/shared.dll。当mian程序链接时,链接器自动台这个目录下进行链接;INSTALL安装时将这个目录下的动态库安装到指定的位置。
注意: 编译时一定要在build目录下进行编译,不然编译后的东西将会分布在目录中的各个地方,不方便整理。

五、运行cmake linux脚本的编写

#!/bin/bash

OS_TYPE=linux
OS_ARCH=x86
COMPILE_TYPE=Release
INSTALL_DIR=$PWD/install

show_help() {
    cat<<EOF
    -a set OS_ARCH
    -d set COMPILE_TYPE
    -i set INSTALL_DIR
EOF
}
#解析编译选项,a:会解析成-a :表示-a后面需要跟上参数
while getopts "a:di:h" opt; do
  case $opt in
    a)
      OS_ARCH="$OPTARG"
      ;;
    d)
      COMPILE_TYPE=Debug      
      ;;
    i)
      INSTALL_DIR=$OPTARG      
      ;;
	h)
      show_help
      exit 0
      ;;
  esac
done

INSTALL_PREFIX=${INSTALL_DIR}/${OS_TYPE}/${OS_ARCH}/${COMPILE_TYPE}/
#编译cmake
cmd="cmake .. -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX}  -DCMAKE_BUILD_TYPE=${COMPILE_TYPE} -DCMAKE_OS_ARCH=${OS_ARCH} -DCMAKE_OS_TYPE=${OS_TYPE}"

cd $PWD/build 
$cmd
make 
make install
cd ..

脚本使用: ./build.sh -a x86 -d 生成32位的调试版程序
./build.sh -a x64 生成64位调试版程序。
linux平台的编译器用的是GNU,运行cmake生成makefile,运行makefile编译工程。与windows的MSVC编译有所不同:MSVC先构建visual studio工程,然后 通过MSbuild 进行该工程的编译。

六、总结

本文给出了大多数用cmake进行构建项目的一个模板,能够在不同平台和不同的架构下进行编译,cmake相比于gcc和makefile能够更加高效的编译复杂项目。
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:35:34  更:2022-10-31 11:39:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 2:50:09-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码