日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

Unity3D跨平台动态库编译---记kcp基于CMake的各平台构建实践

發(fā)布時(shí)間:2023/12/13 综合教程 27 生活家
生活随笔 收集整理的這篇文章主要介紹了 Unity3D跨平台动态库编译---记kcp基于CMake的各平台构建实践 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一  為什么需要?jiǎng)討B(tài)庫(kù)

  1)提供原生代碼(native code)的支持,也叫原生插件,但是我實(shí)踐的是c/cpp跨平臺(tái)動(dòng)態(tài)庫(kù),這里不具體涉及安卓平臺(tái)java庫(kù)和ios平臺(tái)的objectc庫(kù)構(gòu)建。

  2)某些開(kāi)源庫(kù)是c/cpp編寫(xiě),沒(méi)有對(duì)應(yīng)c#版本

  3)或者有c#版本實(shí)現(xiàn),但是效率或者gc達(dá)不到期望效果,特別是GC,一般的開(kāi)源庫(kù)c#版本的作者,對(duì)gc優(yōu)化得大多不好

  4)追求效率,比如A*尋路等開(kāi)銷(xiāo)比較大的算法,想做下優(yōu)化

  5)某些模塊,如網(wǎng)絡(luò)模塊,需要Unity客戶(hù)端和后端跑一份相同的邏輯代碼,而不想維護(hù)兩份語(yǔ)言的實(shí)現(xiàn)

二  示例demo選擇

  前陣子由于項(xiàng)目需要,編譯了一下kcp庫(kù),這里拿kcp編譯到Unity的各平臺(tái)動(dòng)態(tài)庫(kù)來(lái)做一次總結(jié),kcp的github地址:https://github.com/skywind3000/kcp。

  有關(guān)這個(gè)庫(kù)的其它信息這里不做介紹,它本質(zhì)就是一個(gè)可靠UDP的網(wǎng)絡(luò)庫(kù),我們項(xiàng)目是用在了一款多人實(shí)時(shí)射擊類(lèi)游戲中。

三  編譯工具選擇

  這里使用的是CMake,官網(wǎng)地址為:https://cmake.org/。有關(guān)CMake的使用資料自行網(wǎng)絡(luò)獲取,我這里只說(shuō)一點(diǎn),這是一個(gè)跨平臺(tái)的構(gòu)建工具,針對(duì)不同的平臺(tái),只需要一份描述文件,很方便,不需要每個(gè)平臺(tái)去寫(xiě)makefile。

四  示例demo選擇

  

  其中:

    1)cmke目錄:包含CMake在安卓、iOS平臺(tái)進(jìn)行構(gòu)建時(shí)需要要到的兩個(gè)文件:android.toolchain.cmake、iOS.cmake

    2)Plugins目錄:各平臺(tái)構(gòu)建的輸出目錄,構(gòu)建完成后可以直接放置到Unity項(xiàng)目Assdets目錄下使用

    3)CMakeLists.txt文件:主要要由我們自己編寫(xiě)的一個(gè)文件,cmake根據(jù)CMakeLists生成各個(gè)平臺(tái)編譯的中間文件以及makefile文件

    4)目標(biāo)庫(kù)源代碼:kcp.h、kcp.c

    5)make_xxx:各平臺(tái)執(zhí)行構(gòu)建腳本文件,這些文件基本是固定的,不需要做什么修改

五  項(xiàng)目簡(jiǎn)要說(shuō)明

  1、kcp項(xiàng)目需要做的調(diào)整

    kcp.c不需要?jiǎng)樱琸cp.h修改部分如下:

 1 #ifdef DLL_EXPORTS
 2 #define KCPDLL _declspec(dllexport)
 3 #else
 4 #define KCPDLL
 5 #endif
 6 
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 
11     //---------------------------------------------------------------------
12     // interface
13     //---------------------------------------------------------------------
14 
15     // create a new kcp control object, 'conv' must equal in two endpoint
16     // from the same connection. 'user' will be passed to the output callback
17     // output callback can be setup like this: 'kcp->output = my_udp_output'
18     KCPDLL ikcpcb* ikcp_create(IUINT32 conv, void *user);
19     //其它導(dǎo)出接口省略
20 
21 #ifdef __cplusplus
22 }
23 #endif

  2、CMakeLists文件編寫(xiě)

 1 cmake_minimum_required(VERSION 2.8)
 2 
 3 if ( WIN32 AND NOT CYGWIN AND NOT ( CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" ) )
 4     set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT" CACHE STRING "")
 5     set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd" CACHE STRING "")
 6     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT" CACHE STRING "")
 7     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd" CACHE STRING "")
 8 endif ()
 9 
10 project(kcp)
11 
12 if ( IOS )
13         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode")
14         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode")
15 endif ()
16 
17 find_path(KCP_PROJECT_DIR NAMES SConstruct
18     PATHS 
19     ${CMAKE_SOURCE_DIR}
20     NO_DEFAULT_PATH
21     )
22 
23 MARK_AS_ADVANCED(KCP_PROJECT_DIR)
24 
25 set ( KCP_CORE
26     kcp.c
27 )
28 
29 macro(source_group_by_dir proj_dir source_files)
30     if(MSVC OR APPLE)
31         get_filename_component(sgbd_cur_dir ${proj_dir} ABSOLUTE)
32         foreach(sgbd_file ${${source_files}})
33             get_filename_component(sgbd_abs_file ${sgbd_file} ABSOLUTE)
34             file(RELATIVE_PATH sgbd_fpath ${sgbd_cur_dir} ${sgbd_abs_file})
35             string(REGEX REPLACE "(.*)/.*" \1 sgbd_group_name ${sgbd_fpath})
36             string(COMPARE EQUAL ${sgbd_fpath} ${sgbd_group_name} sgbd_nogroup)
37             string(REPLACE "/" "\" sgbd_group_name ${sgbd_group_name})
38             if(sgbd_nogroup)
39                 set(sgbd_group_name "\")
40             endif(sgbd_nogroup)
41             source_group(${sgbd_group_name} FILES ${sgbd_file})
42         endforeach(sgbd_file)
43     endif(MSVC OR APPLE)
44 endmacro(source_group_by_dir)
45 
46 source_group_by_dir(${CMAKE_CURRENT_SOURCE_DIR} KCP_CORE)
47 
48 if (APPLE)
49     if (IOS)
50         set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)")
51         add_library(kcp STATIC
52            ${KCP_CORE}
53         )
54     else ()
55         set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
56         add_library(kcp MODULE
57             ${KCP_CORE}
58         )
59         set_target_properties ( kcp PROPERTIES BUNDLE TRUE )
60         #set_target_properties ( kcp PROPERTIES FRAMEWORK TRUE )
61         #set_target_properties ( kcp PROPERTIES MACOSX_RPATH TRUE )
62     endif ()
63 else ( )
64     add_library(kcp SHARED
65         ${KCP_CORE}
66     )
67 endif ( )
68 
69 if ( WIN32 AND NOT CYGWIN )
70     target_compile_definitions (kcp PRIVATE DLL_EXPORTS)
71 endif ( )

    1)第10行:指定項(xiàng)目名稱(chēng)為kcp

    2)第26行:指定要編譯的c/cpp文件

    3)第70行:指定預(yù)定義宏DLL_EXPORTS,這個(gè)宏只有在window平臺(tái)編譯dll動(dòng)態(tài)庫(kù)才需要,其它平臺(tái)不需要

    4)其它沒(méi)什么好說(shuō)的,在構(gòu)建你自己的項(xiàng)目時(shí),只需要注意的帶有“kcp”字樣的地方替換為你自己對(duì)應(yīng)的項(xiàng)目名稱(chēng)即可。

  3、各平臺(tái)構(gòu)建腳本

    1)window32位系統(tǒng):make_win32.bat

1 mkdir build32 & pushd build32
2 cmake -G "Visual Studio 14 2015" ..
3 popd
4 cmake --build build32 --config Release
5 md Pluginsx86
6 copy /Y build32Releasekcp.dll Pluginsx86kcp.dll
7 rmdir /S /Q build32
8 pause

    2)windows64位系統(tǒng):make_win64.bat

1 mkdir build64 & pushd build64
2 cmake -G "Visual Studio 14 2015 Win64" ..
3 popd
4 cmake --build build64 --config Release
5 md Pluginsx86_64
6 copy /Y build64Releasekcp.dll Pluginsx86_64kcp.dll
7 rmdir /S /Q build64
8 pause

    3)linux32位系統(tǒng):make_linux32.sh

1 mkdir -p build_linux32 && cd build_linux32
2 cmake -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 ../
3 cd ..
4 cmake --build build_linux32 --config Release
5 cp build_linux32/kcp.so Plugins/x86/kcp.so
6 rm -rf build_linux32

    4)linux64位系統(tǒng):make_linux64.sh

1 mkdir -p build_linux64 && cd build_linux64
2 cmake ../
3 cd ..
4 cmake --build build_linux64 --config Release
5 cp build_linux64/kcp.so Plugins/x86_64/kcp.so
6 rm -rf build_linux64

    5)Mac系統(tǒng):make_osx.sh

1 mkdir -p build_osx && cd build_osx
2 cmake -GXcode ../
3 cd ..
4 cmake --build build_osx --config Release
5 mkdir -p Plugins/kcp.bundle/Contents/MacOS/
6 cp build_osx/Release/kcp.bundle/Contents/MacOS/kcp Plugins/kcp.bundle/Contents/MacOS/kcp
7 rm -rf build_osx

    6)android系統(tǒng):make_android.sh

 1 if [ -z "$ANDROID_NDK" ]; then
 2     export ANDROID_NDK=~/android-ndk-r10e
 3 fi
 4 
 5 mkdir -p build_v7a && cd build_v7a
 6 cmake -DANDROID_ABI=armeabi-v7a -DCMAKE_TOOLCHAIN_FILE=../cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-clang3.6 -DANDROID_NATIVE_API_LEVEL=android-9 ../
 7 cd ..
 8 cmake --build build_v7a --config Release
 9 mkdir -p Plugins/Android/libs/armeabi-v7a/
10 cp build_v7a/libkcp.so Plugins/Android/libs/armeabi-v7a/libkcp.so
11 rm -rf build_v7a
12 
13 mkdir -p build_x86 && cd build_x86
14 cmake -DANDROID_ABI=x86 -DCMAKE_TOOLCHAIN_FILE=../cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN_NAME=x86-clang3.5 -DANDROID_NATIVE_API_LEVEL=android-9 ../
15 cd ..
16 cmake --build build_x86 --config Release
17 mkdir -p Plugins/Android/libs/x86/
18 cp build_x86/libkcp.so Plugins/Android/libs/x86/libkcp.so
19 rm -rf build_x86

    7)iOS系統(tǒng):make_ios.sh

 1 mkdir -p build_ios && cd build_ios
 2 cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/iOS.cmake  -GXcode ../
 3 cd ..
 4 cmake --build build_ios --config Release
 5 mkdir -p Plugins/iOS/
 6 exist_armv7=`lipo -info build_ios/Release-iphoneos/libkcp.a | grep armv7 | wc -l`
 7 exist_arm64=`lipo -info build_ios/Release-iphoneos/libkcp.a | grep arm64 | wc -l`
 8 if [ $[exist_armv7] -eq 0 ]; then
 9     echo "** ERROR **: No support for armv7, maybe XCode version is to high, use manual_build_ios instead!"
10 elif [ $[exist_arm64] -eq 0 ]; then
11     echo "** ERROR ** : No support for arm64, maybe XCode version is to high, use manual_build_ios instead!"
12 else
13     cp build_ios/Release-iphoneos/libkcp.a Plugins/iOS/libkcp.a
14     rm -rf build_io
15 fi

    8)Windows Phone系統(tǒng):make_uwp.bat

 1 mkdir build_uwp & pushd build_uwp
 2 cmake -G "Visual Studio 14 2015" -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 ..
 3 popd
 4 cmake --build build_uwp --config Release
 5 md PluginsWSAx86
 6 copy /Y build_uwpReleasekcp.dll PluginsWSAx86kcp.dll
 7 rmdir /S /Q build_uwp
 8 
 9 mkdir build_uwp64 & pushd build_uwp64
10 cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 ..
11 popd
12 cmake --build build_uwp64 --config Release
13 md PluginsWSAx64
14 copy /Y build_uwp64Releasekcp.dll PluginsWSAx64kcp.dll
15 rmdir /S /Q build_uwp64
16 
17 mkdir build_uwp_arm & pushd build_uwp_arm
18 cmake -G "Visual Studio 14 2015 ARM" -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 ..
19 popd
20 cmake --build build_uwp_arm --config Release
21 md PluginsWSAARM
22 copy /Y build_uwp_armReleasekcp.dll PluginsWSAARMkcp.dll
23 rmdir /S /Q build_uwp_arm
24 
25 pause

    9)這些腳本都很簡(jiǎn)單明了,像需要的VS版本、安卓的NDK版本等等,一看便知。要移植到你自己的構(gòu)建項(xiàng)目也很簡(jiǎn)單,基本只需要修改項(xiàng)目名稱(chēng)即可。

六  各平臺(tái)構(gòu)建環(huán)境簡(jiǎn)要說(shuō)明

  1)以下各平臺(tái),均需要安裝CMake,安裝教程,包括各平臺(tái)環(huán)境變量等的配置自行谷歌,很多相關(guān)帖子。

  2)window系統(tǒng)和windows phone系統(tǒng):在window系統(tǒng)中執(zhí)行對(duì)應(yīng)的.bat腳本即可,windows phone的編譯需要相關(guān)SDK。本帖使用VS2015,windows phone暫時(shí)不需要,所以沒(méi)有構(gòu)建測(cè)試過(guò)。

  3)linux系統(tǒng):在linux系統(tǒng)中執(zhí)行對(duì)應(yīng)的.sh腳本即可

  4)mac系統(tǒng):在mac系統(tǒng)中執(zhí)行對(duì)應(yīng)的.sh腳本即可

  5)iOS系統(tǒng):在mack系統(tǒng)中執(zhí)行對(duì)應(yīng)的.sh腳本即可。需要xcode版本8.1,版本太高會(huì)有問(wèn)題,可以進(jìn)行手動(dòng)構(gòu)建,參考博文:iOS代碼封裝成.a文件(封裝SDK)。真機(jī)上的.a動(dòng)態(tài)庫(kù)需要同時(shí)支持armv7,ram64架構(gòu),查看你編譯出來(lái)的.a是否是正確架構(gòu)可使用lipo -info kcp.a

  6)android系統(tǒng):安卓系統(tǒng)可以在各個(gè)平臺(tái)編譯,我這里是在linux系統(tǒng)中編譯的,執(zhí)行對(duì)應(yīng)的.sh腳本即可,andorid SDK版本為:android-ndk-r10e。關(guān)于SDK安裝以及環(huán)境變量配置自行谷歌。

  7)可能根據(jù)各位自己的情況,編譯過(guò)程會(huì)遇到各種小問(wèn)題,但是這些問(wèn)題幾乎都是出在環(huán)境上,如環(huán)境變量、SDK版本、xcode版本等,我這里已經(jīng)對(duì)環(huán)境信息給了足夠的說(shuō)明,如果你實(shí)踐當(dāng)中問(wèn)題解決不了,可以參考我這里列舉的環(huán)境。

  8).sh文件在window下編輯可能會(huì)存在文件結(jié)束符問(wèn)題,使用doc2unix命令轉(zhuǎn)換就好,遇到權(quán)限問(wèn)題使用chmod命令就好,其它可能遇到的細(xì)節(jié)問(wèn)題自己耐心多多摸索,問(wèn)題都不大。

七  Unity項(xiàng)目動(dòng)態(tài)庫(kù)配置簡(jiǎn)要說(shuō)明

  1、輸出目錄結(jié)構(gòu)

    由于我們公司全部在window下開(kāi)發(fā),所以沒(méi)有編譯linux下的動(dòng)態(tài)庫(kù),如果你們需要,將在x86、x86_64目錄下存在libkcp.so文件。同樣,window phone平臺(tái)也沒(méi)實(shí)測(cè)。

  2、window平臺(tái)

    x86、x86_64下的.dll文件:

  3、Mac平臺(tái)

    kcp.bundle,配置時(shí)選擇osx系統(tǒng),任意cpu

  4、linux平臺(tái)

    x86、x86_64下的.so文件,相應(yīng)配置

  5、andorid平臺(tái)

    Android子目錄下的.so文件,選擇Android Platform,cpu架構(gòu)做對(duì)應(yīng)勾選,很簡(jiǎn)單,不再截圖

  6、iOS平臺(tái)

    選擇iOS Platform

八  動(dòng)態(tài)庫(kù)項(xiàng)目使用

  編寫(xiě)對(duì)應(yīng)kcp.cs文件,聲明外部函數(shù),腳本如下:

 1 namespace KCP
 2 {
 3     using System;
 4     using System.Runtime.InteropServices;
 5 
 6     public class kcp
 7     {
 8 #if UNITY_IPHONE && !UNITY_EDITOR
 9         const string KcpDLL = "__Internal";
10 #else
11         const string KcpDLL = "kcp";
12 #endif
13 
14         [DllImport(KcpDLL, CallingConvention=CallingConvention.Cdecl)]
15         public static extern uint ikcp_check(IntPtr kcp, uint current);、
16         //其它接口省略
17     }
18 }

  1)函數(shù)調(diào)用約定指明為cdecl

  2)所有接口以靜態(tài)外部函數(shù)導(dǎo)出

  3)DllIport在iOS上和其它平臺(tái)導(dǎo)出使用的參數(shù)不一樣

  4)在構(gòu)建你自己的動(dòng)態(tài)庫(kù)時(shí)依葫蘆畫(huà)瓢就好,沒(méi)啥太多要說(shuō)的

九  kcp_build完整構(gòu)建工程

  github地址:https://github.com/smilehao/kcp_bulild

博客:http://www.cnblogs.com/SChivas/

倉(cāng)庫(kù):https://github.com/smilehao/

郵箱:703016035@qq.com

感謝您的閱讀,如果您覺(jué)得本文對(duì)您有所幫助,請(qǐng)點(diǎn)一波推薦。

歡迎各位點(diǎn)評(píng)轉(zhuǎn)載,但是轉(zhuǎn)載文章之后務(wù)必在文章頁(yè)面中給出作者和原文鏈接,謝謝。

總結(jié)

以上是生活随笔為你收集整理的Unity3D跨平台动态库编译---记kcp基于CMake的各平台构建实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。