xcode6_beta build fix: Undefined symbols _fwrite$UNIX2003

使用xcode6 编译cocos2dx会有以下错误

Undefined symbols for architecture i386:
  "_fwrite$UNIX2003", referenced from:
      _unixErrorHandler in libcocos2dx iOS.a(tif_unix.o)
      _unixWarningHandler in libcocos2dx iOS.a(tif_unix.o)
      _empty_output_buffer in libcocos2dx iOS.a(jdatadst.o)
      _term_destination in libcocos2dx iOS.a(jdatadst.o)
      _Fax3PrintDir in libcocos2dx iOS.a(tif_fax3.o)
      _PredictorPrintDir in libcocos2dx iOS.a(tif_predict.o)
  "_strerror$UNIX2003", referenced from:
      _TIFFOpen in libcocos2dx iOS.a(tif_unix.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

google后发现, http://stackoverflow.com/questions/8732393/code-coverage-with-xcode-4-2-missing-files ,针对2dx的只需要在AppDelegate.cpp的最后面添加:

1
2
3
4
5
6
7
8
9
10
extern "C"{
size_t fwrite$UNIX2003( const void *a, size_t b, size_t c, FILE *d )
{
return fwrite(a, b, c, d);
}
char* strerror$UNIX2003( int errnum )
{
return strerror(errnum);
}
}

即可

解决 xcode 5 资源文件更新后不自动复制的问题

升级到xcode5后一很奇怪的问题:资源文件以文件夹形式引入在xcode里, 但是如果更新资源文件夹下的图片, xcode不会自动复制到目标设备, 必须clean, 再build.
猜测可能的原因是xcode根据文件夹的更新日期来判断此文件夹需不需要重新复制

解决方法:

设置一个Build Phases在每次build的时候touch一下资源文件, 这样xcode就会重新复制资源文件了

步骤:

1.选中项目, 添加一个Run Script Build Phase


Read More

Set ubuntu as Mac AFP&TimeMachine server with netatalk 3.05

准备使用netatalk在Ubuntu Server上搭建支持TimeMachine备份的文件服务器,查了一下netatalk新的版本已经不需要avahi了,不过apt-get获取的netatalk还是老版本的,so,下载源码编译安装

首先安装依赖

sudo apt-get install libssl-dev libgcrypt11-dev libkrb5-dev \
    libpam0g-dev libwrap0-dev libdb-dev libavahi-client-dev \
    libacl1-dev libldap2-dev libcrack2-dev systemtap-sdt-dev \
    libdbus-1-dev libdbus-glib-1-dev libglib2.0-dev libevent-dev

下载解压netatalk3.0.5源码

wget http://softlayer-dal.dl.sourceforge.net/project/netatalk/netatalk/3.0.5/netatalk-3.0.5.tar.bz2
tar xvf netatalk-3.0.5.tar.bz2 
cd netatalk-3.0.5/

Read More

Update: Android.mk 中的 LOCAL_SRC_FILES, LOCAL_C_INCLUDES

我在先前的两篇post
编写Android.mk中的LOCAL_SRC_FILES的终极技巧

编写 android.mk 中 LOCAL_C_INCLUDES 的技巧

中提到了一些编译android.mk文件的技巧, 由于都涉及到了shell命令, 导致不能完全在windows下工作, 下面我使用纯净的makefile语法重新编写了脚本

# 配置自己的源文件目录和源文件后缀名
MY_FILES_PATH  :=  $(LOCAL_PATH) \
                   $(LOCAL_PATH)/../../Classes

MY_FILES_SUFFIX := %.cpp %.c

# 递归遍历目录下的所有的文件
rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

# 获取相应的源文件
MY_ALL_FILES := $(foreach src_path,$(MY_FILES_PATH), $(call rwildcard,$(src_path),*.*) ) 
MY_ALL_FILES := $(MY_ALL_FILES:$(MY_CPP_PATH)/./%=$(MY_CPP_PATH)%)
MY_SRC_LIST  := $(filter $(MY_FILES_SUFFIX),$(MY_ALL_FILES)) 
MY_SRC_LIST  := $(MY_SRC_LIST:$(LOCAL_PATH)/%=%)

# 去除字串的重复单词
define uniq =
  $(eval seen :=)
  $(foreach _,$1,$(if $(filter $_,${seen}),,$(eval seen += $_)))
  ${seen}
endef

# 递归遍历获取所有目录
MY_ALL_DIRS := $(dir $(foreach src_path,$(MY_FILES_PATH), $(call rwildcard,$(src_path),*/) ) )
MY_ALL_DIRS := $(call uniq,$(MY_ALL_DIRS))

# 赋值给NDK编译系统
LOCAL_SRC_FILES  := $(MY_SRC_LIST)
LOCAL_C_INCLUDES := $(MY_ALL_DIRS)

完全使用makefile语法编写, 可以工作在所有平台上

我已经在cocos2d-x中提交了一个pull request https://github.com/cocos2d/cocos2d-x/pull/3921, 希望能被集成到cocos2d-x的代码库中, 以后使用就不需要自己修改了

自定义xcode代码提示的风格

网上有个图片:

我喜欢左边的风格, 很不幸xcode默认的代码提示自动完成都是右边风格的, 修改它一下
用文本编辑工具打开文件:
/Applications/Xcode.app/Contents/PlugIns/IDECodeSnippetLibrary.ideplugin/Contents/Resources/SystemCodeSnippets.codesnippets

可以看到里面是xcode预定义的自动完成代码, 找到要修改的{地方, 比如

<string>class &lt;#class name#&gt; {
  &lt;#instance variables#&gt;

public:
  &lt;#member functions#&gt;
};</string>

很明显这是定义一个C++类, 在{后面添加一个回车修改成

<string>class &lt;#class name#&gt; 
{
  &lt;#instance variables#&gt;

public:
  &lt;#member functions#&gt;
};</string>

依次修改需要的地方,保存,重新启动xcode, 收工.

查看android上程序的内存占用

在android设置上开发, 要查看android程序的实际内存占用情况有两种方法

1. 使用linux命令top

android基于linux, 所以我们可以使用top命令来查看内存使用

打开终端:

    # 进入android的shell环境
    adb shell
    #执行top命令, 只显示内存占用最多的前4个程序
    top -m 4

可以看到输出

RSS一栏即为内存占用

2. 使用eclipse中的ADT工具

eclipse中安装adt插件后,在DDMS界面可以查看android设备的很多信息, 其中就包括内存使用

把android设备连接电脑,打开eclipse, 从左上切换到DDMS界面

然后再点System Information ,选 Memory usage, 把鼠标移动到想查看的进程上,就可以看到内存使用了

默认类型char 在 android NDK r9 和 xcode 4.6.3中的不同

测试一些代码中,发现一个奇怪的bug.最好发现是如下原因:
考虑代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
char c_num;
int i_num;
c_num = -1;
i_num = c_num;
if (i_num == c_num) {
CCLOG("OK 1");
}
i_num = -1;
c_num = i_num;
if (i_num == c_num) {
CCLOG("OK 2");
}

xcode ios SDk 6.1 编译得到输出

      OK 1  
      OK 2

android NDK r9, gcc 4.8编译得到输出

      OK 1

可见,在xcode中char被定义为有符号数,而在ndk中定义是无符号数

cocos2d-x 2.1.4 启用C++11后使用 NDK r9 gcc 4.8无法编译

下载android ndk r9版本后,发现cocos2d-x无法编译通过报一大堆错误和警告,仔细查看是这两个

    warning: invalid suffix on literal; C++11 requires a space between literal and identifier
    error: format not a string literal and no format arguments

第一个警告是由于头文件不符合C++11的标准引起的,第二个警告是因为格式化字串函数产生的,只需要给gcc参数让其忽略掉这两个错误即可。
打开android项目的Application.mk文件,在APP_CPPFLAGS变量后面添加

    -Wno-format-security -Wno-literal-suffix

就可以了。

Ubuntu 13.04 不能保存屏幕亮度的补丁

安装Ubuntu后,再安装屏幕亮度指示器(Indicator Brightness), 发现每次重启后亮度都会恢复到最大,无法记忆上次设置的屏幕亮度.经查看,这个指示器是python写的,脚本路径是/opt/extras.ubuntu.com/indicator-brightness/indicator-brightness, 决定在修改脚本,增加自动保存亮度的代码.

使用任何文件编辑器打开它, 在开头添加如下两个方法来保存和加载亮度数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import os
import os.path
filepath = os.path.expanduser('~')+"/.brightness"
def save_to_file(rec):
try:
savefile = open(filepath, "w")
savefile.write("%s" % rec)
savefile.close()
except:
savefile = ""
def read_from_file():
lastBrightness = 0
try:
savefile = open(filepath, "r")
lastBrightness = int(savefile.read())
savefile.close()
except:
lastBrightness = 0
return lastBrightness

这里,我把当前亮度保存$HOME/.brightness文件里.
再添加对这两个方法的调用
if __name__ == "__main__":后面添加

1
2
3
rec = read_from_file()
if rec != 0:
set_brightness(rec)

读取保存的亮度记录,并设置

同时修改set_brightness方法为:

1
2
3
4
def set_brightness(brightness):
subprocess.call(['pkexec','/usr/lib/gnome-settings-daemon/gsd-backlight-helper','--set-brightness',"%s" % brightness])
save_to_file(brightness)
create_menu(ind)

保存indicator-brightness文件,并修复权限

sudo chown root:root indicator-brightness
sudo chmod 755 indicator-brightness

注销,重新登录,生效

附件为我修改的indicator-brightness文件, 这里下载Download

升级 eclipse 4.3, 导入老版本安装的plugins

eclipse 4.3已于近日发布, 在使用流畅性上相对于4.2有了大大的提升, 由于我平时使用eclipse是为了开发android, 所以下载安装新的eclipse需要安装android开发所需的ADT插件等一大堆, 如果再重新下载安装一遍这些插件, 太麻烦了, 直接导入以前安装的插件就方便多了
我选择下载Eclipse Standard 4.3,解压运行eclipse, 然后选择File->Import->Install->From Exist Installation, 在下一个对话框里选择原来的eclipse 4.2的安装文件夹, next, 同意授权, 一路next即可把原来所有的插件安装过来