通过预编译实现不同的编译条件

在项目中,在多个target或者不同的平台中,希望加载不同的头文件或者编译输出,比如ios设备加载这个头文件,安卓设备加载另外一个文件等

这里就可以在一个文件工程中加不同的编译条件来执行

这里分为两类

(1)只区分设备

屏幕快照 2015-03-23 上午10.43.26.png

如果只是区分设备,cocos2d-x里面已经提供了自带的方法,使用CC_TARGET_PLATFORM判断即可,这个可以有很多平台,比如说判断是否是ios平台,可以执行这个语法


if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
    {
        
    }


这样通过判断可以执行不同的操作和加载头文件等

(2)同一个工程区分不同的target

这里需要在target的build setting里面设置

在Apple LLVM 6.0 -Custom Compiler Flags里面设置Other C Flags.只需呀设置c flags即可,c++flags会随着c的那个修改而自动修改

怎么设置呢?

屏幕快照 2015-03-23 上午10.41.37.png

比如说在Debug里面,添加一个


-DVER_HU


然后当在工程中,需要这个target使用头文件或者判断是,可以使用这样一句来判断


#if defined(VER_HU)
    {
       
    }
    #endif


然后就可以像区分设备那样使用了,这个和上面那个不同的地方就是上面那个是在程序中判断的,而这个直接就是预编译命令,在编辑阶段就已经判断了,如果不满足是不编译的,前面记得要加-D这个标志,因为-D是gcc设置#define的一个标志,你要可以设置成其他的带表示的,比如说-DHU=30 这个就相当于#define HU 30

当然这个是可以同时使用的,比如下面这个


#if defined(VER_HU) && (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    {
        CCLOG("hudongdong");
    }
    #endif


点击查看原图

说点其他的:

Debug就是调试模式,Release是发布模式

这两个在第二个设置中有一个不同的地方

Release模式比Debug多了一句


-DNS_BLOCK_ASSERTIONS=1


这一句的作用就是屏蔽NSAssert()

NSAssert 只能在Objective-c里面使用。是assert的一个扩充。能捕获assert类异常及打印一些
可读的日志。而assert只是让app crash(abort).也就是崩溃掉,这样你就知道有异常了.
xcode 中 大家都会在debug(QA) 模式下进行调试代码,但是在发布的时候就不想让他崩溃了
所以我们只需要再build Settings 中假如宏定义控制 NSAssert的生效范围
例如 只希望debug(QA) 下启动 release(Prod) 不启用,
则添加 NS_BLOCK_ASSERTIONS
或者根据自己的target 定义 导入 #import <Cocoa/Cocoa.h> or #import <Foundation/Foundation.h> lines.
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。

还有就是宏定义有#ifdef 和 #if defined这两种

比如说


#if defined (AAA)
{
}
#endif



#ifdef (AAA)
{
}
#endif


#ifdef 和 #if defined 的区别在于,后者可以组成复杂的预编译条件,比如

#if defined (AAA) && defined (BBB)
xxxxxxxxx
#endif

#if defined (AAA) || VERSION > 12
xxxxxxxxx
#endif

而#ifdef 就不能用上面的用法,也就是说,当你要判断单个宏是否定义时
#ifdef 和 #if defined 效果是一样的,但是当你要判断复杂的条件时,只能用 #if

当然使用宏定义都要用#endif结尾

判断不同的可以用这样


#if defined(VER_1)
{
}
#elif defined(VER_2) || defined(VER_3)
{
}
#elif defined(VER_4)
{
}
#endif
//和这样
#if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
{
}
#else
{
}
#endif


这样就可以相当于if elseif

最后其他的预编译介绍

微软的编译器定义 _DEBUG 作为debug版本
gcc 定义 DEBUG 作为debug版本。xcode使用gcc,所以也是定义DEBUG,将工程模式设为Debug可以看到GCC_PREPROCESSOR_DEFINITIONS这个变量定义了DEBUG。OTHER_CFLAGS也行,这是直接设定gcc的参数,所以需要使用gcc的语法,比如-DDEBUG。当然最好还是使用xcode提供的预处理宏定义专用变量GCC_PREPROCESSOR_DEFINITIONS。

所以直接可以使用#ifdef DEBUG就可以判断是否是DEBUG模式


xcode中屏蔽NSLog, NSAssert
没有预处理宏定义用来屏蔽NSLog,如果使用了cocos2d可以使用它的CCLOG代替NSLog,CCLOG内部实现还是调用NSLog,但CCLOG使用预处理宏定义COCOS2D_DEBUG分别处理debug和release版本,debug版本就是NSLog,release版本为空。
对于NSAssert, 使用xcode提供的模板生成release版时会定义OTHER_CFLAGS为-DNS_BLOCK_ASSERTIONS,从而屏蔽NSAssert。使用cocos2d的模板生成的release版貌似没有定义NS_BLOCK_ASSERTIONS,需要自己添加。


屏蔽 C 标准库中的assert()
如果定义了 NDEBUG,则assert()函数将不会编译。

Last modification:January 1st, 1970 at 08:00 am
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

Leave a Comment