From 9f573603a3a4c6479003c84b28296d668165fc81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 09:55:42 +0200 Subject: [PATCH 01/15] moar CI --- .../actions/manylinux_2014_setup/action.yml | 111 +++++++ .github/actions/ubuntu_18_setup/action.yml | 100 ++++++ .github/workflows/Java.yml | 308 ++++++++++++++++++ 3 files changed, 519 insertions(+) create mode 100644 .github/actions/manylinux_2014_setup/action.yml create mode 100644 .github/actions/ubuntu_18_setup/action.yml create mode 100644 .github/workflows/Java.yml diff --git a/.github/actions/manylinux_2014_setup/action.yml b/.github/actions/manylinux_2014_setup/action.yml new file mode 100644 index 00000000..8f524e61 --- /dev/null +++ b/.github/actions/manylinux_2014_setup/action.yml @@ -0,0 +1,111 @@ +name: "Setup manylinux2014 image" +description: "Installs/configures additional CI dependencies" +inputs: + aws-cli: + description: 'Setup aws-cli' + default: 0 + ninja-build: + description: 'Setup ninja-build' + default: 0 + vcpkg: + description: 'Setup vcpkg (installs to $GITHUB_WORKSPACE/vcpkg)' + default: 0 + openssl: + description: 'Setup OpenSSL (requires vcpkg to also be installed)' + default: 0 + ccache: + description: 'Setup Ccache' + default: 0 + jdk: + description: 'Setup JDK' + default: 0 + odbc: + description: 'Setup ODBC' + default: 0 + ssh: + description: 'Setup SSH' + default: 0 + glibc32: + description: 'Setup 32bit glibc' + default: 0 + nodejs: + description: 'Setup NodeJS' + default: 0 + gcc_4_8: + description: 'Setup GCC 4.8 (installs to /usr/bin/g++, default will still be GCC 10)' + default: 0 + python_alias: + description: 'Create an alias for python3 to python3.9' + default: 0 + +runs: + using: "composite" + steps: + - name: Setup general dependencies + shell: bash + run: scripts/setup_manylinux2014.sh general + + - name: Install AWS CLI + if: ${{ inputs.aws-cli == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh aws-cli + + - name: Setup dependencies for ODBC + if: ${{ inputs.odbc == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh odbc + + - name: Setup dependencies for ccache + if: ${{ inputs.ccache == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh ccache + + - name: Setup JDK + if: ${{ inputs.jdk == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh jdk + + - name: Setup SSH + if: ${{ inputs.ssh == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh ssh + + - name: Setup NodeJS + if: ${{ inputs.nodejs == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh nodejs + + - name: Setup 32bit compiler + if: ${{ inputs.glibc32 == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh glibc32 + + - name: Setup python3 as python3.9 + if: ${{ inputs.python_alias == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh python_alias + + - name: Setup old (GCC 4.8) compiler + if: ${{ inputs.gcc_4_8 == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh gcc_4_8 + + # Note instead of using scripts/setup_manylinux2014.sh vcpkg, we prefer to use + # lukka/run-vcpkg@v11.1 here as it configures vcpkg to cache to GH actions. + - name: Setup vcpkg + if: ${{ inputs.vcpkg == 1 }} + uses: lukka/run-vcpkg@v11.1 + with: + vcpkgGitCommitId: a1a1cbc975abf909a6c8985a6a2b8fe20bbd9bd6 + + - name: Install OpenSSL + if: ${{ inputs.openssl == 1 }} + shell: bash + run: scripts/setup_manylinux2014.sh openssl + + - name: Setup Ccache + if: ${{ inputs.ccache == 1 }} + uses: hendrikmuhs/ccache-action@v1.2.11 # Note: pinned due to GLIBC incompatibility in later releases + with: + key: ${{ github.job }} + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} \ No newline at end of file diff --git a/.github/actions/ubuntu_18_setup/action.yml b/.github/actions/ubuntu_18_setup/action.yml new file mode 100644 index 00000000..d8938ab1 --- /dev/null +++ b/.github/actions/ubuntu_18_setup/action.yml @@ -0,0 +1,100 @@ +name: "Setup Ubuntu 18" +description: "Setup an Ubuntu 18 docker container with the required libraries" +inputs: + openssl: + description: 'OpenSSL' + default: 0 + python: + description: 'Python' + default: 1 + aarch64_cross_compile: + description: 'Install dependencies for aarch64 cross-compiling' + default: 0 + vcpkg: + description: 'Install vcpkg' + default: 0 + ccache: + description: 'Install ccache' + default: 0 + +runs: + using: "composite" + steps: + - name: Install + shell: bash + run: | + apt-get update -y -qq + apt-get install -y -qq software-properties-common + add-apt-repository ppa:git-core/ppa + apt-get update -y -qq + apt-get install -y -qq ninja-build make gcc-multilib g++-multilib libssl-dev wget openjdk-8-jdk zip maven unixodbc-dev libc6-dev-i386 lib32readline6-dev libssl-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip build-essential checkinstall libffi-dev curl libz-dev openssh-client pkg-config + + - name: Install + shell: bash + if: ${{ inputs.aarch64_cross_compile == 1 }} + run: | + apt-get install -y -qq gcc-aarch64-linux-gnu g++-aarch64-linux-gnu + + - name: Install Git 2.18.5 + shell: bash + run: | + wget https://github.com/git/git/archive/refs/tags/v2.18.5.tar.gz + tar xvf v2.18.5.tar.gz + cd git-2.18.5 + make + make prefix=/usr install + git --version + + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Install CMake 3.21 + shell: bash + run: | + wget https://github.com/Kitware/CMake/releases/download/v3.21.3/cmake-3.21.3-linux-x86_64.sh + chmod +x cmake-3.21.3-linux-x86_64.sh + ./cmake-3.21.3-linux-x86_64.sh --skip-license --prefix=/usr/local + cmake --version + + - name: Install Python 3.8 + if: ${{ inputs.python }} == 1 + shell: bash + run: | + wget https://www.python.org/ftp/python/3.8.17/Python-3.8.17.tgz + tar xvf Python-3.8.17.tgz + cd Python-3.8.17 + mkdir -p pythonbin + ./configure --with-ensurepip=install + make -j + make install + python3.8 --version + python3.8 -m pip install pip + python3.8 -m pip install requests awscli + + - name: Version Check + shell: bash + run: | + ldd --version ldd + python3 --version + git --version + git log -1 --format=%h + + - name: Setup vcpkg + if: ${{ inputs.vcpkg == 1 }} + uses: lukka/run-vcpkg@v11.1 + with: + vcpkgGitCommitId: a1a1cbc975abf909a6c8985a6a2b8fe20bbd9bd6 + + - name: Setup Ccache + if: ${{ inputs.ccache == 1 }} + uses: hendrikmuhs/ccache-action@v1.2.11 # Note: pinned due to GLIBC incompatibility in later releases + with: + key: ${{ github.job }} + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} + + - name: Instal OpenSSL through vcpkg + if: ${{ inputs.openssl == 1 }} + shell: bash + run: | + cd $VCPKG_ROOT && ./vcpkg install openssl --triplet=${{ inputs.aarch64_cross_compile == 1 && 'arm64-linux' || 'x64-linux' }} \ No newline at end of file diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml new file mode 100644 index 00000000..973515e0 --- /dev/null +++ b/.github/workflows/Java.yml @@ -0,0 +1,308 @@ +name: Java JDBC +on: + push: + pull_request: + workflow_dispatch: + repository_dispatch: + +env: + GH_TOKEN: ${{ secrets.GH_TOKEN }} + OVERRIDE_GIT_DESCRIBE: ${{ inputs.override_git_describe }} + +jobs: + java-linux-amd64: + name: Java Linux (amd64) + runs-on: ubuntu-latest + container: + image: quay.io/pypa/manylinux2014_x86_64 + env: + GEN: ninja + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + + - uses: ./.github/actions/manylinux_2014_setup + with: + ninja-build: 1 + ccache: 1 + jdk: 1 + python_alias: 1 + aws-cli: 1 + + - name: Build + shell: bash + run: make build + + - name: Java Tests + shell: bash + if: ${{ inputs.skip_tests != 'true' }} + run: make test + + - name: Deploy + shell: bash + env: + AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + run: | + cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-amd64.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-amd64.jar + - uses: actions/upload-artifact@v3 + with: + name: java-linux-amd64 + path: | + build/release/duckdb_jdbc.jar + + java-linux-aarch64: + name: Java Linux (aarch64) + runs-on: ubuntu-latest + container: + image: quay.io/pypa/manylinux2014_arm64 + needs: java-linux-amd64 + env: + GEN: ninja + DUCKDB_PLATFORM: linux_arm64 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + + - uses: ./.github/actions/ubuntu_18_setup + with: + ccache: 1 + aarch64_cross_compile: 1 + + - name: Install Stuff + shell: bash + run: > + curl -L https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u345-b01/OpenJDK8U-jdk_x64_linux_hotspot_8u345b01.tar.gz | tar xvz + + - name: Build + shell: bash + run: CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ make build + + - name: Deploy + shell: bash + env: + AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + run: | + cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-aarch64.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-aarch64.jar + + - uses: actions/upload-artifact@v3 + with: + name: java-linux-aarch64 + path: | + build/release/duckdb_jdbc.jar + + + java-windows-amd64: + name: Java Windows (arm64) + runs-on: windows-latest + needs: java-linux-amd64 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Setup Ccache + uses: hendrikmuhs/ccache-action@main + with: + key: ${{ github.job }} + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} + + - name: Build + shell: bash + run: > + python scripts/windows_ci.py + + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_GENERATOR_PLATFORM=x64 -DJDBC_DRIVER=1 -DBUILD_EXTENSIONS=json -DENABLE_EXTENSION_AUTOLOADING=1 -DENABLE_EXTENSION_AUTOINSTALL=1 -DBUILD_SHELL=0 -DOVERRIDE_GIT_DESCRIBE="$OVERRIDE_GIT_DESCRIBE" + + cmake --build . --config Release + - name: Java Tests + if: ${{ inputs.skip_tests != 'true' }} + shell: bash + working-directory: tools/jdbc + run: make test_release + - name: Deploy + shell: bash + env: + AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + run: | + cp tools/jdbc/duckdb_jdbc.jar duckdb_jdbc-windows-amd64.jar + ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar + - uses: actions/upload-artifact@v3 + with: + name: java-windows-amd64 + path: | + tools/jdbc/duckdb_jdbc.jar + + + java-osx-universal: + name: Java OSX (Universal) + runs-on: macos-14 + needs: java-linux-amd64 + env: + BUILD_JDBC: 1 + BUILD_JSON: 1 + OSX_BUILD_UNIVERSAL: 1 + ENABLE_EXTENSION_AUTOLOADING: 1 + ENABLE_EXTENSION_AUTOINSTALL: 1 + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Setup Ccache + uses: hendrikmuhs/ccache-action@main + with: + key: ${{ github.job }} + save: ${{ github.ref == 'refs/heads/main' }} + - name: Build + shell: bash + run: make + - name: Java Tests + if: ${{ inputs.skip_tests != 'true' }} + shell: bash + run: make test_release + - name: Java Example + shell: bash + run: | + (cd examples/jdbc; make; make maven) + - name: Deploy + shell: bash + env: + AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} + run: | + cp build/release/duckdb_jdbc.jar duckdb_jdbc-osx-universal.jar + ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar + - uses: actions/upload-artifact@v3 + with: + name: java-osx-universal + path: | + build/release/duckdb_jdbc.jar + + + java-combine: + if: ${{ inputs.override_git_describe == '' }} + name: Java Combine + runs-on: ubuntu-latest + needs: + - java-linux-aarch64 + - java-linux-amd64 + - java-windows-amd64 + - java-osx-universal + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + + - shell: bash + run: mkdir jdbc-artifacts + + - uses: actions/download-artifact@v3 + with: + name: java-linux-aarch64 + path: jdbc-artifacts/java-linux-aarch64 + + - uses: actions/download-artifact@v3 + with: + name: java-linux-amd64 + path: jdbc-artifacts/java-linux-amd64 + + - uses: actions/download-artifact@v3 + with: + name: java-windows-amd64 + path: jdbc-artifacts/java-windows-amd64 + + - uses: actions/download-artifact@v3 + with: + name: java-osx-universal + path: jdbc-artifacts/java-osx-universal + + - name: Combine JARs + shell: bash + run: | + if [[ "$GITHUB_REF" =~ ^(refs/heads/main|refs/tags/v.+)$ && "$GITHUB_REPOSITORY" = "duckdb/duckdb" ]] ; then + export XML=' + + + + ossrh + hfmuehleisen + PASSWORD + + + ' + mkdir ~/.m2 + echo $XML | sed "s/PASSWORD/${{ secrets.MAVEN_PASSWORD }}/" > ~/.m2/settings.xml + echo "${{ secrets.MAVEN_PGP_PK }}" | base64 -d > maven_pgp_key + gpg --import maven_pgp_key + python scripts/jdbc_maven_deploy.py ${{ github.ref_name }} jdbc-artifacts . + fi + ls -lahR jdbc-artifacts + + - uses: actions/upload-artifact@v3 + with: + name: java-jars + path: | + jdbc-artifacts + + jdbc-compliance: + name: JDBC Compliance + runs-on: ubuntu-20.04 + if: ${{ inputs.skip_tests != 'true' }} + needs: java-linux-amd64 + container: quay.io/pypa/manylinux2014_x86_64 + env: + BUILD_JDBC: 1 + GEN: ninja + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + ref: ${{ inputs.git_ref }} + + - uses: ./.github/actions/manylinux_2014_setup + with: + ninja-build: 1 + ccache: 1 + jdk: 1 + python_alias: 1 + aws-cli: 1 + + - name: Install + shell: bash + run: | + git clone https://github.com/cwida/jdbccts.git + + - name: Setup Ccache + uses: hendrikmuhs/ccache-action@v1.2.11 # Note: pinned due to GLIBC incompatibility in later releases + with: + key: ${{ github.job }} + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} + + - name: Build + shell: bash + run: make release + + - name: Test + shell: bash + run: (cd jdbccts && make DUCKDB_JAR=../build/release/duckdb_jdbc.jar test) From f9b28ddd9f8ab90ac989ff420a1a98a47fbc02e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 09:57:47 +0200 Subject: [PATCH 02/15] moo --- .gitignore | 1 + scripts/setup_manylinux2014.sh | 84 ++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 .gitignore create mode 100755 scripts/setup_manylinux2014.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c795b054 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/scripts/setup_manylinux2014.sh b/scripts/setup_manylinux2014.sh new file mode 100755 index 00000000..8e9a7d70 --- /dev/null +++ b/scripts/setup_manylinux2014.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +# This script is used to setup the additional dependencies required by duckdb +# for the manylinux2014 image. The reason for this to exist in a script is firstly to be able to +# easily reproduce the same environment locally. Secondly, these steps can be now used +# both in the x86 jobs as the aarch64 jobs on GH actions (aarch64 jobs need a special env). + +# Examples +# +### To install just basics: +# +# > scripts/setup_manylinux2014.sh general +# +### Install openssl (through vcpkg, which will be in /tmp/vcpkg), ccache and jdk +# +# > VCPKG_TARGET_DIR=/tmp scripts/setup_manylinux2014.sh general vcpkg openssl ccache jdk +# + +# Installs deps for a specific required dependency +install_deps() { + if [ "$1" = "general" ]; then + git config --global --add safe.directory '*' + yum install -y curl zip unzip tar + yum install -y ninja-build + + elif [ "$1" = "aws-cli" ]; then + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + ./aws/install + aws --version + + elif [ "$1" = "odbc" ]; then + yum install -y unixODBC-devel + + elif [ "$1" = "vcpkg" ]; then + # Note: it is preferred to use the lukka/run-vcpkg@v11 over this when running this + # in a Github Actions job. When running locally or in the aarch64, these can be used instead + # Also note that this action install. + # Note2: this installs vcpkg to $VCPKG_TARGET_DIR + ( + cd $VCPKG_TARGET_DIR ; + git clone https://github.com/Microsoft/vcpkg.git ; + git checkout a1a1cbc975abf909a6c8985a6a2b8fe20bbd9bd6 ; + cd vcpkg ; + ./bootstrap-vcpkg.sh + ) + export VCPKG_ROOT=$VCPKG_TARGET_DIR/vcpkg + + elif [ "$1" = "openssl" ]; then + yum install -y perl-IPC-Cmd + + elif [ "$1" = "ccache" ]; then + yum -y install ccache + + elif [ "$1" = "python_alias" ]; then + ln -fs /usr/local/bin/python3.9 /usr/local/bin/python3 + + elif [ "$1" = "jdk" ]; then + yum install -y java-11-openjdk-devel maven + + elif [ "$1" = "ssh" ]; then + yum install -y openssh-clients + + elif [ "$1" = "glibc32" ]; then + yum install -y libgcc*i686 libstdc++*i686 glibc*i686 libgfortran*i686 + + elif [ "$1" = "gcc_4_8" ]; then + yum install -y gcc-c++ + + elif [ "$1" = "nodejs" ]; then + yum install -y nodejs + + else + >&2 echo "unknown input for setup_manylinux2014.sh: '$1'" + exit $exit_code + fi +} + +for var in "$@" +do + install_deps $var +done + + From ae3c06568418098268041527c65da8391cb540ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 14:38:56 +0200 Subject: [PATCH 03/15] arch --- .gitignore | 4 +++- CMakeLists.txt | 29 ++++++++++++++++++++++++----- CMakeLists.txt.in | 29 ++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index c795b054..28bb9dc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -build \ No newline at end of file +build +.idea +cmake-build-debug \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 06a0da2b..6779e7e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,13 +37,32 @@ add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${D target_compile_options(duckdb_java PRIVATE -fexceptions) target_link_libraries(duckdb_java duckdb-native ) + + +set(OS_NAME "unknown") +set(OS_ARCH "amd64") + +string(REGEX MATCH "(arm64|aarch64)" IS_ARM "${CMAKE_SYSTEM_PROCESSOR}") +if(IS_ARM) + set(OS_ARCH "arm64") +elseif(FORCE_32_BIT) + set(OS_ARCH "i386") +endif() + if(APPLE) - set(OS_NAME osx) - set(OS_ARCH universal) + set(OS_NAME "osx") endif() -#if(OVERRIDE_JDBC_OS_ARCH) -# set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) -#endif() +if(WIN32) + set(OS_NAME "windows") +endif() +if(UNIX AND NOT APPLE) + set(OS_NAME "linux") # sorry BSD +endif() + +if(OVERRIDE_JDBC_OS_ARCH) + set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) +endif() + string(JOIN "_" LIB_SUFFIX ".so" ${OS_NAME} ${OS_ARCH}) set_target_properties(duckdb_java PROPERTIES SUFFIX ${LIB_SUFFIX}) set_target_properties(duckdb_java PROPERTIES PREFIX "lib") diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index 01fbb0a8..ae2f58a6 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -37,13 +37,32 @@ add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${D target_compile_options(duckdb_java PRIVATE -fexceptions) target_link_libraries(duckdb_java duckdb-native ${LIBRARY_FILES}) + + +set(OS_NAME "unknown") +set(OS_ARCH "amd64") + +string(REGEX MATCH "(arm64|aarch64)" IS_ARM "${CMAKE_SYSTEM_PROCESSOR}") +if(IS_ARM) + set(OS_ARCH "arm64") +elseif(FORCE_32_BIT) + set(OS_ARCH "i386") +endif() + if(APPLE) - set(OS_NAME osx) - set(OS_ARCH universal) + set(OS_NAME "osx") endif() -#if(OVERRIDE_JDBC_OS_ARCH) -# set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) -#endif() +if(WIN32) + set(OS_NAME "windows") +endif() +if(UNIX AND NOT APPLE) + set(OS_NAME "linux") # sorry BSD +endif() + +if(OVERRIDE_JDBC_OS_ARCH) + set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) +endif() + string(JOIN "_" LIB_SUFFIX ".so" ${OS_NAME} ${OS_ARCH}) set_target_properties(duckdb_java PROPERTIES SUFFIX ${LIB_SUFFIX}) set_target_properties(duckdb_java PROPERTIES PREFIX "lib") From 6d29953ee3ad88c4bd2693d40e389392d914a86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 14:58:34 +0200 Subject: [PATCH 04/15] missing parquet test file --- CMakeLists.txt | 1 + CMakeLists.txt.in | 1 + data/parquet-testing/userdata1.parquet | Bin 0 -> 113629 bytes 3 files changed, 2 insertions(+) create mode 100644 data/parquet-testing/userdata1.parquet diff --git a/CMakeLists.txt b/CMakeLists.txt index 6779e7e1..216e462d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,7 @@ endif() if(APPLE) set(OS_NAME "osx") + set(OS_ARCH "universal") endif() if(WIN32) set(OS_NAME "windows") diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index ae2f58a6..a0807268 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -51,6 +51,7 @@ endif() if(APPLE) set(OS_NAME "osx") + set(OS_ARCH "universal") endif() if(WIN32) set(OS_NAME "windows") diff --git a/data/parquet-testing/userdata1.parquet b/data/parquet-testing/userdata1.parquet new file mode 100644 index 0000000000000000000000000000000000000000..2ae23dac0ffe794068f26c163b7245b3509f31c5 GIT binary patch literal 113629 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 DbfIxZ literal 0 HcmV?d00001 From 5b96019e25ac5642d2cd5b7b9dc3c09c6847632e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 15:02:34 +0200 Subject: [PATCH 05/15] moar tests --- .github/workflows/Java.yml | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index 973515e0..a7483aff 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -59,7 +59,7 @@ jobs: runs-on: ubuntu-latest container: image: quay.io/pypa/manylinux2014_arm64 - needs: java-linux-amd64 + # needs: java-linux-amd64 env: GEN: ninja DUCKDB_PLATFORM: linux_arm64 @@ -102,7 +102,7 @@ jobs: java-windows-amd64: name: Java Windows (arm64) runs-on: windows-latest - needs: java-linux-amd64 +# needs: java-linux-amd64 steps: - uses: actions/checkout@v3 with: @@ -119,17 +119,12 @@ jobs: - name: Build shell: bash - run: > - python scripts/windows_ci.py - - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_GENERATOR_PLATFORM=x64 -DJDBC_DRIVER=1 -DBUILD_EXTENSIONS=json -DENABLE_EXTENSION_AUTOLOADING=1 -DENABLE_EXTENSION_AUTOINSTALL=1 -DBUILD_SHELL=0 -DOVERRIDE_GIT_DESCRIBE="$OVERRIDE_GIT_DESCRIBE" - - cmake --build . --config Release + run: make build - name: Java Tests if: ${{ inputs.skip_tests != 'true' }} shell: bash working-directory: tools/jdbc - run: make test_release + run: make test - name: Deploy shell: bash env: @@ -148,13 +143,7 @@ jobs: java-osx-universal: name: Java OSX (Universal) runs-on: macos-14 - needs: java-linux-amd64 - env: - BUILD_JDBC: 1 - BUILD_JSON: 1 - OSX_BUILD_UNIVERSAL: 1 - ENABLE_EXTENSION_AUTOLOADING: 1 - ENABLE_EXTENSION_AUTOINSTALL: 1 +# needs: java-linux-amd64 steps: - uses: actions/checkout@v3 with: @@ -170,15 +159,11 @@ jobs: save: ${{ github.ref == 'refs/heads/main' }} - name: Build shell: bash - run: make + run: make build - name: Java Tests if: ${{ inputs.skip_tests != 'true' }} shell: bash - run: make test_release - - name: Java Example - shell: bash - run: | - (cd examples/jdbc; make; make maven) + run: make test - name: Deploy shell: bash env: @@ -268,7 +253,7 @@ jobs: name: JDBC Compliance runs-on: ubuntu-20.04 if: ${{ inputs.skip_tests != 'true' }} - needs: java-linux-amd64 + # needs: java-linux-amd64 container: quay.io/pypa/manylinux2014_x86_64 env: BUILD_JDBC: 1 From b2c98f54632653c39af52cb91eeaa3752bfa8593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 15:06:07 +0200 Subject: [PATCH 06/15] make release fine --- .github/workflows/Java.yml | 10 +++++----- Makefile | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index a7483aff..e3223c1e 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -33,7 +33,7 @@ jobs: - name: Build shell: bash - run: make build + run: make release - name: Java Tests shell: bash @@ -58,7 +58,7 @@ jobs: name: Java Linux (aarch64) runs-on: ubuntu-latest container: - image: quay.io/pypa/manylinux2014_arm64 + image: ubuntu:18.04 # needs: java-linux-amd64 env: GEN: ninja @@ -81,7 +81,7 @@ jobs: - name: Build shell: bash - run: CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ make build + run: CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ make release - name: Deploy shell: bash @@ -119,7 +119,7 @@ jobs: - name: Build shell: bash - run: make build + run: make release - name: Java Tests if: ${{ inputs.skip_tests != 'true' }} shell: bash @@ -159,7 +159,7 @@ jobs: save: ${{ github.ref == 'refs/heads/main' }} - name: Build shell: bash - run: make build + run: make release - name: Java Tests if: ${{ inputs.skip_tests != 'true' }} shell: bash diff --git a/Makefile b/Makefile index ca11f93a..c743cf0a 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ CP=$(JAR)$(SEP)$(TEST_JAR) test: java -cp $(CP) org.duckdb.TestDuckDBJDBC -build: +release: mkdir -p build/release cd build/release && cmake $(GENERATOR) ../.. && cmake --build . From 8444c87f531260c8770dee0296aec8b56573c968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 15:11:27 +0200 Subject: [PATCH 07/15] bigobj --- CMakeLists.txt | 5 ++++- CMakeLists.txt.in | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 216e462d..a855d4c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,11 +28,14 @@ set(DUCKDB_SRC_FILES src/duckdb/ub_src_catalog.cpp src/duckdb/ub_src_catalog_cat set(CMAKE_JAVA_COMPILE_FLAGS -source 1.8 -target 1.8 -encoding utf-8) +if(MSVC) + add_definitions(/bigobj) +endif() + add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver GENERATE_NATIVE_HEADERS duckdb-native) add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) - add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) target_compile_options(duckdb_java PRIVATE -fexceptions) target_link_libraries(duckdb_java duckdb-native ) diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index a0807268..fcb95c1a 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -28,11 +28,14 @@ set(DUCKDB_SRC_FILES ${SOURCE_FILES}) set(CMAKE_JAVA_COMPILE_FLAGS -source 1.8 -target 1.8 -encoding utf-8) +if(MSVC) + add_definitions(/bigobj) +endif() + add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver GENERATE_NATIVE_HEADERS duckdb-native) add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) - add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) target_compile_options(duckdb_java PRIVATE -fexceptions) target_link_libraries(duckdb_java duckdb-native ${LIBRARY_FILES}) From cdc8e6f7da66b98afebbc3c59d4d4f53ae9c70f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 15:16:29 +0200 Subject: [PATCH 08/15] flags --- .github/workflows/Java.yml | 4 ++-- CMakeLists.txt | 4 ++++ CMakeLists.txt.in | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index e3223c1e..c0da752d 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -132,7 +132,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} run: | cp tools/jdbc/duckdb_jdbc.jar duckdb_jdbc-windows-amd64.jar - ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar - uses: actions/upload-artifact@v3 with: name: java-windows-amd64 @@ -171,7 +171,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} run: | cp build/release/duckdb_jdbc.jar duckdb_jdbc-osx-universal.jar - ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar + # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar - uses: actions/upload-artifact@v3 with: name: java-osx-universal diff --git a/CMakeLists.txt b/CMakeLists.txt index a855d4c0..9722ef66 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,8 +30,12 @@ set(CMAKE_JAVA_COMPILE_FLAGS -source 1.8 -target 1.8 -encoding utf-8) if(MSVC) add_definitions(/bigobj) +else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG ") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") endif() + add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver GENERATE_NATIVE_HEADERS duckdb-native) add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index fcb95c1a..3e2db8c0 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -30,8 +30,12 @@ set(CMAKE_JAVA_COMPILE_FLAGS -source 1.8 -target 1.8 -encoding utf-8) if(MSVC) add_definitions(/bigobj) +else() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG ") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") endif() + add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver GENERATE_NATIVE_HEADERS duckdb-native) add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) From 43025c3794a2a3106cfd074d6c61f04332e389ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 15:26:34 +0200 Subject: [PATCH 09/15] release build ay --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c743cf0a..8b68d9d9 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ test: release: mkdir -p build/release - cd build/release && cmake $(GENERATOR) ../.. && cmake --build . + cd build/release && cmake -DCMAKE_BUILD_TYPE=Release $(GENERATOR) ../.. && cmake --build . --config Release clean: rm -rf build \ No newline at end of file From f45dd3ea9f2365d4f83c073d9bb3bebed2fb953e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 15:40:27 +0200 Subject: [PATCH 10/15] add check for universal-ness --- .github/workflows/Java.yml | 3 +++ CMakeLists.txt | 23 +++++++++++++---------- CMakeLists.txt.in | 24 ++++++++++++------------ 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index c0da752d..7aa23a7a 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -164,6 +164,9 @@ jobs: if: ${{ inputs.skip_tests != 'true' }} shell: bash run: make test + - name: See if this actually universal + shell: bash + run: lipo -archs build/release/libduckdb_java.so_osx_universal | grep "x86_64 arm64" - name: Deploy shell: bash env: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9722ef66..e645ffc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,8 @@ set(DUCKDB_SRC_FILES src/duckdb/ub_src_catalog.cpp src/duckdb/ub_src_catalog_cat set(CMAKE_JAVA_COMPILE_FLAGS -source 1.8 -target 1.8 -encoding utf-8) +add_definitions(-DDUCKDB_BUILD_LIBRARY) + if(MSVC) add_definitions(/bigobj) else() @@ -36,16 +38,6 @@ else() endif() -add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver - GENERATE_NATIVE_HEADERS duckdb-native) -add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) - -add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) -target_compile_options(duckdb_java PRIVATE -fexceptions) -target_link_libraries(duckdb_java duckdb-native ) - - - set(OS_NAME "unknown") set(OS_ARCH "amd64") @@ -59,6 +51,7 @@ endif() if(APPLE) set(OS_NAME "osx") set(OS_ARCH "universal") + SET(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X" FORCE) endif() if(WIN32) set(OS_NAME "windows") @@ -71,6 +64,16 @@ if(OVERRIDE_JDBC_OS_ARCH) set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) endif() + +add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver + GENERATE_NATIVE_HEADERS duckdb-native) +add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) + +add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) +target_compile_options(duckdb_java PRIVATE -fexceptions) +target_link_libraries(duckdb_java duckdb-native ) + + string(JOIN "_" LIB_SUFFIX ".so" ${OS_NAME} ${OS_ARCH}) set_target_properties(duckdb_java PROPERTIES SUFFIX ${LIB_SUFFIX}) set_target_properties(duckdb_java PROPERTIES PREFIX "lib") diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index 3e2db8c0..6244f626 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -28,6 +28,8 @@ set(DUCKDB_SRC_FILES ${SOURCE_FILES}) set(CMAKE_JAVA_COMPILE_FLAGS -source 1.8 -target 1.8 -encoding utf-8) +add_definitions(-DDUCKDB_BUILD_LIBRARY) + if(MSVC) add_definitions(/bigobj) else() @@ -36,16 +38,6 @@ else() endif() -add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver - GENERATE_NATIVE_HEADERS duckdb-native) -add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) - -add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) -target_compile_options(duckdb_java PRIVATE -fexceptions) -target_link_libraries(duckdb_java duckdb-native ${LIBRARY_FILES}) - - - set(OS_NAME "unknown") set(OS_ARCH "amd64") @@ -58,7 +50,8 @@ endif() if(APPLE) set(OS_NAME "osx") - set(OS_ARCH "universal") + set(OS_ARCH "universal") + SET(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X" FORCE) endif() if(WIN32) set(OS_NAME "windows") @@ -71,11 +64,18 @@ if(OVERRIDE_JDBC_OS_ARCH) set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) endif() +add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver + GENERATE_NATIVE_HEADERS duckdb-native) +add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) + +add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) +target_compile_options(duckdb_java PRIVATE -fexceptions) +target_link_libraries(duckdb_java duckdb-native ${LIBRARY_FILES}) + string(JOIN "_" LIB_SUFFIX ".so" ${OS_NAME} ${OS_ARCH}) set_target_properties(duckdb_java PROPERTIES SUFFIX ${LIB_SUFFIX}) set_target_properties(duckdb_java PROPERTIES PREFIX "lib") - add_custom_command( OUTPUT dummy_jdbc_target DEPENDS duckdb_java duckdb_jdbc duckdb_jdbc_tests From 4cd94bb24b6437a4846a8293cea7803e18dbab38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 16:07:23 +0200 Subject: [PATCH 11/15] linking libs on windows --- CMakeLists.txt | 16 +++++++++++----- CMakeLists.txt.in | 9 +++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e645ffc5..eeae51a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,8 +50,8 @@ endif() if(APPLE) set(OS_NAME "osx") - set(OS_ARCH "universal") - SET(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X" FORCE) + set(OS_ARCH "universal") + SET(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE STRING "Build architectures for Mac OS X" FORCE) endif() if(WIN32) set(OS_NAME "windows") @@ -64,21 +64,27 @@ if(OVERRIDE_JDBC_OS_ARCH) set(OS_ARCH ${OVERRIDE_JDBC_OS_ARCH}) endif() - add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver GENERATE_NATIVE_HEADERS duckdb-native) add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) + + +set(DUCKDB_SYSTEM_LIBS ${CMAKE_DL_LIBS}) + +if(MSVC) + set(DUCKDB_SYSTEM_LIBS ${DUCKDB_SYSTEM_LIBS} ws2_32 rstrtmgr bcrypt) +endif() + add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) target_compile_options(duckdb_java PRIVATE -fexceptions) target_link_libraries(duckdb_java duckdb-native ) - +target_link_libraries(duckdb_java ${DUCKDB_SYSTEM_LIBS}) string(JOIN "_" LIB_SUFFIX ".so" ${OS_NAME} ${OS_ARCH}) set_target_properties(duckdb_java PROPERTIES SUFFIX ${LIB_SUFFIX}) set_target_properties(duckdb_java PROPERTIES PREFIX "lib") - add_custom_command( OUTPUT dummy_jdbc_target DEPENDS duckdb_java duckdb_jdbc duckdb_jdbc_tests diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in index 6244f626..8ebf1101 100644 --- a/CMakeLists.txt.in +++ b/CMakeLists.txt.in @@ -68,9 +68,18 @@ add_jar(duckdb_jdbc ${JAVA_SRC_FILES} META-INF/services/java.sql.Driver GENERATE_NATIVE_HEADERS duckdb-native) add_jar(duckdb_jdbc_tests ${JAVA_TEST_FILES} INCLUDE_JARS duckdb_jdbc) + + +set(DUCKDB_SYSTEM_LIBS ${CMAKE_DL_LIBS}) + +if(MSVC) + set(DUCKDB_SYSTEM_LIBS ${DUCKDB_SYSTEM_LIBS} ws2_32 rstrtmgr bcrypt) +endif() + add_library(duckdb_java SHARED src/jni/duckdb_java.cpp src/jni/functions.cpp ${DUCKDB_SRC_FILES}) target_compile_options(duckdb_java PRIVATE -fexceptions) target_link_libraries(duckdb_java duckdb-native ${LIBRARY_FILES}) +target_link_libraries(duckdb_java ${DUCKDB_SYSTEM_LIBS}) string(JOIN "_" LIB_SUFFIX ".so" ${OS_NAME} ${OS_ARCH}) set_target_properties(duckdb_java PROPERTIES SUFFIX ${LIB_SUFFIX}) From e22ed715659a983aff2f3dbcbe0c342a94e69e0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Mon, 29 Apr 2024 16:23:12 +0200 Subject: [PATCH 12/15] this is wrong --- .github/workflows/Java.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index 7aa23a7a..015aa7d4 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -123,7 +123,6 @@ jobs: - name: Java Tests if: ${{ inputs.skip_tests != 'true' }} shell: bash - working-directory: tools/jdbc run: make test - name: Deploy shell: bash From 7afa2b69db24600ba0b866fa7e4fa7538ba60f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Tue, 30 Apr 2024 09:12:44 +0200 Subject: [PATCH 13/15] correct arch for arm --- .github/workflows/Java.yml | 6 ++++-- Makefile | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index 015aa7d4..6a607e15 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -81,7 +81,7 @@ jobs: - name: Build shell: bash - run: CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ make release + run: CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ OVERRIDE_JDBC_OS_ARCH=arm64 make release - name: Deploy shell: bash @@ -123,7 +123,9 @@ jobs: - name: Java Tests if: ${{ inputs.skip_tests != 'true' }} shell: bash - run: make test + run: | + ls -R . + make test - name: Deploy shell: bash env: diff --git a/Makefile b/Makefile index 8b68d9d9..53581f89 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,17 @@ JARS= ifeq ($(OS),Windows_NT) # windows is weird SEP=";" - JARS=. + JARS=build/release else SEP=":" JARS=build/release endif +ARCH_OVERRIDE= +ifneq ($(OVERRIDE_JDBC_OS_ARCH),) + ARCH_OVERRIDE=-DOVERRIDE_JDBC_OS_ARCH=$(OVERRIDE_JDBC_OS_ARCH) +endif + GENERATOR= ifeq ($(GEN),ninja) @@ -28,7 +33,7 @@ test: release: mkdir -p build/release - cd build/release && cmake -DCMAKE_BUILD_TYPE=Release $(GENERATOR) ../.. && cmake --build . --config Release + cd build/release && cmake -DCMAKE_BUILD_TYPE=Release $(GENERATOR) $(ARCH_OVERRIDE) ../.. && cmake --build . --config Release clean: rm -rf build \ No newline at end of file From 44f5cb87f769c9c2848abdae9636f959466154ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Tue, 30 Apr 2024 09:35:27 +0200 Subject: [PATCH 14/15] staging --- .github/workflows/Java.yml | 10 ++--- scripts/upload-assets-to-staging.sh | 64 +++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 5 deletions(-) create mode 100755 scripts/upload-assets-to-staging.sh diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index 6a607e15..6869e217 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -47,7 +47,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} run: | cp build/release/duckdb_jdbc.jar duckdb_jdbc-linux-amd64.jar - # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-amd64.jar + ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-linux-amd64.jar - uses: actions/upload-artifact@v3 with: name: java-linux-amd64 @@ -132,13 +132,13 @@ jobs: AWS_ACCESS_KEY_ID: ${{ secrets.S3_DUCKDB_STAGING_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} run: | - cp tools/jdbc/duckdb_jdbc.jar duckdb_jdbc-windows-amd64.jar - # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar + cp build/release/duckdb_jdbc.jar duckdb_jdbc-windows-amd64.jar + ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-windows-amd64.jar - uses: actions/upload-artifact@v3 with: name: java-windows-amd64 path: | - tools/jdbc/duckdb_jdbc.jar + build/release/duckdb_jdbc.jar java-osx-universal: @@ -175,7 +175,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.S3_DUCKDB_STAGING_KEY }} run: | cp build/release/duckdb_jdbc.jar duckdb_jdbc-osx-universal.jar - # ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar + ./scripts/upload-assets-to-staging.sh github_release duckdb_jdbc-osx-universal.jar - uses: actions/upload-artifact@v3 with: name: java-osx-universal diff --git a/scripts/upload-assets-to-staging.sh b/scripts/upload-assets-to-staging.sh new file mode 100755 index 00000000..d2111d89 --- /dev/null +++ b/scripts/upload-assets-to-staging.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Main extension uploading script + +# Usage: ./scripts/upload-staging-asset.sh * +# : Folder to upload to +# : File to be uploaded + +if [ -z "$1" ] || [ -z "$2" ]; then + echo "Usage: ./scripts/upload-staging-asset.sh [... ]" + exit 1 +fi + +set -e + +# skip if repo is not in duckdb organization +if [ "$GITHUB_REPOSITORY_OWNER" != "duckdb" ]; then + echo "Repository is $GITHUB_REPOSITORY_OWNER (not duckdb)" + exit 0 +fi + +FOLDER="$1" +DRY_RUN_PARAM="" + +# dryrun if repo is not duckdb/duckdb +if [ "$GITHUB_REPOSITORY" != "duckdb/duckdb" ]; then + echo "Repository is $GITHUB_REPOSITORY (not duckdb/duckdb)" + DRY_RUN_PARAM="--dryrun" +fi +# dryrun if we are not in main +if [ "$GITHUB_REF" != "refs/heads/main" ]; then + echo "git ref is $GITHUB_REF (not refs/heads/main)" + DRY_RUN_PARAM="--dryrun" +fi + +if [ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]; then + echo "overriding DRY_RUN_PARAM, forcing upload" + DRY_RUN_PARAM="" +fi + +# dryrun if AWS key is not set +if [ -z "$AWS_ACCESS_KEY_ID" ]; then + echo "No access key available" + DRY_RUN_PARAM="--dryrun" +fi + + +TARGET=$(git log -1 --format=%h) + +if [ "$UPLOAD_ASSETS_TO_STAGING_TARGET" ]; then + TARGET="$UPLOAD_ASSETS_TO_STAGING_TARGET" +fi + +# decide target for staging +if [ "$OVERRIDE_GIT_DESCRIBE" ]; then + TARGET="$TARGET/$OVERRIDE_GIT_DESCRIBE" +fi + +python3 -m pip install awscli + +for var in "${@: 2}" +do + aws s3 cp $var s3://duckdb-staging/$TARGET/$GITHUB_REPOSITORY/$FOLDER/ $DRY_RUN_PARAM --region us-east-2 +done From e14d7b2f289d48cf41ff0b311ddba14a304d0695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20M=C3=BChleisen?= Date: Tue, 30 Apr 2024 09:56:10 +0200 Subject: [PATCH 15/15] should be it --- .../actions/manylinux_2014_setup/action.yml | 2 +- .github/actions/ubuntu_18_setup/action.yml | 2 +- .github/workflows/Java.yml | 14 +- scripts/jdbc_maven_deploy.py | 201 ++++++++++++++++++ scripts/upload-assets-to-staging.sh | 6 +- 5 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 scripts/jdbc_maven_deploy.py diff --git a/.github/actions/manylinux_2014_setup/action.yml b/.github/actions/manylinux_2014_setup/action.yml index 8f524e61..71bb3f0a 100644 --- a/.github/actions/manylinux_2014_setup/action.yml +++ b/.github/actions/manylinux_2014_setup/action.yml @@ -108,4 +108,4 @@ runs: uses: hendrikmuhs/ccache-action@v1.2.11 # Note: pinned due to GLIBC incompatibility in later releases with: key: ${{ github.job }} - save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} \ No newline at end of file + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb-java' }} \ No newline at end of file diff --git a/.github/actions/ubuntu_18_setup/action.yml b/.github/actions/ubuntu_18_setup/action.yml index d8938ab1..c01e8ce7 100644 --- a/.github/actions/ubuntu_18_setup/action.yml +++ b/.github/actions/ubuntu_18_setup/action.yml @@ -91,7 +91,7 @@ runs: uses: hendrikmuhs/ccache-action@v1.2.11 # Note: pinned due to GLIBC incompatibility in later releases with: key: ${{ github.job }} - save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb-java' }} - name: Instal OpenSSL through vcpkg if: ${{ inputs.openssl == 1 }} diff --git a/.github/workflows/Java.yml b/.github/workflows/Java.yml index 6869e217..65d33ac6 100644 --- a/.github/workflows/Java.yml +++ b/.github/workflows/Java.yml @@ -59,7 +59,7 @@ jobs: runs-on: ubuntu-latest container: image: ubuntu:18.04 - # needs: java-linux-amd64 + needs: java-linux-amd64 env: GEN: ninja DUCKDB_PLATFORM: linux_arm64 @@ -102,7 +102,7 @@ jobs: java-windows-amd64: name: Java Windows (arm64) runs-on: windows-latest -# needs: java-linux-amd64 + needs: java-linux-amd64 steps: - uses: actions/checkout@v3 with: @@ -115,7 +115,7 @@ jobs: uses: hendrikmuhs/ccache-action@main with: key: ${{ github.job }} - save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb' }} + save: ${{ github.ref == 'refs/heads/main' || github.repository != 'duckdb/duckdb-java' }} - name: Build shell: bash @@ -144,7 +144,7 @@ jobs: java-osx-universal: name: Java OSX (Universal) runs-on: macos-14 -# needs: java-linux-amd64 + needs: java-linux-amd64 steps: - uses: actions/checkout@v3 with: @@ -225,7 +225,7 @@ jobs: - name: Combine JARs shell: bash run: | - if [[ "$GITHUB_REF" =~ ^(refs/heads/main|refs/tags/v.+)$ && "$GITHUB_REPOSITORY" = "duckdb/duckdb" ]] ; then + if [[ "$GITHUB_REF" =~ ^(refs/heads/main|refs/tags/v.+)$ && "$GITHUB_REPOSITORY" = "duckdb/duckdb-java" ]] ; then export XML=' +# sub cv25519 2022-02-07 [E] + +import os +import pathlib +import shutil +import subprocess +import sys +import tempfile +import zipfile +import re + + +def exec(cmd): + print(cmd) + res = subprocess.run(cmd.split(' '), capture_output=True) + if res.returncode == 0: + return res.stdout + raise ValueError(res.stdout + res.stderr) + + +if len(sys.argv) < 4 or not os.path.isdir(sys.argv[2]) or not os.path.isdir(sys.argv[3]): + print("Usage: [release_tag, format: v1.2.3] [artifact_dir] [jdbc_root_path]") + exit(1) + +version_regex = re.compile(r'^v((\d+)\.(\d+)\.\d+)$') +release_tag = sys.argv[1] +deploy_url = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' +is_release = True + +if release_tag == 'main': + # for SNAPSHOT builds we increment the minor version and set patch level to zero. + # seemed the most sensible + last_tag = exec('git tag --sort=-committerdate').decode('utf8').split('\n')[0] + re_result = version_regex.search(last_tag) + if re_result is None: + raise ValueError("Could not parse last tag %s" % last_tag) + release_version = "%d.%d.0-SNAPSHOT" % (int(re_result.group(2)), int(re_result.group(3)) + 1) + # orssh uses a different deploy url for snapshots yay + deploy_url = 'https://oss.sonatype.org/content/repositories/snapshots/' + is_release = False +elif version_regex.match(release_tag): + release_version = version_regex.search(release_tag).group(1) +else: + print("Not running on %s" % release_tag) + exit(0) + +jdbc_artifact_dir = sys.argv[2] +jdbc_root_path = sys.argv[3] + +combine_builds = ['linux-amd64', 'osx-universal', 'windows-amd64', 'linux-aarch64'] + +staging_dir = tempfile.mkdtemp() + +binary_jar = '%s/duckdb_jdbc-%s.jar' % (staging_dir, release_version) +pom = '%s/duckdb_jdbc-%s.pom' % (staging_dir, release_version) +sources_jar = '%s/duckdb_jdbc-%s-sources.jar' % (staging_dir, release_version) +javadoc_jar = '%s/duckdb_jdbc-%s-javadoc.jar' % (staging_dir, release_version) + +pom_template = """ + + 4.0.0 + org.duckdb + duckdb_jdbc + ${VERSION} + jar + DuckDB JDBC Driver + A JDBC-Compliant driver for the DuckDB data management system + https://www.duckdb.org + + + + MIT License + https://raw.githubusercontent.com/duckdb/duckdb/main/LICENSE + repo + + + + + + Mark Raasveldt + mark@duckdblabs.com + DuckDB Labs + https://www.duckdblabs.com + + + Hannes Muehleisen + hannes@duckdblabs.com + DuckDB Labs + https://www.duckdblabs.com + + + + + scm:git:git://github.com/duckdb/duckdb.git + scm:git:ssh://github.com:duckdb/duckdb.git + http://github.com/duckdb/duckdb/tree/main + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.13 + true + + ossrh + https://oss.sonatype.org/ + + + + + + + +""" + +# create a matching POM with this version +pom_path = pathlib.Path(pom) +pom_path.write_text(pom_template.replace("${VERSION}", release_version)) + +# fatten up jar to add other binaries, start with first one +shutil.copyfile(os.path.join(jdbc_artifact_dir, "java-" + combine_builds[0], "duckdb_jdbc.jar"), binary_jar) +for build in combine_builds[1:]: + old_jar = zipfile.ZipFile(os.path.join(jdbc_artifact_dir, "java-" + build, "duckdb_jdbc.jar"), 'r') + for zip_entry in old_jar.namelist(): + if zip_entry.startswith('libduckdb_java.so'): + old_jar.extract(zip_entry, staging_dir) + exec("jar -uf %s -C %s %s" % (binary_jar, staging_dir, zip_entry)) + +javadoc_stage_dir = tempfile.mkdtemp() + +exec("javadoc -Xdoclint:-reference -d %s -sourcepath %s/src/main/java org.duckdb" % (javadoc_stage_dir, jdbc_root_path)) +exec("jar -cvf %s -C %s ." % (javadoc_jar, javadoc_stage_dir)) +exec("jar -cvf %s -C %s/src/main/java org" % (sources_jar, jdbc_root_path)) + +# make sure all files exist before continuing +if ( + not os.path.exists(javadoc_jar) + or not os.path.exists(sources_jar) + or not os.path.exists(pom) + or not os.path.exists(binary_jar) +): + raise ValueError('could not create all required files') + +# now sign and upload everything +# for this to work, you must have entry in ~/.m2/settings.xml: + +# +# +# +# ossrh +# hfmuehleisen +# [...] +# +# +# + +results_dir = os.path.join(jdbc_artifact_dir, "results") +if not os.path.exists(results_dir): + os.mkdir(results_dir) + + +for jar in [binary_jar, sources_jar, javadoc_jar]: + shutil.copyfile(jar, os.path.join(results_dir, os.path.basename(jar))) + +print("JARs created, uploading (this can take a while!)") +deploy_cmd_prefix = 'mvn gpg:sign-and-deploy-file -Durl=%s -DrepositoryId=ossrh' % deploy_url +exec("%s -DpomFile=%s -Dfile=%s" % (deploy_cmd_prefix, pom, binary_jar)) +exec("%s -Dclassifier=sources -DpomFile=%s -Dfile=%s" % (deploy_cmd_prefix, pom, sources_jar)) +exec("%s -Dclassifier=javadoc -DpomFile=%s -Dfile=%s" % (deploy_cmd_prefix, pom, javadoc_jar)) + + +if not is_release: + print("Not a release, not closing repo") + exit(0) + +print("Close/Release steps") +# # beautiful +os.environ["MAVEN_OPTS"] = '--add-opens=java.base/java.util=ALL-UNNAMED' + +# this list has horrid output, lets try to parse. What we want starts with orgduckdb- and then a number +repo_id = re.search(r'(orgduckdb-\d+)', exec("mvn -f %s nexus-staging:rc-list" % (pom)).decode('utf8')).groups()[0] +exec("mvn -f %s nexus-staging:rc-close -DstagingRepositoryId=%s" % (pom, repo_id)) +exec("mvn -f %s nexus-staging:rc-release -DstagingRepositoryId=%s" % (pom, repo_id)) + +print("Done?") diff --git a/scripts/upload-assets-to-staging.sh b/scripts/upload-assets-to-staging.sh index d2111d89..ab3b9693 100755 --- a/scripts/upload-assets-to-staging.sh +++ b/scripts/upload-assets-to-staging.sh @@ -22,9 +22,9 @@ fi FOLDER="$1" DRY_RUN_PARAM="" -# dryrun if repo is not duckdb/duckdb -if [ "$GITHUB_REPOSITORY" != "duckdb/duckdb" ]; then - echo "Repository is $GITHUB_REPOSITORY (not duckdb/duckdb)" +# dryrun if repo is not duckdb/duckdb-java +if [ "$GITHUB_REPOSITORY" != "duckdb/duckdb-java" ]; then + echo "Repository is $GITHUB_REPOSITORY (not duckdb/duckdb-java)" DRY_RUN_PARAM="--dryrun" fi # dryrun if we are not in main