mac系统xcode6.1下cocos2d-x工程引入libpomelo2,编译libpomelo2
  admin 发表于 2014-11-19 23:37  分类:技术资料  4,948 次阅读  0条评论

写这个教程只是为了记录下自己在mac系统xcode6.1cocos2d-x工程中引入libpomelo2时遇到的坑坑洼洼……

虽然编译出来了,但是整个过程还是留下许多疑问乃至错误,我在这里分享出来,希望各位大侠看到其中的错误后,不吝赐教。我的邮箱是:yaoduoshao@qq.com

第一步是下载libpomelo2

下载地址是https://github.com/NetEase/libpomelo2

由于libpomelo2用gyp生成各种编译环境下的项目文件,所以,还要下载gyp。

下载地址是https://github.com/martine/gyp

第三步安装gyp。

cdgyp的目录后,运行如下命令:

$python setup.py install

这是一个python脚本,所以运行这个命令的前提是你的计算机上安装了python

不用担心,OS-X一般自带python

如果运行上面的命令后,提示找不到python,请按照网上的教程,安装python2.7

安装完python后,再运行这个命令,可能会提示你权限不足:

[Errno 13] Permission denied: '/Library/Python/2.7/site-packages/test-easy-install-11922.pth'

不用担心,运行如下命令

$ su -

输入root用户的密码后,进入root用户模式下,再cdgyp目录,重新运行安装命令:

$python setup.py install

不出意外的话,运行完就会提示gyp安装成功。执行如下命令

# exit

退出root用户。

再执行gyp命令

$gyp

如果弹出如下信息,说明安装成功:

gyp: usage: gyp [options ...] [build_file ...]

gyp: error: no build_file

至于弹不出这个信息的情况,恕我没遇到,所以……

第四步用gyp生成xcdode的工程。

进入pomelo目录之后,运行如下命令:

$gyp –depth=. pomelo.gyp -Dlibrary=static_library -DTO=ios

这句话的意思是用gyp在当前目录下通过pomelo.gyp生成iOS的静态库项目。

基本上,运行完这句命令,我的噩梦开始了——

ValueError: Found multiple build files for -lssl

直译过来就是,发现多个构建文件。没明白这句话是什么意思,在这里请大虾们指教。

虽然没明白什么意思,但是通过-lssl这几个字母终于猜测出应该跟openssl有关系。

没找到办法解决上述错误,我暂时又用不到openssl,可以先把他注释掉:

vi打开pomelo.gy,把

’no_tls_support%': “false”,

中的false改成true,就不编译openssl了。

保存后,再运行如下命令,就可以生成xcode的项目文件了:

$gyp –depth=. pomelo.gyp -Dlibrary=static_library -DTO=ios

在这里,由于我实在不知道如何把openssl加入编译工程中,所以干脆给去掉了T_T,哪位知道如何编译的,还请不吝赐教。

运行完这句命令就可以在libpomelo2的目录下看到生成的xcodeproj文件,deps下的janssonuv目录下也会生成相应的xcodeproj文件。

第五步生成静态库。

cdpomelo目录下,分别运行如下命令

$xcodebuild -project deps/jansson/jansson.xcodeproj

$xcodebuild -project deps/uv/uv.xcodeproj

$xcodebuild -project pomelo.xcodeproj

运行完之后分别会看到如下三个文件

./build/Default/libpomelo2.a

./deps/uv/build/Debug/libuv.a

./deps/jansson/build/Default/libjansson.a

这三个文件就是我们要的。

按照我的理解,我的电脑是64位的,所以生成的是64位的库文件,不知这样理解是否正确,还请知道的大侠指教。

我们还要编译i386的库文件,按照网络上的教程,要分别运行如下命令

$xcodebuild -project deps/jansson/jansson.xcodeproj -sdk iphonesimulator6.1 -arch i386

$xcodebuild -project deps/uv/uv.xcodeproj -sdk iphonesimulator6.1 -arch i386

$xcodebuild -project pomelo.xcodeproj -sdk iphonesimulator6.1 -arch i386

其中iphonesimulator6.1 是模拟器的版本,可以根据自己系统上的版本进行选择,例如我选择iphonesimulator8.1

第一个jansson库顺利编译出来,运行第二个编译命令和第三个编译命令的时候有如下错误:

Check dependencies

target specifies product type 'com.apple.product-type.tool', but there's no such product type for the 'iphonesimulator' platform

查了半天没找到什么原因。不知是否跟xcode6.1有关,请各位大侠不吝指教。

以下是archsdk两个参数的解释:

   -arch ARCH                                build each target for the architecture ARCH; this will override architectures defined in the project

   -sdk SDK                                  use SDK as the name or path of the base SDK when building the project

sdk参数会作为编译出来的项目的路径。

去掉sdk这个参数可以编译成功,只是我也不清楚去掉sdk的参数会否对最终编译出来的库有影响,请各位大侠不吝指教。

在去掉sdk参数进行编译之前我们先做一件事儿——把刚才默认生成的库目录换个名字,免得后面生成的i386库覆盖原来生成的库,例如原来是在三个build目录下,我这里将三个build目录改名为build1

执行如下命令,进行编译i386版本:

$xcodebuild -project deps/jansson/jansson.xcodeproj  -arch i386

$xcodebuild -project deps/uv/uv.xcodeproj  -arch i386

$xcodebuild -project pomelo.xcodeproj -arch i386

运行完这三个命令将会生成i386版本的三个库。

第六步用lipo将i386的库和默认编译出的库打包在一起。

cdpomelo目录下,执行如下命令:

$lipo -create ./build/Default/libpomelo2.a  ./build/Default1/libpomelo2.a  -output libpomelo2.a

$lipo -create ./deps/jansson/build/Default/libjansson.a ./deps/jansson/build/Default1/libjansson.a  -output libjansson.a

$lipo -create ./deps/uv/build/Default/libuv.a ./deps/uv/build/Default1/libuv.a  -output libuv.a

执行完这三个命令,就可以看到libpomelo目录下有三个打包成功的.a文件:

libpomelo2libjansson.alibuv.a

第七步将生成的库文件添加到xcode工程中。

Xcode中打开你要调用libpomelo2的项目,在项目target->Build Phases将生成的三个.a静态库文件加入到”Link Binary With Libraries”里。

”Build Settings””Header Search Paths”里加入如下目录:

libpomelo/include

libpomelo/src

libpomelo/deps/jansson/src

libpomelo/deps/uv/include

第八步编译工程。

到这一步基本上可以享受前面的成果了!!

但不要高兴地太早,你的cocos2d-x工程生成到最后可能会遇到如下错误:

Undefined symbols for architecture i386:

 "_alphasort$INODE64", referenced from:

     _uv__fs_readdir in libuv.a(fs.o)

 "_fopen$UNIX2003", referenced from:

     _json_dump_file in libjansson.a(dump.o)

     _json_load_file in libjansson.a(load.o)

 "_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)

     _dump_to_file in libjansson.a(dump.o)

     _Fax3PrintDir in libcocos2dx iOS.a(tif_fax3.o)

     _PredictorPrintDir in libcocos2dx iOS.a(tif_predict.o)

     …

 "_nanosleep$UNIX2003", referenced from:

     _uv__server_io in libuv.a(stream.o)

 "_scandir$INODE64", referenced from:

     _uv__fs_readdir in libuv.a(fs.o)

 "_strerror$UNIX2003", referenced from:

     _TIFFOpen in libcocos2dx iOS.a(tif_unix.o)

     _json_load_file in libjansson.a(load.o)

 "_strftime$UNIX2003", referenced from:

     _default_log in libpomelo2.a(pc_lib.o)

 "_strtod$UNIX2003", referenced from:

     _jsonp_strtod in libjansson.a(strconv.o)

 "_waitpid$UNIX2003", referenced from:

     _uv__chld in libuv.a(process.o)

ld: symbol(s) not found for architecture i386

clang: error: linker command failed with exit code 1 (use -v to see invocation)

最后的解决方法是:

打开你的工程里的AppDelegate.cpp

引入头文件dirent.h

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

#include <dirent.h>

#endif

AppDelegate.cpp的最后,加入如下代码:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

extern"C"{

   size_t fwrite$UNIX2003( constvoid *a, size_t b, size_t c, FILE *d )

   {

       return fwrite(a, b, c, d);

   }

   char* strerror$UNIX2003( int errnum )

   {

       return strerror(errnum);

   }

   FILE* fopen$UNIX2003( constchar *filename, constchar *mode )

   {

       return fopen(filename, mode);

   }

   double strtod$UNIX2003(constchar *nptr,char **endptr)

   {

       return strtod(nptr, endptr);

   }

   int alphasort$INODE64(conststructdirent **a, conststructdirent **b)

   {

       return alphasort(a, b);

   }

   int nanosleep$UNIX2003(conststructtimespec *req, structtimespec *rem)

   {

       return nanosleep(req, rem);

   }

   size_t strftime$UNIX2003(char* strDest, size_t maxsize, constchar* format, conststructtm* timeptr)

   {

       return strftime(strDest, maxsize, format, timeptr);

   }

   pid_t waitpid$UNIX2003(pid_t pid,int * status,int options)

   {

       return waitpid(pid, status, options);

   }

   int scandir$INODE64(constchar *dir,

                       structdirent ***namelist,

                       int (*filter) (constvoid *f),

                       int (*compare )(conststructdirent ** a, conststructdirent ** b))

   {

       return scandir(dir, namelist, 0, alphasort);

   }

}

#endif

之后再编译你的cocos2d-x项目,应该就可以了。

总结:

不得不说libpomelo2对于我等新手来说坑实在是有点多。

最终我编译出来可以在模拟器上运行的cocos2d-x程序,后面还有很多东西需要进一步验证。整个编译过程连猜带蒙,甚至还有几个步骤不确定是否正确,例如:

1、我取消了openssl的编译,如果有能解决这个问题的大侠,请不吝赐教

2、$xcodebuild -project pomelo.xcodeproj

 $xcodebuild -project pomelo.xcodeproj -arch i386

 $xcodebuild -project pomelo.xcodeproj -sdk iphonesimulator6.1 -arch i386

三种有什么区别?不带sdk参数编译出来的,用的时候会否有影响?

3、在AppDelegate.cpp中加入的那段代码是否是必须的?是因为我编译的不对?还是xcode的问题?

在这里再次吐槽一下libpomelo2的编译——开发人员能不能把门槛弄低一些啊!!!文档能不能全面完整一些啊!!!对于我们这样的小白,太难了!!!

以上疑问,请各位不吝赐教,yaoduoshao@qq.com

欢迎交流。

本文参考自:http://blog.csdn.net/ctbinzi/article/details/39023887

本文固定链接: http://www.youduoshao.com/2014-11-19/201411192349.html

填写您的称呼和邮箱即可发布评论

快捷键:Ctrl+Enter