[Tutorial] build cocos2d-x as a static library in Mac Xcode

————————————-[English, 要看中文版請往下捲]—————————————-
[the story]
Recently, I create a new game project by using the latest cocos2d-x framework. I download the latest cocos2d-x 3.6. And I follow the tutorial to create a cocos2d-x project. I build & run the project successfully. But I notice a thing, if I clean the project or modify partial of my codes / resources. When building project, Xcode will compile whole source codes of cocos2d library again! It spends very very much time. It will compile 621 source files of cocos2d library. If I must wait so long every time when I just modify a piece of my code, how can I continue to write my fucking code!!?

So, I spent two days to search an available solution in the internet. I also ask a question in StackOverflow. There are still no answers. Finally, I find a post in a Japanese developer’s blog site. I follow his steps and build a cocos2d-x static library successfully. I import the static library into my game project, and it did works! okay, let me show you the screenshot first. it’s truely working!

Okay, let’s enter the main tutorial. The content is mainly translated from this Japanese developers’s post.

[Tutorial Begin]

Create a new cocos2d-x project

First, create a new project. Go to the root directory of the cocos2d-x library (i.e. /Users/YourName/Library/cocos2d-x-3.6).
Execute the following command in Mac command line.

cocos new HelloWorld -p com.CompanyName.HelloWorld -l cpp

open Xcode project file.

open HelloWorld/proj.ios_mac/HelloWorld.xcodeproj
Modify Build Settings

choose cocos2d_libs.xcodeproj and select the Target: libcocos2d iOS. modify its Build Settings.
The default values should be the same as the following, if not, modify them.

Architectures => Standard architectures
Build Active Architecture Only => No

In the “Valid Architectures” field, add two additional value: i386 and x86_64. This is for the Xcode simulator, to make the library runnable .

The final values should have five: arm64, armv7, armv7s, i386, x86_64. as the screenshot:
Using Rakefile to build Static Library
cd HelloWorld/cocos2d/build
vi Rakefile

input the following content:

PROJECT_PATH = "./cocos2d_libs.xcodeproj"
TARGET_NAME="'libcocos2d iOS'"
OUTPUT_DEBUG="tmp/iphonesimulator"
OUTPUT_RELEASE="tmp/iphoneos"
OUTPUT_LIB="./lib"
directory OUTPUT_LIB

desc "using lib command to build a static library"
task "lib" do
    sh "xcodebuild -project #{PROJECT_PATH} -configuration Release -sdk iphonesimulator8.3 -target #{TARGET_NAME} -arch i386 -arch x86_64 TARGET_BUILD_DIR=#{OUTPUT_DEBUG} BUILT_PRODUCTS_DIR=#{OUTPUT_DEBUG} clean build"

    sh "xcodebuild -project #{PROJECT_PATH} -configuration Release -sdk iphoneos8.3 -target #{TARGET_NAME} -arch armv7 -arch armv7s -arch arm64 TARGET_BUILD_DIR=#{OUTPUT_RELEASE} BUILT_PRODUCTS_DIR=#{OUTPUT_RELEASE} clean build"
end

desc "using lipo command to link static libraries for each device to one combined library file"
task "lipo" => OUTPUT_LIB do

    Dir.glob("#{OUTPUT_RELEASE}/*"){|path|
        p path
        file = File.basename(path)

        sh "lipo '#{OUTPUT_DEBUG}/#{file}' '#{OUTPUT_RELEASE}/#{file}' -create -output '#{OUTPUT_LIB}/#{file}'"
    }
end
begin building static library, execute the following command.

rake lib

The whole process will spend about 10 ~ 20 minutes, depends on your working machine. If the procedure stops within a minute, it might be error occurring. For me, I meet a error that process can’t find the correct iphonesimulator8.2 and iphoneos8.2 directory, so I must modify them to the correct value in my environment.

After building static library successfully, you will see two libcocos2d iOS.a files in the “tmp” directory. One is for real device, the other is for simulator. So, we must do one more step to pack these two files to one merged .a file. Execute the following command.

rake lipo

This will take couple of seconds. After done, you will see a “lib” directory which contains a libcocos2d iOS.a file, its size is about 117.9 MB. This is the static library file we want.

Import Static Library to Your Project

choose .xcodeproj file -> Build Phases -> Link Binary With Libraries. Delete all red-font libraries, and re-add them.

Add the static library which we just built to the library list.
Delete “libcocos2d Mac” and “libcocos2d iOS” target in the project setting (It’s the reason why building project so fucking slow). Keep the cocos2d source code files alive for that we can view the code in the future.
Congratulations! Enjoy the jet building speed!

Now you can clean whole project and rebuild it. You will see Xcode won’t compile cocos2d source files any more. It only compile the files in your own project. The building speed will be 50 times comparing with the original, I guess.

That’s all … good luck! :mrgreen:

————————————-[中文]—————————————-
[前言]
最近我要開一個新遊戲專案,想改用最新版的cocos2d-x來做。我去下載了最新版的cocos2d-x 3.6後,照著這個教學頁面成功開了一個新的cocos2d-x project。在Xcode也build成功跑出畫面了。但我發現只要有做過clean整個project的動作,甚至只是改了一些project裡自己寫的code。在build project時,有時候Xcode會誤以為你有去動到cocos2d library的source code,因此常常重新去compile cocos2d library的source code。總共有621個files要重build,需要蠻久的一段時間(大概3~4分鐘)。如果每次只是改個小東西,就要花這麼多時間等它重build,我還要不要寫code!!?

因此這兩天,我花了很多時間不斷上網找解法,在StackOverflow上問問題。都沒有找到我要的答案。最後,終於在今天讓我找到一個日本開發者的教學文章,成功build出cocos2d-x的static library,並import到我自己的project裡跑出結果。好,先讓你們看個畫面,代表我不是在虎爛的…

以下進入正題,內容主要是翻譯自這篇日本教學文章

[教學開始]

建立新專案

首先,要開一個cocos2d的專案。到你下載並解壓好的cocos2d-x根目錄(例: /Users/YourName/Library/cocos2d-x-3.6)執行以下指令

cocos new HelloWorld -p com.CompanyName.HelloWorld -l cpp

接著打開Xcode project檔。

open HelloWorld/proj.ios_mac/HelloWorld.xcodeproj
修改Build Settings

選擇cocos2d_libs.xcodeproj,再選擇Target: libcocos2d iOS,修改其Build Settings。
應該預設值就是下面寫的值了,如果不是,請改為下面的值。

Architectures => Standard architectures
Build Active Architecture Only => No

另外在Valid Architectures 那欄追加兩個值: i386 和 x86_64。這是為了讓build出來的Library也可以在模擬器上跑。

修改後的結果應該有五個值: arm64, armv7, armv7s, i386, x86_64
完整結果如圖片所示:
使用Rakefile來建立Static Library
cd HelloWorld/cocos2d/build
vi Rakefile

內容輸入以下程式碼:

PROJECT_PATH = "./cocos2d_libs.xcodeproj"
TARGET_NAME="'libcocos2d iOS'"
OUTPUT_DEBUG="tmp/iphonesimulator"
OUTPUT_RELEASE="tmp/iphoneos"
OUTPUT_LIB="./lib"
directory OUTPUT_LIB

desc "using lib command to build a static library"
task "lib" do
    sh "xcodebuild -project #{PROJECT_PATH} -configuration Release -sdk iphonesimulator8.3 -target #{TARGET_NAME} -arch i386 -arch x86_64 TARGET_BUILD_DIR=#{OUTPUT_DEBUG} BUILT_PRODUCTS_DIR=#{OUTPUT_DEBUG} clean build"

    sh "xcodebuild -project #{PROJECT_PATH} -configuration Release -sdk iphoneos8.3 -target #{TARGET_NAME} -arch armv7 -arch armv7s -arch arm64 TARGET_BUILD_DIR=#{OUTPUT_RELEASE} BUILT_PRODUCTS_DIR=#{OUTPUT_RELEASE} clean build"
end

desc "using lipo command to link static libraries for each device to one combined library file"
task "lipo" => OUTPUT_LIB do

    Dir.glob("#{OUTPUT_RELEASE}/*"){|path|
        p path
        file = File.basename(path)

        sh "lipo '#{OUTPUT_DEBUG}/#{file}' '#{OUTPUT_RELEASE}/#{file}' -create -output '#{OUTPUT_LIB}/#{file}'"
    }
end
開始製作static library,輸入以下command。

rake lib

整個過程大概需要10~20分鐘,要看你的機器的執行速度。如果不到一分鐘就停了,那可能是有出現錯誤。像我是遇到找不到 iphonesimulator8.2 和 iphoneos8.2 這兩個資料夾,要改成你的執行環境正確的值。

完成build static library後,你會在tmp資料裡看到兩個libcocos2d iOS.a檔,一個是給實機device跑的,另一個是給模擬器跑的。因此我們還要再做最後一步,將這兩個.a檔打包成為一個merged的.a檔。執行下面的指令。

rake lipo

這大概只需要幾秒鐘就能跑完,跑完之後你會看到一個lib資料。裡面有一個libcocos2d iOS.a檔,檔案大小約 117.9 MB。這就是最終我們要的static library檔了。

Import Static Library到你的專案

選擇.xcodeproj檔 -> Build Phases -> Link Binary With Libraries。將紅字的library全都砍掉,重新加。

將剛剛做出來的static library加進Library清單裡。
然後將你的project裡的cocos2d_libs.xcodeproj裡的 libcocos2d Mac 和 libcocos2d iOS 這兩個Target都刪除掉(就是這兩個Target才導致build project速度變慢!)。cocos2d library裡的source code則留著,以方便日後寫code時可以回頭查看。
完成了! 享受飛快的build project速度吧!

現在你可以Clean整個Project,再重build。你會發現Xcode不會再去compile cocos2d原本的source files了。只會去compile你自己project裡的files。速度大概是原本的50倍以上,我猜~

That’s all … good luck! :mrgreen:

Tags: , , , , , ,

Leave a Reply