在<<跨平台编译的经验之谈--cmake编译文件的一般方法>> 一文中,总结了CMake编译文件CMakeLists.txt在构建一个工程时的一般方法。该篇文章主要讲述在Mac电脑上,构建CMake编译文件的方法.虽然Mac电脑的系统也源属于Unix系统,但当我们需要用到Cocoa的一些framework时,就需要通过cmake构建出Xcode工程,这也是Mac平台不同与Unix系统的一个方面,且在编译iPhone应用时,需要在Xcode进行签名.
因此,下面我们主要讲述讲述CMake构建iphone工程来开启我们的Xcode之旅.
Xcode构建流程:
在用CMake编译文件构建一个工程一般方法的基础上,Xcode工程的CMake文件具有以下形式 (其中粗体字部分是构建Xcode工程所需要的):
cmake_minimum_required(VERSION 2.8.2)
//添加一些编译器选项
project(my_project)
include_directories(thirdparty/ include/)
set(SRC_FILES main.cc *.m) //注意*.m是启动iphone应用程序的主要文件,这里*是指某个文件
add_executable(my_target ${SRC_FILES})
//设置xcode平台属性
target_link_libraries(my_target thirdparty/src/*.so)
//设置my_target.app bundle的属性
install(TARGETS my_target DESTINATION my_target.app)
1 添加编译选项
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++")
if() --- endif() -- 它是CMake的分支语句,是我们在同一个CMake编译文件里构建不同平台时的 重要语法之一
include -- 它是CMake支持的一个重要功能之一,它包含的是一个.cmake文件,此处CMakeForceCompiler.cmake文件是我们安装cmake时自带的, 当我们包含它之后,就能够使用它里面提供的一些函数和宏,比如CMAKE_FORCE_C_COMPILER和CMAKE_FORCE_CXX_COMPILER.
clang是苹果重点支持的编译器,比较常用流行的c++编译器有gcc g++,clang是新兴的一种编译器,google最近在Android ndk编译中也采用了它.
CMAKE_FORCE_<*>_COMPILER(compiler, compiler_id) -- 主要是选择了使用何种编译器进行编译
CMAKE_XCODE_ATTRIBUTE_<*> -- 他主要是设置了Xcode平台的一些属性,CLANG_CXX_LANGUAGE_STANDARD和CLANG_CXX_LIBRARY是Xcode Build Settings面板下的选项,如下图所示:
2 设置Xcode平台属性
set(CMAKE_OSX_SYSROOT iphoneos)
set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)")
set(CMAKE_EXE_LINKER_FLAGS "-framework Foundation -framework UIKit")
set_target_properties(my_project PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO")
foreach(SRC_FILE ${SRC_FILES})
set_source_files_properties(${SRC_FILE} PROPERTIES COMPILE_FLAGS "-x objective-c++")
endforeach(SRC_FILE ${SRC_FILES})
set_target_properties(${my_project} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.example.company.\${PRODUCT_NAME:rfc1034identifier}")
CMAKE_OSX_SYSROOT -- 定义OS X平台SDK的位置, 指定了它,系统的库才能为我们所用,iphoneos表示iphone当前版本的sdk。
CMAKE_OSX_ARCHITECHTURES --定义OS X的编译平台,一般设置为标准的平台,如arm64, armv7,标准平台的值为$(ARCHS_STANDARD), $()表示系统生成的变量。
XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH--表明我们是否只编译我们激活的平台
以上两个选项, 如图所示
CMAKE_EXE_LINKER_FLAGS -- 目标文件在链接库时所需要用到的一些标识。它可以指定链接时的编译选项,如是否打印warning等,也可以告诉链接器搜索系统的哪些库. 它与target_link_libraries的区别在于,target_link_libraries用于链接一个特定的库, 而它会告诉连接器搜索系统的库.
foreach() --- endforeach() --cmake提供的遍历的方法,非常好用
set_source_files_properties -- 让编译的源文件具有某种属性,该属性通常是由 key-value的形式设置的,即COMPILE_FLAGS 和 "-x objective-c++"是一个键值对,它们使得编译时将源文件看成是objective-c++的。
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY-- 设置开发者签名, 如图所示
通过选择自己的开发者帐号,我们能够将自己的开发应用安装在手机上。
MACOSX_BUNDLE_GUI_IDENTIFIER -- 设置了我们应用的包名,其中PRODUCT_NAME:rfc1034identifier PRODUCT_NAME是我们编译的Target名字, rfc1034identifier是正则表达式
3 设置 my_target.app bundle的属性
set_property(TARGET my_project PROPERTY MACOSX_BUNDLE TRUE)
set_property(TARGET my_project PROPERTY MACOSX_BUNDLE_ICON_FILE my_project_OSX.icns)
set_property(TARGET my_project PROPERTY MACOSX_BUNDLE_INFO_PLIST Info.plist)
set_property -- 设置属性, TARGET指定了我们要设置属性的类型是目标文件, 然后后面紧接着的是key-value值
MACOSX_BUNDLE: 表示在Xcode平台上的可执行文件, 如果设置其为TRUE,则表示将我们编译的目标文件的类型设置为Xcode下的可执行文件
MACOSX_BUNDLE_ICON_FILE: 故名思义,设置可执行文件的icon,即手机界面的应用图标
MACOSX_BUNDLE_INFO_PLIST:它是我们应用程序的一个配置文件,能够指定应用名称,应用的横竖屏等属性。
4 Install:
在最后的install的语句中,我们将编译的目标文件生成到my_target.app里,my_target.app是一个文件夹, 如果想看其内容,点击右键选择packageContents.
5 总结:
以上,分析了cmake编译iphone Xcode工程的基本写法。它在遵循了在<<跨平台编译的经验之谈--cmake编译文件>>一文中中的基本流程.我们可以看到,与Unix平台编译所不同的是
1 它需要构建一个Xcode工程,因此在其流程上引入了需要Xcode设置属性的工作
2 它输出的目标文件为.app文件文件
3 编译的源文件多了.m这种与平台相关的文件
网友评论