背景
上一篇文章介绍了我配置 ffmpeg 开发环境的过程。这篇文章介绍配置 Godot Extension (GDExtension)开发环境过程中踩的一些坑。
众所周知,Godot 引擎在 4.x 大版本伊始就将旧的 GDNative 插件系统更换为了更先进(大约)的GDExtension 系统。其开发团队希望这套新系统是向后兼容的,然而不幸的是因为种种原因,minor version 0 和 1 之间就不兼容了。不过这不是今天介绍的重点。
我现在正在使用 Godot 4.2,开发环境为 Clion。
怎么构建静态库?
官方
对于构建开发 GDExtension 所需的 godot-cpp 库,官方给出的说法是使用 scons 构建系统,并且附上了相应的脚本。实际上如果你平时使用过这个,当然可以按照官方的说法搞。但我平时不用这个。另外比较坑的一点是这个脚本不会输出它使用的编译器,导致开始我编译静态库用的是 MSVC,弄到 Clion 那边编译插件动态库时候用的 MinGW,然后一直链接失败……所以说还是要注意一下。
CMake
官方也给出了使用 CMake 构建的方案。该怎么编译怎么编译就是了。
怎么写 CMakeList?
因为我用的 Clion,然后构建系统用的 CMake,所以说这上面要花点工夫。官方的样例代码 godot-cpp/test
里面有一个 CMakeList,可以作为参考。
我的项目架构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| /src /thirdparty ├─godot_cpp │ ├─bin # static lib │ ├─gd_extension │ │ └─gdextension_interface.h │ ├─gen │ │ ├─include │ │ │ └─godot_cpp │ │ │ ├─classes │ │ │ ├─core │ │ │ └─variant │ │ └─src │ │ ├─classes │ │ └─variant │ └─include │ └─godot_cpp │ ├─classes │ ├─core │ ├─templates │ └─variant └─libavx # ffmpeg ├─bin ├─include │ ├─libavcodec │ ├─libavdevice │ ├─libavfilter │ ├─libavformat │ ├─libavutil │ ├─libpostproc │ ├─libswresample │ └─libswscale └─lib └─pkgconfig
|
注意 godot-cpp/include
godot-cpp/gen/include
godot-cpp/gd_extension
里面的头文件都要导入!
并且最后还需要链接刚刚编译好的静态库。
我的 CMakeList 如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| cmake_minimum_required(VERSION 3.29) project(godot_ffmpeg)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF)
set(BUILD_AS_GODOT_EXTENSION ON) set(GODOT_EXTENSION_PLATFORM "windows") set(GODOT_EXTENSION_TARGETED_BITS 64) set(GODOT_EXTENSION_BUILD_TEMPLATE "release")
file(GLOB_RECURSE SOURCES "${CMAKE_SOURCE_DIR}/src/*.c**") file(GLOB_RECURSE HEADERS "${CMAKE_SOURCE_DIR}/src/*.h**")
include_directories(${CMAKE_SOURCE_DIR}/thirdparty/libavx/include)
link_directories(${CMAKE_SOURCE_DIR}/thirdparty/libavx/lib)
if (BUILD_AS_GODOT_EXTENSION)
message(STATUS "Building as Godot extension.") message(STATUS "Platform: ${GODOT_EXTENSION_PLATFORM}") message(STATUS "Targeted bits: ${GODOT_EXTENSION_TARGETED_BITS}") message(STATUS "Build template: ${GODOT_EXTENSION_BUILD_TEMPLATE}")
set(GODOT_GDEXTENSION_DIR ${CMAKE_SOURCE_DIR}/thirdparty/godot_cpp/gd_extension) set(CPP_BINDINGS_PATH ${CMAKE_SOURCE_DIR}/thirdparty/godot_cpp) set(CPP_LIB_PATH ${CMAKE_SOURCE_DIR}/thirdparty/godot_cpp/bin)
include_directories(${GODOT_GDEXTENSION_DIR}) include_directories(${CPP_BINDINGS_PATH}/include) include_directories(${CPP_BINDINGS_PATH}/gen/include)
link_directories(${CMAKE_SOURCE_DIR}/thirdparty/godot_cpp/bin/)
add_library(godot_ffmpeg SHARED ${SOURCES} ${HEADERS}) else ()
message(STATUS "Building as standalone executable.") add_executable(godot_ffmpeg ${SOURCES} ${HEADERS})
endif ()
if (BUILD_AS_GODOT_EXTENSION)
target_include_directories(${PROJECT_NAME} PRIVATE ${CPP_BINDINGS_PATH}/include ${CPP_BINDINGS_PATH}/gen/include ${GODOT_GDEXTENSION_DIR} )
endif ()
target_link_libraries( godot_ffmpeg PRIVATE avcodec avdevice avfilter avformat avutil postproc swresample swscale )
if (BUILD_AS_GODOT_EXTENSION)
message(STATUS "Linking from: ${CPP_LIB_PATH}/libgodot-cpp.${GODOT_EXTENSION_PLATFORM}.${GODOT_EXTENSION_BUILD_TEMPLATE}.${GODOT_EXTENSION_TARGETED_BITS}.a")
target_link_libraries(godot_ffmpeg PRIVATE ${CPP_LIB_PATH}/libgodot-cpp.${GODOT_EXTENSION_PLATFORM}.${GODOT_EXTENSION_BUILD_TEMPLATE}.${GODOT_EXTENSION_TARGETED_BITS}.a)
endif ()
|
以上。