cmake

make file 相关

Posted by nomadli on February 19, 2019

./CMakeLists.txt

  • 编译脚本、一个目录一个 ```

    需要cmake版本大于等于3.13

    隐含调用cmake_policy(VERSION 3.13)指定策略,指定版本低于2.4时策略使用2.4

    cmake_minimum_required (VERSION 3.13)

判断是否作为子项目,获取父目录如果变量被定义则表示是子项目

get_directory_property(has_parent PARENT_DIRECTORY) if(NOT has_parent) set(HELLO_IN_PROJECT_BUILD false) endif()

添加编译子目录

第二个可选参数EXCLUDE_FROM_ALL,将目录从默认目标中排除,即需要明确指定才会编译

add_subdirectory(src)


## ./src/version.h.in

#ifndef VERSION_H #define VERSION_H

#define HELLO_V_MAJOR @HELLO_VERSION_MAJOR@ #define HELLO_V_MINOR @HELLO_VERSION_MINOR@

#endif//VERSION_H


## ./src/policy.cmake

如果存在CMP0048策略,则使用CMP0048策略的新定义,对应有OLD

cmake_policy(VERSION xxx)使用某版本的策略

cmake_policy(GET CMP0048 var) 获取策略值 NEW、OLD、空

cmake_policy(PUSH) cmake_policy(POP) 栈操作

if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif()

cmake版本比较

if (CMAKE_VERSION VERSION_LESS “3.9.0”) cmake_policy(SET CMP0023 OLD) else() cmake_policy(SET CMP0023 NEW) endif()


## ./src/helllib/CMakeLists.txt

遍历指定目录中目标文件(.c .cpp .cxx等),并将列表合并到targsrcs

aux_source_directory(. targsrcs)

添加一个库目标,默认是static

第二个参数可选[SHARED|STATIC|MODULE]

第三个参数可选EXCLUDE_FROM_ALL 将目标从默认目标中排除,即需要手动指定目标才会编译

add_library(hellolib ${targsrcs})


## ./src/CMakeLists.txt

设置工程名、使用的语言

隐含路径都是顶层父路径

隐含定义输出目录 CMAKE_BINARY_DIR == 命令行-B指定的目录,或命令行当前目录

隐含定义输出目录 PROJECT_BINARY_DIR == ${CMAKE_BINARY_DIR}/src

隐含定义源码目录 CMAKE_SOURCE_DIR == 命令行-S(可以省略-S)指定的源码目录

隐含定义源码目录 PROJECT_SOURCE_DIR == CMAKE_SOURCE_DIR

project(hello, C)

根据模板生成文件,一般用于版本号设置

set(HELLO_VERSION_MAJOR 1 PARENT_SCOPE) 将在父级的CMakeLists中定义或覆盖变量值

set(HELLO_VERSION_MAJOR 1) set(HELLO_VERSION_MINOR 0) configure_file(${CMAKE_SOURCE_DIR}/src/version.h.in ${CMAKE_SOURCE_DIR}/src/version.h)

显示信息并继续 无、STATUS、WARNING、AUTHOR_WARNING、SEND_ERROR、

显示信息必须在引号前后有空格

显示信息并中断 FATAL_ERROR

DEPRECATION 弃用警告

CMAKE_WARN_DEPRECATED、CMAKE_ERROR_DEPRECATED 如果弃用则显示警告或错误

message(STATUS “ Using CMake version: ${CMAKE_VERSION} “) message(STATUS “ Build Hello version: ${HELLO_VERSION_MAJOR}.${HELLO_VERSION_MINOR} “)

导入定义、方法、配置等

CMAKE_CURRENT_LIST_DIR 当前文件目录

include(${CMAKE_CURRENT_LIST_DIR}/policy.cmake)

GNUInstallDirs cmake预定义宏

导入gun 默认安装路径 CMAKE_INSTALL_xx(相对路径)和CMAKE_INSTALL_FULL_xx(绝对路径)

BINDIR(bin) SBINDIR(sbin) LIBEXECDIR(libexec) SYSCONFDIR(etc) SHAREDSTATEDIR(com)

LIBDIR(lib|lib64|lib/arch) INCLUDEDIR(include) OLDINCLUDEDIR(/usr/include)

LOCALSTATEDIR(var) RUNSTATEDIR(LOCALSTATEDIR/run)

DATAROOTDIR(share) DATADIR(DATAROOTDIR) INFODIR(DATAROOTDIR/info)

LOCALEDIR(DATAROOTDIR/locale)

MANDIR(DATAROOTDIR/man) DOCDIR(DATAROOTDIR/doc/PROJECT_NAME)

include(GNUInstallDirs)

判断是否指定编译类型,如果没指定则指定位Release版本并强制刷新缓存

cmake会缓存解析结果到编译目录的文件,除非重新赋值

if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE “Release” CACHE STRING “build type: Debug Release.” FORCE) endif()

BUILD_SHARED_LIBS cmake变量,当编译目标为动态库时被自动定义

CMAKE_COMPILER_IS_GNUCXX 编译器是GCXX

添加fPIC开关,编译位置无关的二进制

if (BUILD_SHARED_LIBS) if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(“-fPIC”) endif() set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) endif()

添加头文件路径

include_directories(${CMAKE_CURRENT_LIST_DIR}/hellolib)

add_subdirectory(hellolib)

此处targsrcs为空列表,因为hellolib中第一次出现是子目录变量,不会出现在父目录

如果先进行父目录遍历,后添加hellolib会导致hellolib中变量不为空

aux_source_directory(. targsrcs) aux_source_directory(./sub01 targsrcs) aux_source_directory(./sub02 targsrcs)

添加一个可执行目标

第二个参数可选EXCLUDE_FROM_ALL,将目标从默认目标中排除,即需要手动指定目标才会编译

add_executable(hello ${targsrcs})

为目标添加依赖库

target_link_libraries(hello hellolib)



## cmake
- CMakeLists.txt 类似makefile是默认的文件
- 常用变量

        PROJECT_NAME            project指令设置的名字
        CMAKE_BUILD_TYPE        Debug、Release、RelWithDebInfo、MinSizeRel
        CMAKE_C_FLAGS_DEBUG     debug时使用的c编译选项
        CMAKE_CXX_FLAGS_DEBUG   debug时使用的c++编译选项
        CMAKE_C_FLAGS_RELEASE   release时使用的c编译选项
        CMAKE_CXX_FLAGS_RELEASE release时使用的c++编译选项
        CMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt所在路径
        CMAKE_C_COMPILER        指定c编译器
        CMAKE_CXX_COMPILER      指定c++编译器
        CMAKE_C_FLAGS           指定c的编译选择 类似add_definitions指令
        CMAKE_CXX_FLAGS         指定c++的编译选择 类似add_definitions指令
        BUILD_SHARED_LIBS       设置编译动态库,默认静态库
        CMAKE_CURRRENT_BINARY_DIR

                                in-source 编译是当前处理CMakeLists.txt所在路径
                                out-of-source 编译指target目录
        CMAKE_CURRENT_LIST_FILE 当前处理的CMakeLists.txt的完整路径
        CMAKE_CURRENT_LIST_LINE 当前所在的CMakeLists.txt的行数
        CMAKE_MODULE_PATH       通过set设置自定义cmake模块的路径,然后用include指令调用模块
        EXECUTABLE_OUTPUT_PATH  定义可以执行文件的输出目录
        LIBRARY_OUTPUT_PATH     定义库文件输出目录
        CMAKE_INCLUDE_CURRENT_DIR 包含CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR目录
        CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE 先搜索用户头文件目录
        CMAKE_INCLUDE_PATH
        CMAKE_LIBRARY_PATH
        CMAKE_MAJOR_VERSION     cmake主版本号
        CMAKE_MINOR_VERSION     cmake次版本号
        CMAKE_PATCH_VERSION     cmake补丁版本号
        CMAKE_SYSTEM            系统的名称包含版本
        CMAKE_SYSTEM_NAME       系统名称不含版本
        CMAKE_SYSTEM_VERSION    系统版本
        CMAKE_SYSTEM_PROCESSOR  处理器名称如x86 i686
        CMAKE_EXPORT_COMPILE_COMMANDS  生成编译数据库,主要用于静态分析,如scan-build
        UNIX                    是否通过UNIX通用可移植接口认证(POSIX)
        WIN32                   是否为widow平台
        CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 设置ON后IF语法中ELSE和ENDIF括号为空
        CMAKE_GENERATOR         -G参数例如生成Xcode项目:输入-GXcode变量为Xcode
        XCODE_VERSION           xcoce的版本
        CMAKE_POSITION_INDEPENDENT_CODE True False默认True为动态库添加-fPIC(内存位置无关的代码)
               
- 指令

        cmake_minimum_required(VERSION 2.6 [FATAL_ERROR])     设置最低版本,FATAL_ERROR设置时将直接失败
        project(name, C)        设置工程名、语言
                                会隐式的定义PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR两个变量
                                CMAKE_BINARY_DIR == name_BINARY_DIR == 命令行中-B后的输出路径
                                PROJECT_BINARY_DIR
                                CMAKE_SOURCE_DIR == name_SOURCE_DIR == 命令行中-S后或者没有任何参数的源码路径
                                PROJECT_SOURCE_DIR
        message(FATAL_ERROR "") 显示信息 //STATUS WARNING         
        set(xxx yyy)            创建变量xxx,值为yyy,第三参数CACHE type(FILEPATH PATH STRING BOOL) doc(描述) 
        $ENV{name}              获取环境变量
        set(ENV{name} xxx)      设置环境变量
        get_directory_property  获取目录属性,一般判断当前cmake是不是子模块get_directory_property(xx PARENT_DIRECTORY)
        option(name "" ON)      默认为ON,可以在命令行-Dname=xxx, name将赋值xxx
        add_definitions         添加宏add_definitions(-DDebug),新版本用add_compile_definitions代替
        add_compile_options     添加其它编译选项
        add_dependencies        设置target依赖的其他target
        add_executable(name xx.c ..)      编译可执行文件
        add_library(name [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] xx.c ..)  name工程名 编译|静态|动态|dlopen|的库
        set_target_properties(name1 name2 PROPERTIES PRO1 value1 PRO2 value2) 设置工程
        add_subdirectory(dir [bin_dir] [EXCLUDE_FROM_ALL]) 向当前工程添加源码目录 指定中间二进制、目标二进制的位置
        enable_testing()        指定生成测试目标
        add_test(testname exename arg ..)
        aux_source_directory(dir name) 将目录下所有源码文件列表存储在name变量中
        exec_program(...)       在cmake执行过程中执行系统命令,不进入生成的工程或make文件中
        include(file [optional]) 加载CMakeLists.txt或者模块
        if(x)缩进elseif(x)缩进else(x)缩进endif(x)
        if(${v}) 不是空、0、N、NO、OFF、FALSE、NOTFOUND、v_NOFOUND时为真
        if(NOT ${v})
        if(${v1} AND ${v2})
        if(${v1} OR ${v2})
        if(COMMAND cmd) cmd可以调用为真
        if(EXISTS dir)
        if(EXISTS f)
        if(f1 IS_NEWER_THAN f2)
        if(IS_DIRECTORY name)
        if(${v} MATCHES regex)
        if(string MATCHES regex)
        if(${v} LESS number)
        if(string LESS number)
        if(${v} GREATER number)
        if(string GREATER number)
        if(${v} EQUAL number)
        if(string EQUAL number)
        if(${v} STRLESS string)
        if(string STRLESS string)
        if(${v} STRGREATER string)
        if(string STRGREATER string)
        if(${v} STREQUAL string)
        if(string STREQUAL string)
        if(<variable|string> VERSION_LESS <variable|string>)//major[.minor[.patch[.tweak]]]
        if(<variable|string> VERSION_EQUAL <variable|string>)
        if(<variable|string> VERSION_GREATER <variable|string>)
        if(DEFINED v) 变量被定义为真
        if(NOT DEFINED v) 变量被定义为假
        while(x) 缩进 endwhile(x)
        foreach(var x1 x2 ...) endforeach(var)
        foreach(var RANGE x) endforeach(var)
        foreach(var RANGE start stop [step]) endforeach(var)
        file(WRITE fname "xxx" ..) 创建或覆盖已有文件, 写入多行文本
        file(APPEND fname "xxx" ..) 附加到文件末尾,多行文本
        file(READ fname vname [LIMIT x] [OFFSET x] [HEX]) 将指定偏移大小的内容存储在变量中
        file(STRINGS fename vname [LIMIT_COUNT x] [LIMIT_INPUT x] [LIMIT_OUTPUT x] [LENGTH_MINIMUM x] [LENGTH_MAXIMUM x] [NEWLINE_CONSUME] [REGEX regex] [NO_HEX_CONVERSION]) 读ASCII字符串、文件中的二进制数据会忽略、回车换行会忽略,返回限制行数、限制字符串长度的list给变量
        file(GLOB vname [RELATIVE path] [globbing expressions]..) 通过表达式生成文件列表到变量
        file(GLOB_RECURSE vname [RELATIVE path]  [FOLLOW_SYMLINKS] [globbing expressions]...) 类似GLOB但保护子目录
        file(MAKE_DIRECTORY [dir...]) 创建目录,父目录不存在也会创建
        file(RENAME <oldname> <newname>)
        file(REMOVE [file1 ...])    删除指定目录或文件,包括子路径
        file(REMOVE_RECURSE [file1 ...]) 删除指定文件或目录,包括非空目录
        file(RELATIVE_PATH vname dir file) 将从dir到文件的相对路径保存在变量中
        file(TO_CMAKE_PATH path result) 将path转换为以/开头的
        file(TO_NATIVE_PATH path result) 将path转换为系统格式
        file(DOWNLOAD url file [TIMEOUT x] [STATUS vstatus] [LOG vlog] [EXPECTED_MD5 sum] [SHOW_PROGRESS])
        file(COPY|INSTALL files... DESTINATION <dir> [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS] [FILES_MATCHING] [[PATTERN <pattern> | REGEX <regex>] [EXCLUDE] [PERMISSIONS permissions...]] [...])
        find_file(vname, name, path1 ..) 在指定目录中查找name头文件路径并保存到vname
        find_path(vname, name, path1 ..) 不含文件名
        find_library(vname, name, path1 ..) 查找库路径
        find_program(vname, name, path1 ..) 查找可执行程序
        find_package(vname, [major.minor] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets... ] ] ) 通过自定义模块路径查找Find${vname}.cmake并执行
        macro(函数名) ... endmacro() 定义函数
        get_cmake_property(xxx 属性名) 获取cmake全局属性,未找到xxx为NOTFOUND, VARIABLES当前目录中定义的所有变量
- 策略 POLICY cmake不同版本间函数或命令会有不同的行为,当行为在不同版本间不同时会给出一个策略号,通过设置策略号来使用新或旧的行为
        POLICY号类似CMP0056 即CMP加数字
        if(POLICY CMP0056) 即判断当前策略是否等于CMP0056
        当调用cmake_minimum_required时(并且版本大于2.4)会隐含调用cmake_policy(VERSION, mimversion)将默认策略设置为指定版本
        cmake_policy(VERSION, major[.minor[.patch[.tweak]]]) 显式将策略设置为指定版本(含有很多策略)
        cmake_policy(SET CMP0056 NEW) 指定某策略使用新版本
        cmake_policy(SET CMP0056 OLD) 指定某策略使用旧版本
        cmake_policy(PUSH) cmake_policy(POP) 临时改变策略
  
- 自定义模块
  RFID  NDEF
  
### CMake 基本使用实例
最简单的CMakeLists.txt文件只需要两行,我们就从这个文件开始。CMakeLists 文件是这样的(tutorial.cxx源码)

cmake_minimum_required (VERSION 2.6) project(Tutorial) add_executable(Tutorial tutorial.cxx)

对于大写,小写,大小写混合的命令书写方法,CMake都支持。假如CMakeList.txt和tutorial.cxx文件都存放在~/cmake_tutorial目录

mkdir ~/cmake_tutorial/build cd ~/cmake_tutorial/build cmake -G “Unix Makefiles” .. 或 cmake .. make 或 cmake –build . –config Release ./Tutorial

### 添加版本号和配置头文件
我们给工程添加的第一个功能就是版本号。CMakeLists 文件如下:

cmake_minimum_required (VERSION 2.6) project(Tutorial)

set (Tutorial_VERSION_MAJOR 1) set (Tutorial_VERSION_MINOR 0)

configure_file ( “${PROJECT_SOURCE_DIR}/TutorialConfig.h.in” “${PROJECT_BINARY_DIR}/TutorialConfig.h” )

include_directories(“${PROJECT_BINARY_DIR}”) 添加头文件路径

add_executable(Tutorial tutorial.cxx)

在源代码目录中,我们新建TutorialConfig.h.in文件,内容如下:

#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

CMake 会使用 CMakeLists 文件中的Tutorial_VERSION_MAJOR 和 Tutorial_VERSION_MINOR 值替换配置文件的@Tutorial_VERSION_MAJOR@ 和 @Tutorial_VERSION_MINOR@。

### 添加一个库
我们把库源文件放到MathFunctions,这个单独的目录中。只需要一行的CMakeLists就足够了:

add_library(MathFunctions mysqrt.cxx)

为了使用新库,我们在顶层的CMakeLists文件中调用add_subdirectory,这样库才会被编译。我们还需要把MathFunctions目录添加到包含目录中,这样才能找到MathFunctions/mysqrt.h文件。最后,还需要把新库添加到可执行文件中。

include_directories (“${PROJECT_SOURCE_DIR}/MathFunctions”) add_subdirectory (MathFunctions)

add_executable (Tutorial tutorial.cxx) target_link_libraries (Tutorial MathFunctions)

### 添加一个选项,默认为ON

option (USE_MYMATH “Use tutorial provided math implementation” ON) if (USE_MYMATH) include_directories (“${PROJECT_SOURCE_DIR}/MathFunctions”) add_subdirectory (MathFunctions) set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) endif (USE_MYMATH)

add_executable (Tutorial tutorial.cxx) target_link_libraries (Tutorial ${EXTRA_LIBS})

相应的TutorialConfig.h.in修改

#cmakedefine USE_MYMATH

在源码中

#ifdef USE_MYMATH #include “MathFunctions.h” #endif

### 添加安装
对于MathFunctions库,我们需要安装库文件和头文件,在MathFunctions/CMakeLists中间添加下面两行:

install (TARGETS MathFunctions DESTINATION bin) install (FILES MathFunctions.h DESTINATION include)

对于程序文件,我们在顶层CMakeLists文件中添加下面几行来安装可以执行文件和配置文件:

install (TARGETS Tutorial DESTINATION bin) install (FILES “${PROJECT_BINARY_DIR}/TutorialConfig.h” DESTINATION include)

CMake变量CMAKE_INSTALL_PREFIX用来确定文件安装的根目录。  命令行-DCMAKE_INSTALL_PREFIX=xxx
### 添加测试
在顶层CMakeLists文件的最后

add_test (TutorialRuns Tutorial 25) #是否正常运行,返回码为0

add_test (TutorialComp25 Tutorial 25) #检测是否答案正确 set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION “25 is 5”)

add_test (TutorialNegative Tutorial -25) #检测负数是否计算正确 set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION “-25 is 0”)

add_test (TutorialSmall Tutorial 0.0001) #检测很小的数计算是否正确 set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION “0.0001 is 0.01”)

add_test (TutorialUsage Tutorial) #检测参数错误 set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION “Usage:.*number”)

macro (do_test arg result) #添加一个测试函数 add_test (TutorialComp${arg} Tutorial ${arg}) set_tests_properties (TutorialComp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result}) endmacro (do_test)

do_test (25 “25 is 5”) #测试25的结果是不是5 do_test (-25 “-25 is 0”) #测试-25的结构是不是0

### 添加系统环境发现
根据目标平台是否支持某些特性,首先在最上层的CMakeLists.txt里面,使用CheckFunctionExists.cmake宏来检测函数。

include (CheckFunctionExists) check_function_exists (log HAVE_LOG) 检测系统中是否有log函数,只检测二进制库,不会检测头文件 check_function_exists (exp HAVE_EXP)

include(CheckIncludeFile) check_include_file(unistd.h HAVE_UNISTD_HEARD_FILE) 检测是否有头文件 可以是列表

include(CheckCSourceCompiles)

include(CheckTypeSize) check_type_size(int, INT_SIZE) 检测int的内存大小

在TutorialConfig.h.in定义以下变量

#cmakedefine HAVE_LOG #cmakedefine HAVE_EXP

一定要在log和exp检测完成后,才能使用configure_file命令。configure_file命令使用当前的设置生成配置文件。
### 添加一个文件生成器
在build过程中添加一个生成的源文件,如生成一个三角函数速查表,在MathFunctions的子目录,新建文件MakeTable.cxx来生成表格。

#include #include #include int main (int argc, char *argv[]) { fopen(argv[1], ....) }

生成的文件应该是有效的C代码段,在MathFunctions的CMakeLists.txt文件中添加生成MakeTable命令,并且执行它。

add_executable(MakeTable MakeTable.cxx) #生成速查表的可执行文件 add_custom_command ( #添加自定义命令 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h DEPENDS MakeTable ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h )

### 构建安装包
在最上层的CMakeLists.txt的尾部添

include (InstallRequiredSystemLibraries) set (CPACK_RESOURCE_FILE_LICENSE “${CMAKE_CURRENT_SOURCE_DIR}/License.txt”) #设置pack变量 set (CPACK_PACKAGE_VERSION_MAJOR “${Tutorial_VERSION_MAJOR}”) set (CPACK_PACKAGE_VERSION_MINOR “${Tutorial_VERSION_MINOR}”) include (CPack)

正常的构建工程,会生成两个packconfig

cpack –config CPackConfig.cmake #二进制分发包 cpack –config CPackSourceConfig.cmake #源码分发包

### 添加测试报告到Kitware
在最上层的CMakeLists.txt中包含CTest模块。

include (CTest)

新建CTestConfig.cmake,在文件中定义本项目在仪表盘中的名称。

set (CTEST_PROJECT_NAME “Tutorial”)

CTest在执行时会读取这个文件

## cmake xcode build

cmake_minimum_required(VERSION 2.8.2)

project(Tutorial)

include_directories(thirdparty/ include/) set(SRC_FILES main.cc  *.m) add_executable(Tutorial ${SRC_FILES})

set(CMAKE_OSX_SYSROOT iphoneos)# SDK的位置,iphoneos表示iphone当前版本的sdk target_link_libraries(Tutorial thirdparty/src/*.so)#三方库 set(CMAKE_EXE_LINKER_FLAGS “-framework Foundation -framework UIKit”)#系统库

set_property(TARGET Tutorial PROPERTY MACOSX_BUNDLE TRUE) set_property(TARGET Tutorial PROPERTY MACOSX_BUNDLE_ICON_FILE my_project_OSX.icns) set_property(TARGET Tutorial PROPERTY MACOSX_BUNDLE_INFO_PLIST Info.plist)

install(TARGETS Tutorial DESTINATION Tutorial.app)

if(CMAKE_VERSION VERSION_LESS 3.0.0)        include(CMakeForceCompiler)        CMAKE_FORCE_C_COMPILER(clang  GNU)        CMAKE_FORCE_CXX_COMPILER(clang++ GNU) endif(CMAKE_VERSION VERSION_LESS 3.0.0)

set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD “c++11”) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY “libc++”) set(CMAKE_OSX_ARCHITECTURES “$(ARCHS_STANDARD)”)

set_target_properties(Tutorial PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH “NO”) set_target_properties(Tutorial PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY “iPhone Developer”) set(MACOSX_BUNDLE_GUI_IDENTIFIER “com.example.company.${PRODUCT_NAME:rfc1034identifier}”)

foreach(SRC_FILE ${SRC_FILES}) set_source_files_properties(${SRC_FILE}  PROPERTIES COMPILE_FLAGS “-x objective-c++”) endforeach(SRC_FILE ${SRC_FILES})


## cmake build ios framework
- shell script
```make
        cmake -GXcode -DCMAKE_INSTALL_PREFIX=xx -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-fembed-bitcode -DCMAKE_CXX_FLAGS=-fembed-bitcode//真机可添加bitcode
        xcrun xcodebuild IPHONEOS_DEPLOYMENT_TARGET=8.0 ARCHS=[arm64,arm64e,armv7,armv7s,i386,x86_64] -sdk [iphoneos iphonesimulator] -configuration Release -jobs 4 -target ALL_BUILD build
        mkdir -p x.framework/Versions/A/Headers
        mkdir -p x.framework/Versions/A/Resources
        cp -R arm64/include/dlib/* x.framework/Versions/A/Headers/
        cp Info.plist x.framework/Versions/A/Resources/
        lipo -create arm64/lib/xx.a xx/lib/xx.a . -o ./Versions/A/x

        pushd x.framework/Versions
                ln -sfh ../Versions/A Current
        popd

        pushd x.framework
                ln -sfh ../x.framework/Versions/Current/Headers Headers
                ln -sfh ../x.framework/Versions/Current/Resources Resources
                ln -sfh ../x.framework/Versions/Current/x x
        popd
  • cmake ``` set_target_properties(dlib PROPERTIES FRAMEWORK TRUE FRAMEWORK_VERSION A MACOSX_FRAMEWORK_IDENTIFIER com.nomadli.dlib MACOSX_FRAMEWORK_INFO_PLIST Info.plist VERSION 16.4.0 # 版本号 SOVERSION 1.0.0 # API 版本 PUBLIC_HEADER dlib.h XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY “iPhone Developer” ) install(TARGETS dlib FRAMEWORK DESTINATION frameworks/ install(TARGETS dassce BUNDLE DESTINATION bundles/ PERMISSIONS
ARCHIVE LIBRARY RUNTIME OBJECTS FRAMEWORK BUNDLE PRIVATE_HEADER PUBLIC_HEADER RESOURCE

OWNER_READ,OWNER_WRITE,OWNER_EXECUTE,GROUP_READ, GROUP_WRITE,GROUP_EXECUTE,WORLD_READ,WORLD_WRITE, WORLD_EXECUTE,SETUID,和SETGID ```

find_library

  1. find_package() 指定 MODULE 使用Find.cmake查找,找不到则失败
  2. 查找CMAKE_PREFIX_PATH CMAKE_FRAMEWORK_PATH CMAKE_APPBUNDLE_PATH 设定NO_CMAKE_PATH取消
  3. 查找 _DIR或_ROOT CMAKE_PREFIX_PATH CMAKE_FRAMEWORK_PATH CMAKE_APPBUNDLE_PATH 设置NO_CMAKE_ENVIRONMENT_PATH 取消
  4. HINT 指定的路径
  5. 系统环境变量PATH,/bin或/sbin结尾的,会自动转化为其父目录。设定NO_SYSTEM_ENVIRONMENT_PATH取消
  6. cmake的TARGET 设置NO_CMAKE_PACKAGE_REGISTRY或set(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY ON)取消
  7. CMAKE_SYSTEM_PREFIX_PATH CMAKE_SYSTEM_FRAMEWORK_PATH CMAKE_SYSTEM_APPBUNDLE_PATH设置NO_CMAKE_SYSTEM_PATH取消
  8. cmake 系统config目录配置 设置NO_CMAKE_SYSTEM_PACKAGE_REGISTRY或set(CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY ON)取消
  9. PATHS 字段查找