Skip to content

Commit ffb50ba

Browse files
committed
Package GraalOS runtime to make graalos standalone and add smoke tests
1 parent 18cd097 commit ffb50ba

11 files changed

Lines changed: 939 additions & 67 deletions

File tree

ci.jsonnet

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
(import "ci/python-gate.libsonnet") +
66
(import "ci/python-bench.libsonnet") +
77
{
8-
overlay: "40bd8048e1a6ba45494605955ffe748ae4db20be",
8+
overlay: "30def35dbfc43256d57ad3b9b981d92718728e2a",
99
specVersion: "8",
1010
// Until buildbot issues around CI tiers are resolved, we cannot use them
1111
// tierConfig: self.tierConfig,
@@ -30,6 +30,9 @@
3030
BISECT_EMAIL_FROM: "",
3131
npm_config_registry: "",
3232
RODINIA_DATASET_ZIP: "",
33+
GRAALPY_GRAALOS_TOOLCHAIN_URL: "",
34+
GRAALPY_GRAALOS_RUNTIME_URL: "",
35+
GRAALPY_GRAALOS_ARTIFACT_BASE_URL: "",
3336
BUILDBOT_COMMIT_SERVICE: "",
3437
INTERNET_ACCESS_ENV: {},
3538
},
@@ -330,6 +333,15 @@
330333
"tox-example": gpgate_ee + require(GPYEE_NATIVE_STANDALONE) + platform_spec(no_jobs) + platform_spec({
331334
"linux:amd64:jdk-latest" : tier3,
332335
}),
336+
"python-svm-graalos-standalone-build": gpgate_ee + internet_access_env + platform_spec(no_jobs) + platform_spec({
337+
"linux:amd64:jdk-latest": tier3 + $.ol8 + task_spec({
338+
environment +: {
339+
GRAALPY_GRAALOS_TOOLCHAIN_URL: $.overlay_imports.GRAALPY_GRAALOS_TOOLCHAIN_URL,
340+
GRAALPY_GRAALOS_RUNTIME_URL: $.overlay_imports.GRAALPY_GRAALOS_RUNTIME_URL,
341+
GRAALPY_GRAALOS_ARTIFACT_BASE_URL: $.overlay_imports.GRAALPY_GRAALOS_ARTIFACT_BASE_URL,
342+
},
343+
}),
344+
}),
333345
},
334346

335347
local need_pgo = task_spec({runAfter: ["python-pgo-profile-post_merge-linux-amd64-jdk-latest"]}),
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
2+
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
#
4+
# The Universal Permissive License (UPL), Version 1.0
5+
#
6+
# Subject to the condition set forth below, permission is hereby granted to any
7+
# person obtaining a copy of this software, associated documentation and/or
8+
# data (collectively the "Software"), free of charge and under any and all
9+
# copyright rights in the Software, and any and all patent rights owned or
10+
# freely licensable by each licensor hereunder covering either (i) the
11+
# unmodified Software as contributed to or provided by such licensor, or (ii)
12+
# the Larger Works (as defined below), to deal in both
13+
#
14+
# (a) the Software, and
15+
#
16+
# (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
17+
# one is included with the Software each a "Larger Work" to which the Software
18+
# is contributed by such licensors),
19+
#
20+
# without restriction, including without limitation the rights to copy, create
21+
# derivative works of, display, perform, and distribute the Software and make,
22+
# use, sell, offer for sale, import, export, have made, and have sold the
23+
# Software and the Larger Work(s), and to sublicense the foregoing rights on
24+
# either these or other terms.
25+
#
26+
# This license is subject to the following condition:
27+
#
28+
# The above copyright notice and either this complete permission notice or at a
29+
# minimum a reference to the UPL must be included in all copies or substantial
30+
# portions of the Software.
31+
#
32+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38+
# SOFTWARE.
39+
40+
import sysconfig
41+
import unittest
42+
43+
44+
def test_graalos_sqlite3_native_extension_smoke():
45+
soabi = sysconfig.get_config_var("SOABI") or ""
46+
if "graalos" not in soabi:
47+
raise unittest.SkipTest(f"requires GraalOS SOABI, got {soabi!r}")
48+
49+
import _sqlite3
50+
import sqlite3
51+
52+
assert _sqlite3.sqlite_version
53+
conn = sqlite3.connect(":memory:")
54+
try:
55+
conn.execute("create table values_for_sum(value integer)")
56+
conn.executemany("insert into values_for_sum(value) values (?)", [(1,), (2,), (3,)])
57+
assert conn.execute("select sum(value) from values_for_sum").fetchone()[0] == 6
58+
finally:
59+
conn.close()
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#
2+
# Copyright (c) 2026, Oracle and/or its affiliates.
3+
#
4+
# All rights reserved.
5+
#
6+
# Redistribution and use in source and binary forms, with or without modification, are
7+
# permitted provided that the following conditions are met:
8+
#
9+
# 1. Redistributions of source code must retain the above copyright notice, this list of
10+
# conditions and the following disclaimer.
11+
#
12+
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of
13+
# conditions and the following disclaimer in the documentation and/or other materials provided
14+
# with the distribution.
15+
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to
16+
# endorse or promote products derived from this software without specific prior written
17+
# permission.
18+
#
19+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
20+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21+
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22+
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24+
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25+
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27+
# OF THE POSSIBILITY OF SUCH DAMAGE.
28+
#
29+
cmake_minimum_required(VERSION 3.22)
30+
project(graalpy-graalos-standalone-payload LANGUAGES NONE)
31+
32+
foreach(required_var
33+
GRAALPY_LAUNCHER
34+
PYTHON_LAUNCHER
35+
PYTHON3_LAUNCHER
36+
GRAALPY_CONFIG_LAUNCHER
37+
GRAALPY_POLYGLOT_GET_LAUNCHER
38+
GRAALPY_SUITE_PARENT)
39+
if(NOT DEFINED ${required_var})
40+
message(FATAL_ERROR "${required_var} needs to be set")
41+
endif()
42+
endforeach()
43+
44+
set(PAYLOAD_DIR "${CMAKE_BINARY_DIR}")
45+
set(GRAALOS_DIR "${PAYLOAD_DIR}/lib/graalos")
46+
set(SYSROOT_LIB_DIR "${GRAALOS_DIR}/sysroot/lib")
47+
48+
file(REMOVE_RECURSE
49+
"${PAYLOAD_DIR}/bin"
50+
"${PAYLOAD_DIR}/libexec"
51+
"${PAYLOAD_DIR}/lib"
52+
"${PAYLOAD_DIR}/config.json")
53+
file(MAKE_DIRECTORY
54+
"${PAYLOAD_DIR}/bin"
55+
"${PAYLOAD_DIR}/libexec"
56+
"${GRAALOS_DIR}"
57+
"${SYSROOT_LIB_DIR}")
58+
59+
function(_append_env_path out_var env_name)
60+
if(DEFINED ENV{${env_name}} AND NOT "$ENV{${env_name}}" STREQUAL "")
61+
list(APPEND ${out_var} "$ENV{${env_name}}")
62+
set(${out_var} "${${out_var}}" PARENT_SCOPE)
63+
endif()
64+
endfunction()
65+
66+
function(_find_graalos_runtime out_var)
67+
set(candidates)
68+
_append_env_path(candidates GRAALOS_RUNTIME_HOME)
69+
_append_env_path(candidates GRAALOS_HOME)
70+
_append_env_path(candidates GRAALOS_BUILD_HOME)
71+
list(APPEND candidates
72+
"${GRAALPY_SUITE_PARENT}/graalos/cmake-build-clang-pkeysoff"
73+
"${GRAALPY_SUITE_PARENT}/graalos/build")
74+
75+
foreach(candidate IN LISTS candidates)
76+
if(EXISTS "${candidate}/graalhost/graalhost"
77+
AND EXISTS "${candidate}/graalhost/libc.so"
78+
AND EXISTS "${candidate}/graalhost/libbinsweep.so")
79+
set(${out_var} "${candidate}" PARENT_SCOPE)
80+
return()
81+
endif()
82+
endforeach()
83+
84+
string(REPLACE ";" "\n" candidate_text "${candidates}")
85+
message(FATAL_ERROR
86+
"Could not find GraalOS graalhost, safe libc.so, and libbinsweep.so. Checked:\n${candidate_text}")
87+
endfunction()
88+
89+
function(_find_graalos_sysroot_lib_dir out_var)
90+
set(candidates)
91+
if(DEFINED ENV{MUSL_TOOLCHAIN} AND NOT "$ENV{MUSL_TOOLCHAIN}" STREQUAL "")
92+
list(APPEND candidates "$ENV{MUSL_TOOLCHAIN}/lib")
93+
endif()
94+
if(DEFINED ENV{GRAALOS_TOOLCHAIN_PATH} AND NOT "$ENV{GRAALOS_TOOLCHAIN_PATH}" STREQUAL "")
95+
list(APPEND candidates "$ENV{GRAALOS_TOOLCHAIN_PATH}/lib")
96+
endif()
97+
if(DEFINED ENV{JAVA_HOME} AND NOT "$ENV{JAVA_HOME}" STREQUAL "")
98+
list(APPEND candidates
99+
"$ENV{JAVA_HOME}/lib/toolchains/musl-swcfi/lib"
100+
"$ENV{JAVA_HOME}/lib/toolchains/sysroot/x86_64-unknown-linux-musl_swcfi/lib")
101+
endif()
102+
file(GLOB graalos_prebuilt_musl_lib_dirs
103+
LIST_DIRECTORIES TRUE
104+
"${GRAALPY_SUITE_PARENT}/graalos/build-tools/prebuilt/graalvm-graalos-*/lib/toolchains/musl-swcfi/lib")
105+
file(GLOB graalos_prebuilt_sysroot_lib_dirs
106+
LIST_DIRECTORIES TRUE
107+
"${GRAALPY_SUITE_PARENT}/graalos/build-tools/prebuilt/graalvm-graalos-*/lib/toolchains/sysroot/x86_64-unknown-linux-musl_swcfi/lib")
108+
list(APPEND candidates
109+
${graalos_prebuilt_musl_lib_dirs}
110+
${graalos_prebuilt_sysroot_lib_dirs})
111+
112+
set(required_libs
113+
libc++.so
114+
libc++.so.1
115+
libc++.so.1.0
116+
libc++abi.so
117+
libc++abi.so.1
118+
libc++abi.so.1.0
119+
libunwind.so
120+
libunwind.so.1
121+
libunwind.so.1.0)
122+
123+
foreach(candidate IN LISTS candidates)
124+
set(found TRUE)
125+
foreach(lib IN LISTS required_libs)
126+
if(NOT EXISTS "${candidate}/${lib}")
127+
set(found FALSE)
128+
break()
129+
endif()
130+
endforeach()
131+
if(found)
132+
set(${out_var} "${candidate}" PARENT_SCOPE)
133+
return()
134+
endif()
135+
endforeach()
136+
137+
string(REPLACE ";" "\n" candidate_text "${candidates}")
138+
message(FATAL_ERROR "Could not find required GraalOS musl-swcfi runtime libraries. Checked:\n${candidate_text}")
139+
endfunction()
140+
141+
function(_copy_executable source target)
142+
configure_file("${source}" "${target}" COPYONLY)
143+
file(CHMOD "${target}"
144+
PERMISSIONS
145+
OWNER_READ OWNER_WRITE OWNER_EXECUTE
146+
GROUP_READ GROUP_EXECUTE
147+
WORLD_READ WORLD_EXECUTE)
148+
endfunction()
149+
150+
function(_copy_file source target)
151+
configure_file("${source}" "${target}" COPYONLY)
152+
endfunction()
153+
154+
function(_write_launcher target virtual_executable)
155+
file(READ "${CMAKE_CURRENT_LIST_DIR}/launcher-wrapper.sh" wrapper_content)
156+
string(REPLACE "@GRAALPY_SANDBOX_VIRTUAL_EXECUTABLE@" "${virtual_executable}" wrapper_content "${wrapper_content}")
157+
file(WRITE "${target}" "${wrapper_content}")
158+
file(CHMOD "${target}"
159+
PERMISSIONS
160+
OWNER_READ OWNER_WRITE OWNER_EXECUTE
161+
GROUP_READ GROUP_EXECUTE
162+
WORLD_READ WORLD_EXECUTE)
163+
endfunction()
164+
165+
_write_launcher("${PAYLOAD_DIR}/bin/${GRAALPY_LAUNCHER}" "/bin/graalpy")
166+
_write_launcher("${PAYLOAD_DIR}/bin/${PYTHON_LAUNCHER}" "/bin/python")
167+
_write_launcher("${PAYLOAD_DIR}/bin/${PYTHON3_LAUNCHER}" "/bin/python3")
168+
_write_launcher("${PAYLOAD_DIR}/bin/${GRAALPY_CONFIG_LAUNCHER}" "/bin/graalpy-config")
169+
_write_launcher("${PAYLOAD_DIR}/libexec/${GRAALPY_POLYGLOT_GET_LAUNCHER}" "/libexec/graalpy-polyglot-get")
170+
171+
_copy_file("${CMAKE_CURRENT_LIST_DIR}/config.json" "${PAYLOAD_DIR}/config.json")
172+
_copy_executable("${CMAKE_CURRENT_LIST_DIR}/graalpy-sandbox-launcher.sh" "${GRAALOS_DIR}/graalpy-sandbox-launcher")
173+
_copy_executable(
174+
"${CMAKE_CURRENT_LIST_DIR}/graalpy-sandbox-expand-config.sh"
175+
"${GRAALOS_DIR}/graalpy-sandbox-expand-config")
176+
_copy_executable("${CMAKE_CURRENT_LIST_DIR}/graalpy-sandbox-fsmappings.sh" "${GRAALOS_DIR}/graalpy-sandbox-fsmappings")
177+
178+
_find_graalos_runtime(graalos_runtime)
179+
_copy_executable("${graalos_runtime}/graalhost/graalhost" "${GRAALOS_DIR}/graalhost")
180+
_copy_file("${graalos_runtime}/graalhost/libc.so" "${GRAALOS_DIR}/libc.so")
181+
_copy_file("${graalos_runtime}/graalhost/libbinsweep.so" "${GRAALOS_DIR}/libbinsweep.so")
182+
183+
_find_graalos_sysroot_lib_dir(graalos_sysroot_lib_dir)
184+
foreach(lib
185+
libc++.so
186+
libc++.so.1
187+
libc++.so.1.0
188+
libc++abi.so
189+
libc++abi.so.1
190+
libc++abi.so.1.0
191+
libunwind.so
192+
libunwind.so.1
193+
libunwind.so.1.0)
194+
file(COPY "${graalos_sysroot_lib_dir}/${lib}" DESTINATION "${SYSROOT_LIB_DIR}")
195+
endforeach()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"env": {
3+
"HOME": "/home",
4+
"PATH": "/bin",
5+
"PYTHONHOME": "/"
6+
},
7+
"working_dir": "/",
8+
"testing_default_mappings": true,
9+
"allowed_ports": [],
10+
"graalhost": {
11+
"seccomp": null,
12+
"log_level": null,
13+
"extra_args": []
14+
},
15+
"fsmappings": []
16+
}

0 commit comments

Comments
 (0)