Meta+Toolchain: Bring jakt in as a part of the toolchain

This also updates the hello-world "utility".

Co-Authored-By: Andrew Kaster <[email protected]>
This commit is contained in:
Ali Mohammad PurandAndrew Kaster authored and Ali Mohammad Pur committed 2024-10-02 08:10:54 +02:00
1 parent 932ca61936
commit ff54fc0f07
15 files changed
+522 -57

No files matched your search

+13
View File
@@ -46,12 +46,18 @@ outputs:
toolchain_prebuilt_primary_key:
description: 'Primary key for the toolchain cache'
value: ${{ steps.toolchain-prebuilt.outputs.cache-primary-key }}
jakt_prebuilt_primary_key:
description: 'Primary key for the jakt toolchain cache'
value: ${{ steps.jakt-prebuilt.outputs.cache-primary-key }}
toolchain_prebuilt_path:
description: 'Path to the prebuilt toolchain'
value: ${{ steps.toolchain-stamps.outputs.toolchain_path }}
toolchain_prebuilt_hit:
description: 'Whether the toolchain prebuilt cache was hit'
value: ${{ steps.toolchain-prebuilt.outputs.cache-hit }}
jakt_prebuilt_hit:
description: 'Whether the jakt prebuilt cache was hit'
value: ${{ steps.jakt-prebuilt.outputs.cache-hit }}
runs:
using: "composite"
@@ -93,6 +99,13 @@ runs:
path: ${{ steps.toolchain-stamps.outputs.toolchain_path }}
key: '"toolchain" | "${{ inputs.arch }}" | "${{ inputs.toolchain }}" | "${{ steps.toolchain-stamps.outputs.toolchain_stamp }}"'
- name: 'Jakt Toolchain Prebuilt Cache'
uses: actions/cache/restore@v4
id: 'jakt-prebuilt'
with:
path: ${{ github.workspace }}/Toolchain/Local/jakt
key: toolchain-${{ runner.os }}"-jakt-toolchain-${{ matrix.arch }}-${{ steps.toolchain-stamps.outputs.toolchain_stamp }}"
- name: 'Toolchain Compiler Cache'
uses: actions/cache/restore@v4
id: 'toolchain-ccache'
+15
View File
@@ -35,6 +35,14 @@ inputs:
description: 'Whether the toolchain prebuilt cache was hit'
required: false
default: false
jakt_prebuilt_primary_key:
description: 'Primary key for the jakt prebuilt cache'
required: false
default: ''
jakt_prebuilt_hit:
description: 'Whether the jakt prebuilt cache was hit'
required: false
default: false
runs:
using: "composite"
@@ -48,6 +56,13 @@ runs:
path: ${{ inputs.toolchain_prebuilt_path }}
key: ${{ inputs.toolchain_prebuilt_primary_key }}
- name: 'Jakt Toolchain Prebuilt Cache'
uses: actions/cache/save@v4
if: ${{ github.event_name != 'pull_request' && !inputs.jakt_prebuilt_hit }}
with:
path: ${{ inputs.jakt_prebuilt_path }}
key: ${{ inputs.jakt_prebuilt_primary_key }}
- name: 'Toolchain Compiler Cache'
uses: actions/cache/save@v4
if: ${{ github.event_name != 'pull_request' && inputs.toolchain_ccache_path != '' }}
+6 -1
View File
@@ -29,7 +29,10 @@ runs:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install ccache clang-18 clang++-18 clang-format-18 lld-18 gcc-13 g++-13 libstdc++-13-dev ninja-build unzip qt6-base-dev qt6-tools-dev-tools libqt6svg6-dev qt6-multimedia-dev libgl1-mesa-dev libpulse-dev libssl-dev libegl1-mesa-dev
sudo apt-get install ccache clang-18 clang++-18 clang-format-18 lld-18 gcc-13 g++-13 libstdc++-13-dev ninja-build unzip qt6-base-dev qt6-tools-dev-tools libqt6svg6-dev qt6-multimedia-dev libgl1-mesa-dev libpulse-dev libssl-dev libegl1-mesa-dev libclang-18-dev
sudo apt-get remove clang-{13,14,15} clang++-{13,14,15} libclang-{13,14,15}-dev llvm-{13,14,15}
sudo apt-get install clang-18 clang++-18 llvm-18 llvm-18-dev
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-18 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-18 100
@@ -65,7 +68,9 @@ runs:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get remove clang-{13,14,15} clang++-{13,14,15} libclang-{13,14,15}-dev llvm-{13,14,15}
sudo apt-get install clang-format-18 ccache e2fsprogs gcc-13 g++-13 libstdc++-13-dev libmpfr-dev libmpc-dev ninja-build optipng qemu-utils qemu-system-i386 unzip generate-ninja libegl1-mesa-dev
sudo apt-get install clang-18 clang++-18 llvm-18 llvm-18-dev
- name: Enable KVM group perms
if: ${{ inputs.os == 'Serenity' }}
+6
View File
@@ -84,6 +84,10 @@ jobs:
ARCH: ${{ inputs.arch}}
CCACHE_DIR: ${{ env.TOOLCHAIN_CCACHE_DIR }}
- name: Build jakt toolchain
if: ${{ !steps.cache-restore.output.jakt_prebuilt_hit }}
run: ARCH="${{ matrix.arch }}" CXX=g++-13 ${{ github.workspace }}/Toolchain/BuildJakt.sh
- name: Create Build Environment
if: ${{ inputs.debug_options == 'ALL_DEBUG' }}
# Build the entire project with all available debug options turned on, to prevent code rot.
@@ -142,6 +146,8 @@ jobs:
toolchain_prebuilt_path: ${{ steps.cache-restore.outputs.toolchain_prebuilt_path }}
toolchain_prebuilt_primary_key: ${{ steps.cache-restore.outputs.toolchain_prebuilt_primary_key }}
toolchain_prebuilt_hit: ${{ steps.cache-restore.outputs.toolchain_prebuilt_hit }}
jakt_prebuilt_primary_key: ${{ steps.cache-restore.outputs.jakt_prebuilt_primary_key }}
jakt_prebuilt_hit: ${{ steps.cache-restore.outputs.jakt_prebuilt_hit }}
# === TEST ===
+2 -8
View File
@@ -49,13 +49,6 @@ if (NOT HACKSTUDIO_BUILD)
# Host tools, required to generate files for the build
find_package(Lagom CONFIG REQUIRED)
if (ENABLE_JAKT)
find_package(Jakt CONFIG REQUIRED
HINTS "${Lagom_DIR}/.."
)
endif()
endif()
# Meta target to run all code-gen steps in the build.
@@ -190,7 +183,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland/Services)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland/Libraries)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland)
add_custom_target(components ALL)
include(jakt)
option(BUILD_EVERYTHING "Build all optional components" ON)
include(utils)
+1 -2
View File
@@ -26,8 +26,7 @@ serenity_option(ENABLE_ACCELERATED_GRAPHICS ON CACHE BOOL "Enable use of acceler
serenity_option(HACKSTUDIO_BUILD OFF CACHE BOOL "Automatically enabled when building from HackStudio")
serenity_option(ENABLE_JAKT OFF CACHE BOOL "Enable building jakt files")
serenity_option(JAKT_SOURCE_DIR "" CACHE STRING "Pre-existing jakt language source directory")
serenity_option(ENABLE_JAKT ON CACHE BOOL "Enable building jakt files")
serenity_option(SERENITY_CACHE_DIR "${PROJECT_BINARY_DIR}/../caches" CACHE PATH "Location of shared cache of downloaded files")
serenity_option(ENABLE_NETWORK_DOWNLOADS ON CACHE BOOL "Allow downloads of required files. If OFF, required files must already be present in SERENITY_CACHE_DIR")
+156 -18
View File
@@ -1,20 +1,158 @@
#
# Builds the jakt bootstrap compiler as a host tool for Lagom to compile files written in jakt
#
include(FetchContent)
FetchContent_Declare(jakt
GIT_REPOSITORY https://github.com/SerenityOS/jakt.git
GIT_TAG main
GIT_SHALLOW TRUE
)
# Allow developers to skip download/update steps with local checkout
if (JAKT_SOURCE_DIR)
set(FETCHCONTENT_SOURCE_DIR_JAKT ${JAKT_SOURCE_DIR} CACHE PATH "Developer's pre-existing jakt source directory" FORCE)
message(STATUS "Using pre-existing JAKT_SOURCE_DIR: ${JAKT_SOURCE_DIR}")
if (NOT ENABLE_JAKT)
return()
endif()
set(JAKT_BUILD_TESTING OFF)
FetchContent_MakeAvailable(jakt)
set(arch ${CMAKE_SYSTEM_PROCESSOR})
if (arch STREQUAL "x86")
set(arch "i686")
endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(vendor "apple")
else()
set(vendor "pc")
endif()
if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(os "win32")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "SerenityOS")
set(os "serenity")
else()
string(TOLOWER ${CMAKE_SYSTEM_NAME} os)
endif()
set(JAKT_COMPILER "${SerenityOS_SOURCE_DIR}/Toolchain/Local/jakt/bin/jakt")
set(JAKT_TARGET_TRIPLE ${arch}-${vendor}-${os}-unknown)
set(JAKT_LIBRARY_BASE "${CMAKE_SYSROOT}/usr/local/lib")
set(JAKT_LIBRARY_DIR "${JAKT_LIBRARY_BASE}/${JAKT_TARGET_TRIPLE}")
set(JAKT_INCLUDE_DIR "${CMAKE_SYSROOT}/usr/local/include/runtime")
cmake_host_system_information(RESULT JAKT_PROCESSOR_COUNT QUERY NUMBER_OF_PHYSICAL_CORES)
set_property(GLOBAL PROPERTY JOB_POOLS jakt_pool=1)
message(STATUS "Using jakt compiler at ${JAKT_COMPILER}")
message(STATUS "Using jakt target triple ${JAKT_TARGET_TRIPLE}")
message(STATUS "Using jakt library directory ${JAKT_LIBRARY_DIR}")
function(add_jakt_executable target source)
cmake_parse_arguments(PARSE_ARGV 2 JAKT_EXECUTABLE "" "" "INCLUDES;CONFIGS;LINK_LIBRARIES;EXTRA_CPP_SOURCES")
set(configs)
set(includes)
set(extra_cpp_sources)
foreach(config IN LISTS JAKT_EXECUTABLE_CONFIGS)
list(APPEND configs "--config" "${config}")
endforeach()
foreach(include IN LISTS JAKT_EXECUTABLE_INCLUDES)
list(APPEND includes "-I" "${include}")
endforeach()
foreach(source IN LISTS JAKT_EXECUTABLE_EXTRA_CPP_SOURCES)
get_filename_component(source ${source} ABSOLUTE)
list(APPEND extra_cpp_sources "-X" "${source}")
endforeach()
set(JAKT_EXECUTABLE_NAME ${target})
set(EXECUTABLE_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${JAKT_EXECUTABLE_NAME}.dir")
set(EMPTY_SOURCE_FILE "${EXECUTABLE_BINARY_DIR}/empty_cmake_hack.cpp")
set(main_output_name "${JAKT_EXECUTABLE_NAME}.a")
set(main_output "${EXECUTABLE_BINARY_DIR}/build/${main_output_name}")
set(depfile "${EXECUTABLE_BINARY_DIR}/build/${main_output_name}.M")
cmake_path(ABSOLUTE_PATH source
BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE source_abs
)
add_custom_command(
OUTPUT ${main_output}
COMMAND ${JAKT_COMPILER}
-d -O -J ${JAKT_PROCESSOR_COUNT}
--ak-is-my-only-stdlib
-T ${JAKT_TARGET_TRIPLE}
--binary-dir "${EXECUTABLE_BINARY_DIR}/build"
--exports-dir "${CMAKE_CURRENT_BINARY_DIR}"
-C ${CMAKE_CXX_COMPILER}
--archiver ${CMAKE_AR}
--link-archive ${main_output_name}
--runtime-library-path ${JAKT_LIBRARY_BASE}
--dep-file ${depfile}
--extra-cpp-flag --sysroot=${CMAKE_SYSROOT}
${configs}
${includes}
${extra_cpp_sources}
"${source_abs}"
DEPFILE ${depfile}
DEPENDS
${JAKT_EXECUTABLE_EXTRA_CPP_SOURCES}
COMMENT "Jakt: Compile ${source}"
JOB_POOL jakt_pool
)
add_custom_target(${JAKT_EXECUTABLE_NAME}.t
DEPENDS ${main_output}
)
add_custom_command(
OUTPUT ${EMPTY_SOURCE_FILE}
COMMAND ${CMAKE_COMMAND} -E touch ${EMPTY_SOURCE_FILE}
)
add_executable(${JAKT_EXECUTABLE_NAME} ${EMPTY_SOURCE_FILE})
add_dependencies(${JAKT_EXECUTABLE_NAME} ${JAKT_EXECUTABLE_NAME}.t)
add_library(${JAKT_EXECUTABLE_NAME}.lib STATIC IMPORTED)
set_property(TARGET ${JAKT_EXECUTABLE_NAME}.lib PROPERTY IMPORTED_LOCATION ${main_output})
target_link_libraries(${JAKT_EXECUTABLE_NAME}
PRIVATE
${JAKT_LIBRARY_DIR}/libjakt_main_${JAKT_TARGET_TRIPLE}.a
${JAKT_EXECUTABLE_NAME}.lib
${JAKT_LIBRARY_DIR}/libjakt_runtime_${JAKT_TARGET_TRIPLE}.a
${JAKT_EXECUTABLE_LINK_LIBRARIES}
)
endfunction()
function(serenity_jakt_app target_name source)
cmake_parse_arguments(PARSE_ARGV 2 SERENITY_JAKT_EXECUTABLE "" "" "INCLUDES;CONFIGS;LINK_LIBRARIES")
add_jakt_executable(${target_name} ${source}
INCLUDES
${INCLUDE_DIRECTORIES}
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/Userland/Libraries
${PROJECT_SOURCE_DIR}/Userland/Libraries/LibCrypt
${PROJECT_SOURCE_DIR}/Userland/Libraries/LibSystem
${PROJECT_SOURCE_DIR}/Userland/Services
${PROJECT_SOURCE_DIR}/Userland
${PROJECT_BINARY_DIR}
${PROJECT_BINARY_DIR}/Userland/Services
${PROJECT_BINARY_DIR}/Userland/Libraries
${PROJECT_BINARY_DIR}/Userland
${SERENITY_JAKT_EXECUTABLE_INCLUDES}
CONFIGS ${SERENITY_JAKT_EXECUTABLE_CONFIGS}
LINK_LIBRARIES ${SERENITY_JAKT_EXECUTABLE_LINK_LIBRARIES}
)
set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
install(TARGETS ${target_name} RUNTIME DESTINATION bin OPTIONAL)
serenity_generated_sources(${target_name})
serenity_set_implicit_links(${target_name})
endfunction(serenity_jakt_app)
function(serenity_jakt_executable target_name)
cmake_parse_arguments(PARSE_ARGV 1 SERENITY_JAKT_EXECUTABLE "" "" "MAIN_SOURCE;CPP_SOURCES;CONFIGS;LINK_LIBRARIES")
add_jakt_executable(${target_name} ${SERENITY_JAKT_EXECUTABLE_MAIN_SOURCE}
INCLUDES
${INCLUDE_DIRECTORIES}
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/Userland/Libraries
${PROJECT_SOURCE_DIR}/Userland/Libraries/LibCrypt
${PROJECT_SOURCE_DIR}/Userland/Libraries/LibSystem
${PROJECT_SOURCE_DIR}/Userland/Services
${PROJECT_SOURCE_DIR}/Userland
${PROJECT_BINARY_DIR}
${PROJECT_BINARY_DIR}/Userland/Services
${PROJECT_BINARY_DIR}/Userland/Libraries
${PROJECT_BINARY_DIR}/Userland
${SERENITY_JAKT_EXECUTABLE_INCLUDES}
CONFIGS ${SERENITY_JAKT_EXECUTABLE_CONFIGS}
LINK_LIBRARIES ${SERENITY_JAKT_EXECUTABLE_LINK_LIBRARIES}
EXTRA_CPP_SOURCES ${SERENITY_JAKT_EXECUTABLE_CPP_SOURCES}
)
endfunction()
+9 -3
View File
@@ -7,6 +7,7 @@ define_property(TARGET PROPERTY SERENITY_COMPONENT_DESCRIPTION BRIEF_DOCS "Seren
define_property(TARGET PROPERTY SERENITY_COMPONENT_RECOMMENDED BRIEF_DOCS "SerenityOS component recommended (flag)" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_COMPONENT_REQUIRED BRIEF_DOCS "SerenityOS component required (flag)" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_COMPONENT_DEPENDS BRIEF_DOCS "SerenityOS component dependencies" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_SKIP_BUILD BRIEF_DOCS "SerenityOS component target should skip build (flag)" FULL_DOCS "-")
function(serenity_component name)
cmake_parse_arguments(PARSE_ARGV 1 SERENITY_COMPONENT "RECOMMENDED;REQUIRED" "DESCRIPTION" "TARGETS;DEPENDS")
@@ -21,14 +22,19 @@ function(serenity_component name)
SERENITY_COMPONENT_REQUIRED "${SERENITY_COMPONENT_REQUIRED}"
SERENITY_COMPONENT_DEPENDS "${SERENITY_COMPONENT_DEPENDS}"
)
set(static_should_disable_target TRUE)
if(BUILD_EVERYTHING OR "${BUILD_${NAME_UPPER}}" OR SERENITY_COMPONENT_REQUIRED)
set(static_should_disable_target FALSE)
endif()
set(should_disable_target $<BOOL:${static_should_disable_target}>)
if(NOT "${SERENITY_COMPONENT_TARGETS}" STREQUAL "") # note: one component is /bin/false, which makes this tricky
foreach(target IN LISTS SERENITY_COMPONENT_TARGETS)
add_dependencies("Component${name}" "${target}")
set(should_disable_target $<OR:${should_disable_target},$<BOOL:$<TARGET_PROPERTY:${target},SERENITY_SKIP_BUILD>>>)
endforeach()
endif()
if(BUILD_EVERYTHING OR "${BUILD_${NAME_UPPER}}" OR SERENITY_COMPONENT_REQUIRED)
add_dependencies(components "Component${name}")
endif()
set_target_properties("Component${name}" PROPERTIES EXCLUDE_FROM_ALL ${should_disable_target})
foreach(dependency IN LISTS SERENITY_COMPONENT_DEPENDS)
add_dependencies("Component${name}" "Component${dependency}")
endforeach()
+50 -3
View File
@@ -77,10 +77,44 @@ function(serenity_libc target_name fs_name)
serenity_generated_sources(${target_name})
endfunction()
if (NOT COMMAND serenity_add_executable)
function(serenity_add_executable name)
# if any of the sources are .jakt files, switch to using serenity_jakt_executable()
# and pass the non-jakt sources as extra cpp sources.
set(jakt_source)
set(cpp_sources)
foreach(source ${ARGN})
if (${source} MATCHES "\\.jakt$")
if (jakt_source)
message(FATAL_ERROR "Multiple main jakt files in executable ${name}")
else()
set(jakt_source ${source})
endif()
else()
list(APPEND cpp_sources ${source})
endif()
endforeach()
if (jakt_source)
if (ENABLE_JAKT)
serenity_jakt_executable(${name} MAIN_SOURCE ${jakt_source} CPP_SOURCES ${cpp_sources})
else()
message(STATUS "Skipping ${name} because jakt is disabled")
# Make an empty c++ file:
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp" "// This file was generated by CMake to skip a jakt executable\n")
add_executable(${name} "${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp")
set_target_properties(${name} PROPERTIES SERENITY_SKIP_BUILD TRUE)
endif()
else()
add_executable(${name} ${cpp_sources})
endif()
endfunction()
endif()
if (NOT COMMAND serenity_bin)
function(serenity_bin target_name)
serenity_install_sources()
add_executable(${target_name} ${SOURCES})
serenity_add_executable(${target_name} ${SOURCES})
target_link_libraries(${target_name} PUBLIC GenericClangPlugin)
set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
install(TARGETS ${target_name} RUNTIME DESTINATION bin OPTIONAL)
@@ -126,10 +160,11 @@ endfunction()
function(serenity_app target_name)
cmake_parse_arguments(PARSE_ARGV 1 SERENITY_APP "" "ICON" "")
serenity_bin("${target_name}")
set(small_icon "${SerenityOS_SOURCE_DIR}/Base/res/icons/16x16/${SERENITY_APP_ICON}.png")
set(medium_icon "${SerenityOS_SOURCE_DIR}/Base/res/icons/32x32/${SERENITY_APP_ICON}.png")
serenity_bin("${target_name}")
if (EXISTS "${small_icon}")
embed_resource("${target_name}" serenity_icon_s "${small_icon}")
else()
@@ -160,7 +195,19 @@ function(embed_resource target section file)
DEPENDS "${input_file}" "${SerenityOS_SOURCE_DIR}/Meta/generate-embedded-resource-assembly.sh"
COMMENT "Generating ${asm_file}"
)
target_sources("${target}" PRIVATE "${asm_file}")
add_library(
${target}-resources-${section}
OBJECT
"${asm_file}"
)
target_link_libraries(
${target} PRIVATE
-Wl,--whole-archive
${target}-resources-${section}
-Wl,--no-whole-archive
)
endfunction()
function(remove_path_if_version_changed version version_file cache_path)
-1
View File
@@ -312,7 +312,6 @@ macro(add_serenity_subdirectory path)
add_subdirectory("${SERENITY_PROJECT_ROOT}/${path}" "${CMAKE_CURRENT_BINARY_DIR}/${path}")
endmacro()
add_custom_target(components ALL)
option(BUILD_EVERYTHING "Build all optional components" ON)
if (NOT TARGET all_generated)
+1 -3
View File
@@ -15,6 +15,4 @@ add_subdirectory(CodeGenerators)
add_subdirectory(ConfigureComponents)
add_subdirectory(IPCMagicLinter)
if (ENABLE_JAKT)
include(jakt)
endif()
include(jakt)
+15
View File
@@ -169,7 +169,9 @@ cmd_with_target() {
else
TOOLCHAIN_DIR="$SERENITY_SOURCE_DIR/Toolchain/Local/$TARGET_TOOLCHAIN/$TARGET"
fi
JAKT_TOOLCHAIN_DIR="$SERENITY_SOURCE_DIR/Toolchain/Local/jakt"
SUPER_BUILD_DIR="$SERENITY_SOURCE_DIR/Build/superbuild-$TARGET$TARGET_TOOLCHAIN"
JAKT_LIB_DIR="$BUILD_DIR/Root/usr/local/lib/$TARGET-pc-serenity-unknown"
else
SUPER_BUILD_DIR="$BUILD_DIR"
CMAKE_ARGS+=("-DCMAKE_INSTALL_PREFIX=$SERENITY_SOURCE_DIR/Build/lagom-install")
@@ -250,6 +252,18 @@ build_toolchain() {
fi
}
build_jakt() {
[ -z "$JAKT_TOOLCHAIN_DIR" ] && return
echo "build_jakt: $JAKT_TOOLCHAIN_DIR"
( cd "$SERENITY_SOURCE_DIR/Toolchain" && ./BuildJakt.sh )
}
ensure_jakt() {
if ! [ -d "$JAKT_TOOLCHAIN_DIR" ] || ! [ -d "$JAKT_LIB_DIR" ]; then
build_jakt
fi
}
ensure_toolchain() {
if [ "$(cmake -P "$SERENITY_SOURCE_DIR"/Meta/CMake/cmake-version.cmake)" -ne 1 ]; then
build_cmake
@@ -269,6 +283,7 @@ ensure_toolchain() {
fi
fi
ensure_jakt
}
confirm_rebuild_if_toolchain_exists() {
+232
View File
@@ -0,0 +1,232 @@
#!/usr/bin/env bash
set -eo pipefail
# This file will need to be run in bash, for now.
# === CONFIGURATION AND SETUP ===
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck source=/dev/null
. "${DIR}/../Meta/shell_include.sh"
exit_if_running_as_root "Do not run BuildJakt.sh as root, your Build directory will become root-owned"
echo "$DIR"
ARCHES=("x86_64" "aarch64" "riscv64")
PREFIX="$DIR/Local/jakt"
VALID_TOOLCHAINS=()
declare -A CXX_GNU=()
declare -A CXX_CLANG=()
declare -A RANLIB_GNU=()
declare -A RANLIB_CLANG=()
declare -A BUILD_GNU=()
declare -A BUILD_CLANG=()
: "${BUILD_GNU[@]}" "${BUILD_CLANG[@]}" # make shellcheck understand that these might be used.
for ARCH in "${ARCHES[@]}"; do
TARGET="$ARCH-pc-serenity"
BUILD_GNU["$ARCH"]="$DIR/../Build/$ARCH"
BUILD_CLANG["$ARCH"]="$DIR/../Build/${ARCH}clang"
CXX_GNU["$ARCH"]="$DIR/Local/$ARCH/bin/$TARGET-g++"
CXX_CLANG["$ARCH"]="$DIR/Local/clang/bin/$TARGET-clang++"
# Indirectly accessed below.
# shellcheck disable=SC2034
RANLIB_GNU["$ARCH"]="$DIR/Local/$ARCH/bin/$TARGET-ranlib"
# shellcheck disable=SC2034
RANLIB_CLANG["$ARCH"]="$DIR/Local/clang/bin/llvm-ranlib"
if [ -x "${CXX_GNU["$ARCH"]}" ]; then
VALID_TOOLCHAINS+=("GNU;${ARCH}")
fi
if [ -x "${CXX_CLANG[${ARCH}]}" ]; then
VALID_TOOLCHAINS+=("CLANG;${ARCH}")
fi
done
if [ "${#VALID_TOOLCHAINS}" -eq 0 ]; then
die "Need to build at least one C++ toolchain (either GNU or Clang) before BuildJakt.sh can succeed"
fi
REALPATH="realpath"
SYSTEM_NAME="$(uname -s)"
NPROC=$(get_number_of_processing_units)
if [ "$SYSTEM_NAME" = "OpenBSD" ]; then
REALPATH="readlink -f"
export CXX=eg++
fi
if command -v ginstall &>/dev/null; then
INSTALL=ginstall
else
INSTALL=install
fi
buildstep() {
NAME=$1
shift
"$@" 2>&1 | sed $'s|^|\x1b[34m['"${NAME}"$']\x1b[39m |'
}
buildstep_ninja() {
# When ninja writes to a pipe, it strips ANSI escape codes and prints one line per buildstep.
# Instead, use NINJA_STATUS so that we get colored output from LLVM's build and fewer lines of output when running in a tty.
# ANSI escape codes in NINJA_STATUS are slightly janky (ninja thinks that "\e[34m" needs 5 output characters instead of 5, so
# its middle elision is slightly off; also it would happily elide the "\e39m" which messes up the output if the terminal is too
# narrow), but it's still working better than the alternative.
NAME=$1
shift
env NINJA_STATUS=$'\e[34m['"${NAME}"$']\e[39m [%f/%t] ' "$@"
}
echo PREFIX is "$PREFIX"
mkdir -p "$DIR/Tarballs"
JAKT_COMMIT_HASH="714b634cf1de81e38a99608c3310157688cd9125"
JAKT_NAME="jakt-${JAKT_COMMIT_HASH}"
JAKT_TARBALL="${JAKT_NAME}.tar.gz"
JAKT_GIT_URL="https://github.com/serenityos/jakt"
# === DEPENDENCIES ===
buildstep dependencies echo "Checking whether 'ninja' is available..."
if ! command -v "${NINJA:-ninja}" >/dev/null; then
buildstep dependencies echo "Please make sure to install Ninja (for the '${NINJA:-ninja}' tool)."
exit 1
fi
buildstep dependencies echo "Checking whether 'cmake' is available..."
if ! command -v cmake >/dev/null; then
buildstep dependencies echo "Please make sure to install CMake (for the 'cmake' tool)."
exit 1
fi
buildstep dependencies echo "Checking whether your C++ compiler works..."
if ! ${CXX:-c++} -o /dev/null -xc++ - >/dev/null <<'PROGRAM'
int main() {}
PROGRAM
then
buildstep dependencies echo "Please make sure to install a working C++ compiler."
exit 1
fi
# === DOWNLOAD AND PATCH ===
pushd "$DIR/Tarballs"
if [ ! -d "${JAKT_NAME}" ]; then
echo "Downloading jakt..."
rm -f "$JAKT_TARBALL"
curl -L --output "$JAKT_TARBALL" "$JAKT_GIT_URL/archive/$JAKT_COMMIT_HASH.tar.gz"
echo "Extracting jakt..."
tar -xzf "${JAKT_TARBALL}"
else
echo "Using existing Jakt source directory"
fi
popd
# === COMPILE AND INSTALL ===
rm -rf "$PREFIX"
mkdir -p "$PREFIX"
rm -rf "$DIR/Build/jakt"
mkdir -p "$DIR/Build/jakt"
pushd "$DIR/Build/jakt"
echo "XXX configure jakt"
buildstep "jakt/configure" cmake -S "$DIR/Tarballs/${JAKT_NAME}" -B . \
-DSERENITY_SOURCE_DIR="$DIR/.." \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_BUILD_TYPE=Release \
-GNinja \
|| exit 1
echo "XXX build jakt"
buildstep_ninja "jakt/build" ninja jakt_stage1
echo "XXX install jakt"
buildstep_ninja "jakt/install" ninja install
popd
build_for() {
TOOLCHAIN="$1"
ARCH="$2"
TARGET="$ARCH-pc-serenity"
JAKT_TARGET="$TARGET-unknown"
current_build="BUILD_${TOOLCHAIN}[${ARCH}]"
current_cxx="CXX_${TOOLCHAIN}[${ARCH}]"
current_ranlib="RANLIB_${TOOLCHAIN}[${ARCH}]"
BUILD="${!current_build}"
TARGET_CXX="${!current_cxx}"
TARGET_RANLIB="${!current_ranlib}"
# On at least OpenBSD, the path must exist to call realpath(3) on it
if [ ! -d "$BUILD" ]; then
mkdir -p "$BUILD"
fi
BUILD=$($REALPATH "$BUILD")
echo "XXX building jakt support libs in $BUILD with $TARGET_CXX"
SYSROOT="$BUILD/Root"
echo SYSROOT is "$SYSROOT"
rm -rf "$DIR/Build/jakt-$TOOLCHAIN-$ARCH"
mkdir -p "$DIR/Build/jakt-$TOOLCHAIN-$ARCH"
pushd "$DIR/Build/jakt-$TOOLCHAIN-$ARCH"
echo "XXX serenity libc headers"
mkdir -p "$BUILD"
pushd "$BUILD"
mkdir -p Root/usr/include/
SRC_ROOT=$($REALPATH "$DIR"/..)
FILES=$(find \
"$SRC_ROOT"/AK \
"$SRC_ROOT"/Kernel/API \
"$SRC_ROOT"/Kernel/Arch \
"$SRC_ROOT"/Userland/Libraries/LibC \
"$SRC_ROOT"/Userland/Libraries/LibELF/ELFABI.h \
"$SRC_ROOT"/Userland/Libraries/LibRegex/RegexDefs.h \
-name '*.h' -print)
for header in $FILES; do
target=$(echo "$header" | sed \
-e "s|$SRC_ROOT/AK/|AK/|" \
-e "s|$SRC_ROOT/Userland/Libraries/LibC||" \
-e "s|$SRC_ROOT/Kernel/|Kernel/|" \
-e "s|$SRC_ROOT/Userland/Libraries/LibELF/|LibELF/|" \
-e "s|$SRC_ROOT/Userland/Libraries/LibRegex/|LibRegex/|")
buildstep "system_headers" mkdir -p "$(dirname "Root/usr/include/$target")"
buildstep "system_headers" "$INSTALL" "$header" "Root/usr/include/$target"
done
unset SRC_ROOT
popd
echo "XXX build jakt support libs"
rm -fr "$SYSROOT/usr/local/lib/$JAKT_TARGET"
buildstep "jakt/support/build/$TOOLCHAIN" "$PREFIX/bin/jakt" cross \
--only-support-libs \
--install-root "$SYSROOT/usr/local" \
--target-triple "$JAKT_TARGET" \
--target-links-ak \
-C "$TARGET_CXX" \
-O \
-J "$NPROC"
buildstep "jakt/support/build/$TOOLCHAIN/ranlib" "$TARGET_RANLIB" "$SYSROOT/usr/local/lib/$JAKT_TARGET/libjakt_runtime_$JAKT_TARGET.a"
buildstep "jakt/support/build/$TOOLCHAIN/ranlib" "$TARGET_RANLIB" "$SYSROOT/usr/local/lib/$JAKT_TARGET/libjakt_main_$JAKT_TARGET.a"
popd
}
for TOOLCHAIN_AND_ARCH in "${VALID_TOOLCHAINS[@]}"; do
IFS=';' read -r TOOLCHAIN ARCH <<< "$TOOLCHAIN_AND_ARCH"
buildstep "build/$TOOLCHAIN/$ARCH" build_for "$TOOLCHAIN" "$ARCH"
done
echo "Done creating jakt toolchain for targets " "${VALID_TOOLCHAINS[@]}"
+15 -17
View File
@@ -1,4 +1,11 @@
file(GLOB CMD_SOURCES CONFIGURE_DEPENDS "*.cpp")
file(GLOB CMD_SOURCES_CPP CONFIGURE_DEPENDS "*.cpp")
file(GLOB CMD_SOURCES_JAKT CONFIGURE_DEPENDS "*.jakt")
if (ENABLE_JAKT)
list(APPEND CMD_SOURCES ${CMD_SOURCES_CPP} ${CMD_SOURCES_JAKT})
else()
list(APPEND CMD_SOURCES ${CMD_SOURCES_CPP})
endif()
list(APPEND SPECIAL_TARGETS test install)
list(APPEND REQUIRED_TARGETS
arp base64 basename cat chmod chown clear comm cp cut date dd df diff dirname dmesg du echo env expr false
@@ -15,6 +22,7 @@ list(APPEND RECOMMENDED_TARGETS
foreach(CMD_SRC ${CMD_SOURCES})
get_filename_component(CMD_NAME ${CMD_SRC} NAME_WLE)
get_filename_component(CMD_EXT ${CMD_SRC} LAST_EXT)
if (CMD_NAME IN_LIST SPECIAL_TARGETS)
set(TARGET_NAME "${CMD_NAME}-bin")
else()
@@ -39,10 +47,14 @@ foreach(CMD_SRC ${CMD_SOURCES})
)
endif()
add_executable(${TARGET_NAME} ${CMD_SRC})
target_link_libraries(${TARGET_NAME} PRIVATE LibCore LibMain)
serenity_add_executable(${TARGET_NAME} ${CMD_SRC})
serenity_set_implicit_links(${TARGET_NAME})
set_target_properties(${TARGET_NAME} PROPERTIES EXCLUDE_FROM_ALL TRUE)
target_link_libraries(${TARGET_NAME} PRIVATE LibCore)
if(NOT ${CMD_EXT} EQUAL jakt)
target_link_libraries(${TARGET_NAME} PRIVATE LibMain)
endif()
install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin OPTIONAL)
if (CMD_NAME IN_LIST SPECIAL_TARGETS)
@@ -53,20 +65,6 @@ foreach(CMD_SRC ${CMD_SOURCES})
endif()
endforeach()
if (ENABLE_JAKT)
add_jakt_executable(hello-jakt
MAIN_SOURCE hello-world.jakt
)
target_link_libraries(hello-jakt PRIVATE LibC)
set_target_properties(hello-jakt PROPERTIES EXCLUDE_FROM_ALL TRUE)
install(TARGETS hello-jakt RUNTIME DESTINATION bin OPTIONAL)
serenity_component(
hello-jakt
RECOMMENDED
TARGETS hello-jakt
)
endif()
install(CODE "file(CREATE_LINK grep ${CMAKE_INSTALL_PREFIX}/bin/egrep SYMBOLIC)")
install(CODE "file(CREATE_LINK grep ${CMAKE_INSTALL_PREFIX}/bin/fgrep SYMBOLIC)")
install(CODE "file(CREATE_LINK grep ${CMAKE_INSTALL_PREFIX}/bin/rgrep SYMBOLIC)")
+1 -1
View File
@@ -1,3 +1,3 @@
function main() {
fn main() {
println("Hello, World, from jakt!");
}