Skip to content

Commit

Permalink
Merge pull request #52 from Virus-Axel/cross_compile_test_ios
Browse files Browse the repository at this point in the history
Add automated build script and fix compatibility in wrapper
  • Loading branch information
Virus-Axel authored May 5, 2023
2 parents f899a2a + 65abc90 commit c6408b4
Show file tree
Hide file tree
Showing 17 changed files with 188 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Cargo.lock
example/SolanaSDK.gd
example/solana_sdk.tscn
example/addons/

/bin/

.vscode/
.godot/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@
path = solana
url = [email protected]:solana-labs/solana.git
branch = master
[submodule "build-containers-with-rust"]
path = build-containers-with-rust
url = [email protected]:Virus-Axel/build-containers-with-rust.git
138 changes: 128 additions & 10 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,74 @@ import os
import sys
from pathlib import Path

CONTAINER_BUILD_PATH = "build-containers-with-rust"
LIBRARY_NAME = "godot-solana-sdk"

def image_id_from_repo_name(repository_name):
return os.popen('podman images --format {{.ID}} --filter=reference=' + repository_name).read()

def get_build_command(platform, architecture):
arguments = ""
env_options = ""
if platform == 'ios':
arguments = ' IOS_SDK_PATH="/root/ioscross/arm64/SDK/iPhoneOS16.1.sdk" IOS_TOOLCHAIN_PATH="/root/ioscross/arm64" ios_triple="arm-apple-darwin11-"'
elif platform == 'macos':
arguments = ' macos_sdk_path="/root/osxcross/target/SDK/MacOSX13.0.sdk/" osxcross_sdk="darwin22"'
elif platform == 'android':
arguments = ""
elif platform == 'javascript':
env_options = 'bash -c "source /root/emsdk/emsdk_env.sh && '
arguments = '"'

return env_options + 'scons -j 4 platform=' + platform + ' arch=' + architecture + ' target=template_release' + arguments


def build_in_container(platform, container_path, architecture, keep_container=False, keep_images=False):
CONTAINER_BUILD_COMMAND = 'echo y | ./build.sh 4.x f36'
REPOSITORY_NAME = {
'ios': 'localhost/godot-ios',
'macos': 'localhost/godot-osx',
'linux': 'localhost/godot-linux',
'windows': 'localhost/godot-windows',
'android': 'localhost/godot-android',
'javascript': 'localhost/godot-web'
}

# Build missing containers
env.Execute('cd ' + container_path + ' && ' + CONTAINER_BUILD_COMMAND)

image_id = image_id_from_repo_name(REPOSITORY_NAME[platform])

env.Execute('podman run -d -it --name test_container ' + image_id)
env.Execute('podman cp . test_container:/root/')

build_command = get_build_command(platform, architecture)

env.Execute('podman exec -w /root/godot-solana-sdk/ test_container ' + build_command)

env.Execute('podman cp test_container:/root/godot-solana-sdk/example/bin/ .')

if not keep_container:
env.Execute('podman rm -f test_container')

if not keep_images:
env.Execute('podman rmi -f ' + image_id)


def build_all(env, container_path, keep_images):
build_in_container('linux', container_path, 'x86_64', keep_images=keep_images)
build_in_container('windows', container_path, 'x86_64', keep_images=keep_images)
build_in_container('javascript', container_path, 'wasm32', keep_images=keep_images)
build_in_container('android', container_path, 'aarch64', keep_images=keep_images)
build_in_container('ios', container_path, 'arm64', keep_images=keep_images)
build_in_container('macos', container_path, 'aarch64', keep_images=keep_images)

home_directory = Path.home()
cargo_build_command = str(home_directory) + '/.cargo/bin/cargo build'

AddOption('--keep_images', dest='keep_images', default=False, action='store_true', help='Keeps the podman images for future builds.')
AddOption('--container_build', dest='container_build', default=False, action='store_true', help='Build in containers for all platforms (specify one to override)')

env = SConscript("godot-cpp/SConstruct")

platform_arg = ARGUMENTS.get("platform", ARGUMENTS.get("p", False))
Expand All @@ -17,31 +82,66 @@ linker_settings = ""
library_path = "wrapper/target/debug/"

if platform_arg == "android":
linker_settings = 'AR=llvm-ar RUSTFLAGS="-C linker=aarch64-linux-android30-clang"'
linker_settings = 'AR=llvm-ar RUSTFLAGS="-C linker=aarch64-linux-android31-clang"'
target_arg = "--target aarch64-linux-android"
library_path = "wrapper/target/aarch64-linux-android/release/"

elif platform_arg == "macos":
target_arg = "--target x86_64-apple-darwin"
library_path = "wrapper/target/x86_64-apple-darwin/release/"
target_arg = "--target aarch64-apple-darwin"
library_path = "wrapper/target/aarch64-apple-darwin/release/"

elif platform_arg == "windows":
target_arg = "--target x86_64-pc-windows-gnu"
library_path = "wrapper/target/x86_64-pc-windows-gnu/release/"

elif platform_arg == "linux":
target_arg = "--target x86_64-unknown-linux-gnu"
library_path = "wrapper/target/x86_64-unknown-linux-gnu/debug/"
library_path = "wrapper/target/x86_64-unknown-linux-gnu/release/"

elif platform_arg == "javascript":
target_arg = "--target wasm-unknown-unknown"
library_path = "wrapper/target/wasm-unknown-unknown/release/"
target_arg = "--target wasm32-unknown-unknown"
library_path = "wrapper/target/wasm32-unknown-unknown/release/"
env.Append(LINKFLAGS=['--js-library', 'wrapper/target/wasm32-unknown-unknown/release/module.js'])

elif platform_arg == "ios":
linker_settings = 'LD_LIBRARY_PATH=/root/ioscross/arm64/lib/ SDKROOT=/root/ioscross/arm64/SDK/iPhoneOS16.1.sdk/'
target_arg = "--target aarch64-apple-ios"
library_path = "wrapper/target/aarch64-apple-ios/release/"
# Adjust environment in build containers to work with rust wrapper

env.Append(LIBS = ['objc'])
env.Append(LIBS = ['c'])
env.Append(LIBS = ['c++'])
env.Append(LINKFLAGS=['-framework', 'Security', '-L', '/root/ioscross/arm64/lib/'])

env['LINK'] = "/root/osxcross/target/bin/aarch64-apple-darwin22-ld"
env.Append(LD_LIBRARY_PATH=['/root/ioscross/arm64/lib/'])

#env['LINKFLAGS'].remove(["-isysroot", env["IOS_SDK_PATH"], "-F" + env["IOS_SDK_PATH"]])
#env.Subst('LINKFLAGS', "-isysroot", "-syslibroot")
#env['LINKFLAGS'] = [s.subst('-isysroot', '-syslibroot') for s in env['LINKFLAGS']]
for index in range(len(env['LINKFLAGS'])):
if env['LINKFLAGS'][index] == "-isysroot":
env['LINKFLAGS'][index] = "-syslibroot"

env['SHLINKFLAGS'].remove("-shared")
env.Append(LINKFLAGS=['-dylib'])

rust_env = Environment(ENV=os.environ)

rust_env.Execute('cd wrapper && ' + linker_settings + ' ' + cargo_build_command + ' ' + target_arg + ' --release')
if platform_arg == 'javascript':
rust_env.Execute('emcc -s MODULARIZE=1 wrapper/target/wasm32-unknown-unknown/release/libwrapper.a -o wrapper/target/wasm32-unknown-unknown/release/module.js')

env.Execute ('cd wrapper && ' + linker_settings + ' ' + cargo_build_command + ' ' + target_arg)
env.Append(LIBPATH = [library_path])
env.Append(LIBS = ['wrapper'])

if platform_arg != 'javascript':
env.Append(LIBS = ['wrapper'])

if platform_arg == 'windows':
env.Append(LIBS = ['ws2_32'])
env.Append(LIBS = ['bcrypt'])
env.Append(LIBS = ['userenv'])

# Build wrapper library

Expand All @@ -62,15 +162,33 @@ sources = Glob("src/*.cpp")

if env["platform"] == "macos":
library = env.SharedLibrary(
"example/bin/libgdexample.{}.{}.framework/libgdexample.{}.{}".format(
"example/bin/lib" + LIBRARY_NAME + ".{}.{}.framework/lib" + LIBRARY_NAME + ".{}.{}".format(
env["platform"], env["target"], env["platform"], env["target"]
),
source=sources,
)
else:
library = env.SharedLibrary(
"example/bin/libgdexample{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
"example/bin/lib" + LIBRARY_NAME + "{}{}".format(env["suffix"], env["SHLIBSUFFIX"]),
source=sources,
)


# Handle the container build
if env.GetOption('container_build'):
keep_images = False

if env.GetOption('keep_images'):
keep_images = True

if 'platform' in ARGUMENTS:
architecture = 'x86_64'
if 'arch' in ARGUMENTS:
architecture = ARGUMENTS['arch']

build_in_container(ARGUMENTS['platform'], CONTAINER_BUILD_PATH, architecture, keep_images=keep_images, keep_container=True)

else:
build_all(env, CONTAINER_BUILD_PATH, keep_images)

Default(library)
1 change: 1 addition & 0 deletions build-containers-with-rust
4 changes: 0 additions & 4 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
# Godot 4+ specific ignores
.godot/

*.import
icon.svg
project.godot
7 changes: 0 additions & 7 deletions example/bin/gdexample.gdextension

This file was deleted.

12 changes: 12 additions & 0 deletions example/bin/godot-solana-sdk.gdextension
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[configuration]

entry_symbol = "solana_sdk_library_init"

[libraries]

linux.64="libgodot-solana-sdk.linux.template_debug.x86_64.so"
ios="libgodot-solana-sdk.ios.template_release.arm64.dylib"
windows.64="libgodot-solana-sdk.windows.template_debug.x86_64.so"
macos="libgodot-solana-sdk.macos.template_release.framework"
javascript="libgodot-solana-sdk.javascript.template_debug.wasm32.wasm"
android="libgodot-solana-sdk.android.template_release.arm64.so"
1 change: 0 additions & 1 deletion solana
Submodule solana deleted from 3bc670
2 changes: 1 addition & 1 deletion wrapper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ bs58 = "*"
bincode = "*"

[lib]
crate-type = ["staticlib"]
crate-type = ["staticlib"]
2 changes: 2 additions & 0 deletions wrapper/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![no_std]

pub mod utils;
pub mod modules;
pub mod test;
6 changes: 5 additions & 1 deletion wrapper/src/modules/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ use solana_sdk::{
pubkey::Pubkey,
account::Account,
};
use std::ffi::c_ulonglong;
use core::ffi::c_ulonglong;

extern crate alloc;
use alloc::boxed::Box;

#[no_mangle]
pub extern "C" fn create_account(lamports: c_ulonglong, space: c_ulonglong, owner: *const Pubkey) -> *mut Account{
let pubkey_ref = unsafe{*owner};
Box::into_raw(Box::new(Account::new(lamports, space as usize, &pubkey_ref)))
}


#[no_mangle]
pub extern "C" fn free_account(account: *mut Account){
unsafe{
Expand Down
4 changes: 4 additions & 0 deletions wrapper/src/modules/account_meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ use solana_sdk::{
pubkey::Pubkey,
instruction::AccountMeta,
};

extern crate alloc;
use alloc::boxed::Box;

#[no_mangle]
pub extern "C" fn create_account_meta(account_key: *const Pubkey, is_signer: bool, is_writeable: bool) -> *mut AccountMeta{
let account_ref = unsafe{*account_key};
Expand Down
5 changes: 4 additions & 1 deletion wrapper/src/modules/hash.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::mem;
use core::mem;

use solana_sdk::hash::Hash;

extern crate alloc;
use alloc::{boxed::Box, vec::Vec};

#[no_mangle]
pub extern "C" fn create_unique_hash() -> *mut Hash{
Box::into_raw(Box::new(Hash::new_unique()))
Expand Down
10 changes: 7 additions & 3 deletions wrapper/src/modules/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ use solana_sdk::{
},
pubkey::Pubkey,
};
use std::ffi::{

extern crate alloc;
use alloc::{vec, boxed::Box, vec::Vec};

use core::ffi::{
c_uchar,
c_int,
};
Expand All @@ -22,15 +26,15 @@ pub extern "C" fn create_instruction_with_bytes(program_id: *const Pubkey, data_
account_metas.push(account_meta_ref);
};

std::mem::forget(pointer_array);
core::mem::forget(pointer_array);

let data = unsafe {
Vec::from_raw_parts(data_array, data_size as usize, data_size as usize)
};

let ret = Instruction::new_with_bytes(program_id_ref, &data, account_metas);

std::mem::forget(data);
core::mem::forget(data);

Box::into_raw(Box::new(ret))
}
Expand Down
8 changes: 6 additions & 2 deletions wrapper/src/modules/keypair.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use solana_sdk::signer::keypair::Keypair;
use std::mem;
use core::mem;

extern crate alloc;

use alloc::{boxed::Box, vec::Vec};

#[no_mangle]
pub extern "C" fn create_keypair() -> *mut Keypair{
Expand All @@ -12,7 +16,7 @@ pub extern "C" fn create_keypair_from_bytes(bytes: *mut u8) -> *mut Keypair{

let ret = match Keypair::from_bytes(arr.clone().as_slice()){
Ok(v) => v,
Err(_) => return std::ptr::null::<Keypair>() as *mut Keypair,
Err(_) => return core::ptr::null::<Keypair>() as *mut Keypair,
};

mem::forget(arr);
Expand Down
12 changes: 4 additions & 8 deletions wrapper/src/modules/pubkey.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use std::mem;
use core::mem;

use solana_sdk::pubkey::Pubkey;
extern crate alloc;

#[no_mangle]
pub extern "C" fn print_pubkey(key: *const Pubkey){
unsafe{
println!("{}\n", (*key).to_string());
}
}
use solana_sdk::pubkey::Pubkey;
use alloc::{boxed::Box, vec::Vec};

#[no_mangle]
pub extern "C" fn create_unique_pubkey() -> *mut Pubkey{
Expand Down
Loading

0 comments on commit c6408b4

Please sign in to comment.