Skip to content

Instantly share code, notes, and snippets.

@Anruin
Last active July 14, 2021 04:38
Show Gist options
  • Save Anruin/91f58a0714e9ab3427317506c4b7ef2b to your computer and use it in GitHub Desktop.
Save Anruin/91f58a0714e9ab3427317506c4b7ef2b to your computer and use it in GitHub Desktop.
Unreal Engine PowerIK Cross-Platform Build

How to build the PowerIK for UE4 for Mac (and possibly for any other platform :) )

How does it work?

There is a problem with Unreal Engine 4 that it won't compile any third-party source files provided within UE4 plugins (at least it didn't work for us Mac platform). But we can make a static library that we can statically link to the UE4 plugins shipped with the Power IK bundle. The PowerIK is very cool as it requires almost none third-party dependencies, so it can be easily built for different platforms. We use CMake to generate project files for different platforms (in our case they were Win64 and Mac). So what needs to be done?

Reorganize the SDK source files

First we have to move sdk directory shipped with the source version to the different directory. So we move it from Source/PowerIKRuntime to the Source/ThirdParty directory.

Important note! We also had to adjust all the include paths for files in SDK to be relative, e.g. #include "../include/PowerIK.h" instead of #include "PowerIKRuntime/sdk/include/PowerIK.h" as we detached them from the direct use by the UE4. I think that it can be tinkered by cmake or something else.

Next it is required to comment out two lines from the original PowerIKRuntime.Build.cs that add SDK source files to the plugin like this:

// string SrcDir = Path.Combine(ModulePath, "sdk", "src");
// PrivateIncludePaths.Add(SrcDir);

Next add the our proxy SDK module to the PublicDependencyModuleNames of the PowerIKRuntime.Build.cs as "PowerIKRuntimeSDK". Also check that "AnimGraphRuntime" added both to PowerIKTool.Build.cs and PowerIKRuntime.Build.cs public dependencies.

Add the third party library definition file

As the next step we create the file named PowerIKRuntimeSDK.Build.cs and put it next to the sdk directory in the ThirdParty directory. Basically the file tells UE4 where to get the libraries to link when we link against the new intermediate cross-platform plugin. The file is attached to the gist.

Add the CMakeLists.txt file

Next we create the file CMakeLists.txt that will be used by cmake tool to generate project files for different platforms. The file is attached to the gist.

Generate the project and build for Win64

  1. Create a _build directory in the PowerIK/Source/ThirdParty/sdk/ directory.
  2. Go to this directory with cd _build.
  3. Run cmake .. -G "Visual Studio 16 2019" -A x64. Here you can change architecture or generator, e.g. for the VS 2017 you will need to use "Visual Studio 15 2017". When the command completes, you will get the PowerIK.sln.
  4. Open the solution in Visual Studio or Rider for UE4 and build the project PowerIK.sln for release. After that you will get the static library file PowerIKRuntime.lib in the sdk/_build/Release directory.

Generate the project and build for Mac

  1. Create a _build directory in the PowerIK/Source/ThirdParty/sdk/ directory.
  2. Go to this directory with cd _build.
  3. Run cmake .. -GXcode -DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_OSX_DEPLOYMENT_TARGET="10.14". Notice that here you will probably need additional flags to specify the target architecture and deployment target. The deployment target should match the target your UE4 version is built for. The recent Xcode will build for 11.10 by default, so we had to adjust it. Changing the architecture should allow you build not only for MacOSX, but also for iOS, but we didn't test it yet. When the command completes, you will get the PowerIK.xcodeproj that you can open and build with the Xcode.
  4. Open the project in Xcode and build it or use xcodebuild command in terminal. After that you will get the static library file libPowerIKRuntime.a that is already configured to be used by the UE4 ModuleRules.

Notes

It should work for any other platform if you will generate and build required project files using cmake and your compiler.

Credits

Great thanks to Epic Games and Power Animated for Unreal Engine and PowerIK.

If you find this helpful, consider to support our project at Patreon https://www.patreon.com/artheon Or you can send a tip to Bitcoin 1E6ixVkj5bG9MpBGXhZejEcGJuPQJMWV4V or Ethereum 0xAd3c93F3F82f4bE7366E0677005c106Eaf9120df

cmake_minimum_required(VERSION 2.8.12)
project(PowerIK)
option(BUILD_ANDROID "Build for Android" OFF)
# Build using Unix. At Windows I used WSL.
if(BUILD_ANDROID)
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 29) # API level
set(CMAKE_ANDROID_ARCH_ABI arm64-v8a)
set(CMAKE_ANDROID_NDK /mnt/c/NVPACK/android-ndk-r21e)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
endif(BUILD_ANDROID)
set(PowerIK_Headers
include/PowerIK.h
include/PowerIKCore.h
include/PowerIKGround.h
include/PowerIKMath.h
include/PowerIKSettings.h
)
set(PowerIK_Sources
${PowerIK_Headers}
src/PowerIK.cpp
src/PowerIKCore.cpp
src/PowerIKGround.cpp
src/PowerIKInit.cpp
src/PowerIKMath.cpp
src/PowerIKSolve.cpp
)
set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Wall")
set(CMAKE_CXX_FLAGS_RELEASE_INIT "-Wall")
add_library(PowerIKRuntime ${PowerIK_Sources})
target_include_directories(PowerIKRuntime PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
using System.IO;
using UnrealBuildTool;
public class PowerIKRuntimeSDK : ModuleRules {
public PowerIKRuntimeSDK(ReadOnlyTargetRules Target) : base(Target) {
Type = ModuleType.External;
UnrealTargetPlatform ParsedPlatform;
if (UnrealTargetPlatform.TryParse("Win64", out ParsedPlatform) && Target.Platform == ParsedPlatform) {
// Add Win64 specific include path and Library.
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "sdk", "include"));
string PowerIkSdkPath = Path.Combine(ModuleDirectory, "sdk", "_build", "Release");
PublicAdditionalLibraries.Add(Path.Combine(PowerIkSdkPath, "PowerIKRuntime.lib"));
} else if (UnrealTargetPlatform.TryParse("Mac", out ParsedPlatform) && Target.Platform == ParsedPlatform) {
// Add Mac specific include path and Library.
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "sdk", "include"));
string PowerIkSdkPath = Path.Combine(ModuleDirectory, "sdk", "_build", "Release");
PublicAdditionalLibraries.Add(Path.Combine(PowerIkSdkPath, "libPowerIKRuntime.a"));
} else if (UnrealTargetPlatform.TryParse("Android", out ParsedPlatform) && Target.Platform == ParsedPlatform) {
// Add Android specific include path and Library.
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "sdk", "include"));
string PowerIkSdkPath = Path.Combine(ModuleDirectory, "sdk", "_build", "Release");
PublicAdditionalLibraries.Add(Path.Combine(PowerIkSdkPath, "PowerIKRuntime.a"));
// PublicDependencyModuleNames.AddRange(new string[] {"Launch"});
// string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
// AdditionalPropertiesForReceipt.Add("AndroidPlugin", Path.Combine(PluginPath, "PowerIKRuntimeSDK_UPL.xml"));
} else if (UnrealTargetPlatform.TryParse("IOS", out ParsedPlatform) && Target.Platform == ParsedPlatform) {
// Add IOS specific include path and Library.
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "sdk", "include"));
string PowerIkSdkPath = Path.Combine(ModuleDirectory, "sdk", "_build", "Release");
PublicAdditionalLibraries.Add(Path.Combine(PowerIkSdkPath, "libPowerIKRuntime.a"));
}
}
}
@opengpu
Copy link

opengpu commented Jul 14, 2021

do you know where to download the PowerIK source code now? Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment