Skip to content

Commit

Permalink
feat: The first version of Java library that contains GDAL 3.5.3 and …
Browse files Browse the repository at this point in the history
…all required native libraries
  • Loading branch information
REASY committed Jan 17, 2023
1 parent c5acdc4 commit eceff81
Show file tree
Hide file tree
Showing 89 changed files with 1,332 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.jar filter=lfs diff=lfs merge=lfs -text
src/main/resources/native/linux-x86-64/* filter=lfs diff=lfs merge=lfs -text
*.gpkg filter=lfs diff=lfs merge=lfs -text
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
build
out
.idea
.gradle
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
gdal-jni-with-native
======
This project builds GDAL, extract native libraries and makes it available as Java library. At the moment it only supports GDAL on Ubuntu x64 (Linux)

### Build
In order to build the project the following should happen:
1. Build GDAL docker image, [build_gdal.sh](scripts.build_gdal.sh) is responsible for that
2. Build [lddtopo-rs](https://github.com/REASY/lddtopo-rs), [build_lddtopo.sh](scripts/build_lddtopo.sh) is responsible for that
3. Analyze the dependencies of /usr/share/java/libgdalalljni.so by building DAG and running topological sort on it
4. Copy all required native modules to src/main/resources/native
5. Generate src/main/resources/native/modules.txt that contains new line separated list of modules to be loaded. The order comes from topological sort!

All of this is done in a script [generate_native_modules.sh](scripts/generate_native_modules.sh), just run it from root folder of the repo to get the final JAR
```bash
./scripts/generate_native_modules.sh
```
81 changes: 81 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
group = 'gdal-jni-with-native'
version = '3.5.3.0'

buildscript {
repositories {
jcenter()
mavenLocal()
mavenCentral()
maven { url "https://plugins.gradle.org/m2/" }
}
}

apply plugin: 'maven'
apply plugin: 'java'
apply plugin: 'idea'

sourceCompatibility = 1.8
targetCompatibility = 1.8

sourceSets {
main {
resources {
srcDir "src/main/resources"
}
}
test {
resources {
srcDir "src/test/resources"
}
}
}

repositories {
mavenLocal()
mavenCentral()
jcenter()
}

dependencies {
implementation group: 'net.java.dev.jna', name: 'jna', version: '5.13.0'
implementation files("libs/gdal-3.5.3.jar",
"libs/gdal-3.5.3-javadoc.jar",
"libs/gdal-3.5.3-sources.jar"
)
}

jar {
from {
configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}

task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}

task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}

artifacts {
archives sourcesJar
archives javadocJar
}

install {
repositories.mavenInstaller {
pom.project {
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
distribution 'repo'
}
}
}
}
}
10 changes: 10 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Docker images
=====

# GDAL image with native libraries
[gdal-ubuntu-small.dockerfile](gdal-ubuntu-small.dockerfile) is based on the one provided by GDAL team, [Small: osgeo/gdal:ubuntu-small-latest](https://github.com/OSGeo/gdal/tree/release/3.5/docker#small-osgeogdalubuntu-small-latest) with two modifications:
- Added swig and Java to be able to generate JNI
- [Removed the load of native library in gdal](https://github.com/OSGeo/gdal/blob/release/3.5/swig/include/java/gdal_java.i#L18). Proper load of all required native all libraries is the reason why this library exists.

# lddtopo
[lddtopo.dockerfile](lddtopo.dockerfile) is built on top of gdal-ubuntu-small.dockerfile. It uses https://github.com/REASY/lddtopo-rs to build the dependency graph of a provided library and run topological sort to get the order in which they should be loaded.
20 changes: 20 additions & 0 deletions docker/bh-set-envvars.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/sh
set -eu

if test "${TARGET_ARCH:-}" != ""; then
if test "${TARGET_ARCH}" = "arm64"; then
export GCC_ARCH=aarch64
else
echo "Unhandled architecture: ${TARGET_ARCH}"
exit 0
fi
export APT_ARCH_SUFFIX=":${TARGET_ARCH}"
export CC=${GCC_ARCH}-linux-gnu-gcc-9
export CXX=${GCC_ARCH}-linux-gnu-g++-9
export WITH_HOST="--host=${GCC_ARCH}-linux-gnu"
else
export APT_ARCH_SUFFIX=""
export WITH_HOST=""
GCC_ARCH="$(uname -m)"
export GCC_ARCH
fi
55 changes: 55 additions & 0 deletions docker/extract_native.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env bash

set -e

if [[ -z "$1" || -z "$2" ]]
then
echo "Missing mandatory arguments: path_shared_library, path_where_to_copy"
exit 1
fi

path_shared_library=$1
copy_path=$2
path_to_json="/tmp/topo_sorted.json"

RUST_LOG=info /opt/lddtopo-rs/target/release/lddtopo-rs --shared-library-path $path_shared_library --output-file $path_to_json

# Skipping libmfhdfalt due to /tmp/xxxx.7669203887046987097/libmfhdfalt_5076252650710112250.so: undefined symbol: error_top
# Skip libproj.so.15
modules_to_ignore=("ld-linux-x86-64" "libc.so" "libm.so" "libpthread" "libstdc" "libmfhdfalt" "libproj.so.15")
os_name="linux"
arch_type="x86-64"

dest_folder="$copy_path/native/${os_name}-${arch_type}"
mkdir -p $dest_folder

path_native_modules_to_load="${copy_path}/native/${os_name}-${arch_type}.txt"
rm -rf "$path_native_modules_to_load"

for OUTPUT in $(jq -r '.topo_sorted_libs[] | .name + ":" + .path' $path_to_json)
do
lib=$(echo $OUTPUT | cut -d ":" -f 1)
found=false
for i in "${modules_to_ignore[@]}"; do
if grep -q "$i" <<< "$lib"; then
#echo "Found $i in $lib, ignoring...";
found=true;
break;
fi
done

if $found; then
continue;
fi

path=$(echo $OUTPUT | cut -d ":" -f 2)
dest_path="${dest_folder}/$lib"
#echo $dest_path

cp $path $dest_path
echo "Copied $lib to $dest_path"

# Write native module to the list of modules
echo $lib >> $path_native_modules_to_load
done

Loading

0 comments on commit eceff81

Please sign in to comment.