From ca42da23c232623f28bb67bb6a373709701875fe Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Thu, 19 May 2022 23:46:36 -0600 Subject: [PATCH] Meta+Userland: Add jakt as an optional Lagom Tool We can now use ENABLE_JAKT to pull jakt as a host tool and use it to pre-process .jakt files into .cpp files for use in serenity applications --- CMakeLists.txt | 3 ++ Documentation/AdvancedBuildInstructions.md | 2 ++ Meta/CMake/code_generators.cmake | 22 ++++++++++++ Meta/CMake/common_options.cmake | 3 ++ Meta/CMake/jakt.cmake | 39 ++++++++++++++++++++++ Meta/CMake/lagom-install-config.cmake | 1 - Meta/CMake/lagom-install-config.cmake.in | 31 +++++++++++++++++ Meta/Lagom/CMakeLists.txt | 4 +-- Meta/Lagom/Tools/CMakeLists.txt | 4 +++ Userland/Utilities/CMakeLists.txt | 13 ++++++++ Userland/Utilities/hello-world.jakt | 3 ++ 11 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 Meta/CMake/jakt.cmake delete mode 100644 Meta/CMake/lagom-install-config.cmake create mode 100644 Meta/CMake/lagom-install-config.cmake.in create mode 100644 Userland/Utilities/hello-world.jakt diff --git a/CMakeLists.txt b/CMakeLists.txt index e5a56e08a29..96ebfbff9d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,9 @@ if (NOT HACKSTUDIO_BUILD) # Host tools, required to generate files for the build find_package(Lagom CONFIG REQUIRED) + if (TARGET Lagom::jakt) + set(ENABLE_JAKT ON) + endif() endif() diff --git a/Documentation/AdvancedBuildInstructions.md b/Documentation/AdvancedBuildInstructions.md index 8c112604f41..94c7199429c 100644 --- a/Documentation/AdvancedBuildInstructions.md +++ b/Documentation/AdvancedBuildInstructions.md @@ -59,6 +59,8 @@ There are some optional features that can be enabled during compilation that are - `BUILD_LAGOM`: builds [Lagom](../Meta/Lagom/ReadMe.md), which makes various SerenityOS libraries and programs available on the host system. - `ENABLE_KERNEL_LTO`: builds the kernel with link-time optimization. - `ENABLE_MOLD_LINKER`: builds the userland with the [`mold` linker](https://github.com/rui314/mold). `mold` can be built by running `Toolchain/BuildMold.sh`. +- `ENABLE_JAKT`: builds the `jakt` compiler as a Lagom host tool and enables building applications and libraries that are written in the jakt language. +- `JAKT_SOURCE_DIR`: `jakt` developer's local checkout of the jakt programming language for rapid testing. To use a local checkout, set to an absolute path when changing the CMake cache of Lagom. e.g. ``cmake -S Meta/Lagom -B Build/lagom -DENABLE_JAKT=ON -DJAKT_SOURCE_DIR=/home/me/jakt`` - `INCLUDE_WASM_SPEC_TESTS`: downloads and includes the WebAssembly spec testsuite tests. In order to use this option, you will need to install `prettier` and `wabt`. wabt version 1.0.23 or higher is required to pre-process the WebAssembly spec testsuite. - `SERENITY_TOOLCHAIN`: Specifies whether to use the established GNU toolchain, or the experimental Clang-based toolchain for building SerenityOS. See the [Clang-based toolchain](#clang-based-toolchain) section below. - `SERENITY_ARCH`: Specifies which architecture to build for. Currently supported options are `i686` and `x86_64`. `x86_64` requires a separate toolchain build from `i686`. diff --git a/Meta/CMake/code_generators.cmake b/Meta/CMake/code_generators.cmake index 0baf6fd1171..90340fdbae9 100644 --- a/Meta/CMake/code_generators.cmake +++ b/Meta/CMake/code_generators.cmake @@ -62,3 +62,25 @@ function(generate_state_machine source header) add_dependencies(all_generated ${target_name}) endif() endfunction() + +function(compile_jakt source) + set(source ${CMAKE_CURRENT_SOURCE_DIR}/${source}) + get_filename_component(source_base ${source} NAME_WE) + set(output "${source_base}.cpp") + add_custom_command( + OUTPUT ${output} + COMMAND $ -o "${CMAKE_CURRENT_BINARY_DIR}/jakt_tmp" ${source} + COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/jakt_tmp/${output}" ${output} + COMMAND "${CMAKE_COMMAND}" -E remove "${CMAKE_CURRENT_BINARY_DIR}/jakt_tmp/${output}" + VERBATIM + DEPENDS Lagom::jakt + MAIN_DEPENDENCY ${source} + ) + get_property(JAKT_INCLUDE_DIR TARGET Lagom::jakt PROPERTY IMPORTED_INCLUDE_DIRECTORIES) + set_source_files_properties("${output}" PROPERTIES + INCLUDE_DIRECTORIES "${JAKT_INCLUDE_DIR};${JAKT_INCLUDE_DIR}/runtime" + COMPILE_FLAGS "-Wno-unused-local-typedefs") + get_filename_component(output_name ${output} NAME) + add_custom_target(generate_${output_name} DEPENDS ${output}) + add_dependencies(all_generated generate_${output_name}) +endfunction() diff --git a/Meta/CMake/common_options.cmake b/Meta/CMake/common_options.cmake index eb516be7fc9..da879ffaed3 100644 --- a/Meta/CMake/common_options.cmake +++ b/Meta/CMake/common_options.cmake @@ -14,3 +14,6 @@ serenity_option(ENABLE_UNICODE_DATABASE_DOWNLOAD ON CACHE BOOL "Enable download serenity_option(INCLUDE_WASM_SPEC_TESTS OFF CACHE BOOL "Download and include the WebAssembly spec testsuite") 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") diff --git a/Meta/CMake/jakt.cmake b/Meta/CMake/jakt.cmake new file mode 100644 index 00000000000..cbbefd5ea88 --- /dev/null +++ b/Meta/CMake/jakt.cmake @@ -0,0 +1,39 @@ +# +# Builds the jakt bootstrap compiler as a host tool for Lagom to compile files written in jakt +# + +include(FetchContent) + +FetchContent_Declare( + Corrosion + GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git + GIT_TAG v0.2.1 +) + +FetchContent_MakeAvailable(Corrosion) + +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}") +endif() + +FetchContent_GetProperties(jakt) +if (NOT jakt_POPULATED) + FetchContent_Populate(jakt) + corrosion_import_crate(MANIFEST_PATH "${jakt_SOURCE_DIR}/Cargo.toml") + corrosion_set_hostbuild(jakt) + add_executable(Lagom::jakt ALIAS jakt) + corrosion_install(TARGETS jakt RUNTIME COMPONENT Lagom_Runtime) + # NOTE: See lagom-install-config.cmake for hax required to get Lagom::jakt to show up on install + install(DIRECTORY "${jakt_SOURCE_DIR}/runtime" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/jakt + FILES_MATCHING PATTERN "*.h" + PATTERN "*.cpp") +endif() diff --git a/Meta/CMake/lagom-install-config.cmake b/Meta/CMake/lagom-install-config.cmake deleted file mode 100644 index 2805685ec69..00000000000 --- a/Meta/CMake/lagom-install-config.cmake +++ /dev/null @@ -1 +0,0 @@ -include("${CMAKE_CURRENT_LIST_DIR}/LagomTargets.cmake") diff --git a/Meta/CMake/lagom-install-config.cmake.in b/Meta/CMake/lagom-install-config.cmake.in new file mode 100644 index 00000000000..8842161ca9b --- /dev/null +++ b/Meta/CMake/lagom-install-config.cmake.in @@ -0,0 +1,31 @@ +include("${CMAKE_CURRENT_LIST_DIR}/LagomTargets.cmake") + +if (@ENABLE_JAKT@) + # FIXME: corrosion does not support corrosion_install(TARGETS ... EXPORT ) + # Instead, hack up the magic sauce using the imported location of IPCCompiler + + # Create imported target Lagom::jakt + add_executable(Lagom::jakt IMPORTED) + + # Figure out where the binary directory of the install tree is + get_property(_IMPORTED_BINDIR + TARGET Lagom::IPCCompiler + PROPERTY LOCATION + ) + get_filename_component(_IMPORTED_BINDIR "${_IMPORTED_BINDIR}" DIRECTORY) + get_filename_component(_IMPORTED_INCLUDEDIR "${_IMPORTED_BINDIR}" DIRECTORY) + set(_IMPORTED_INCLUDEDIR "${_IMPORTED_INCLUDEDIR}/include") + + # Set the imported location of the tool + set_target_properties(Lagom::jakt PROPERTIES + IMPORTED_LOCATION "${_IMPORTED_BINDIR}/jakt" + IMPORTED_INCLUDE_DIRECTORIES "${_IMPORTED_INCLUDEDIR}/jakt" + ) + + if (NOT EXISTS "${_IMPORTED_BINDIR}/jakt") + message(FATAL_ERROR "The imported target \"jakt\" references the file \"${_IMPORTED_BINDIR}/jakt\" but this file does not exist.") + endif() + + unset(_IMPORTED_BINDIR) + unset(_IMPORTED_INCLUDEDIR) +endif() diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index f514b34e7c8..d45c8107033 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -147,10 +147,10 @@ set(Lagom_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/${package}" CACHE PATH "CMake package config location relative to the install prefix") mark_as_advanced(Lagom_INSTALL_CMAKEDIR) +configure_file("${SERENITY_PROJECT_ROOT}/Meta/CMake/lagom-install-config.cmake.in" "${package}Config.cmake" @ONLY) install( - FILES "${SERENITY_PROJECT_ROOT}/Meta/CMake/lagom-install-config.cmake" + FILES "${CMAKE_CURRENT_BINARY_DIR}/${package}Config.cmake" DESTINATION "${Lagom_INSTALL_CMAKEDIR}" - RENAME "${package}Config.cmake" COMPONENT Lagom_Development ) diff --git a/Meta/Lagom/Tools/CMakeLists.txt b/Meta/Lagom/Tools/CMakeLists.txt index 354734c3f10..088e0aaaa53 100644 --- a/Meta/Lagom/Tools/CMakeLists.txt +++ b/Meta/Lagom/Tools/CMakeLists.txt @@ -14,3 +14,7 @@ endfunction() add_subdirectory(CodeGenerators) add_subdirectory(ConfigureComponents) add_subdirectory(IPCMagicLinter) + +if (ENABLE_JAKT) + include(jakt) +endif() diff --git a/Userland/Utilities/CMakeLists.txt b/Userland/Utilities/CMakeLists.txt index a857f878569..593aa5741b6 100644 --- a/Userland/Utilities/CMakeLists.txt +++ b/Userland/Utilities/CMakeLists.txt @@ -51,6 +51,19 @@ foreach(CMD_SRC ${CMD_SOURCES}) endif() endforeach() +if (ENABLE_JAKT) + add_executable(hello-jakt hello-world.cpp) + compile_jakt(hello-world.jakt) + target_link_libraries(hello-jakt 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/rgrep SYMBOLIC)") diff --git a/Userland/Utilities/hello-world.jakt b/Userland/Utilities/hello-world.jakt new file mode 100644 index 00000000000..f020e37a3b3 --- /dev/null +++ b/Userland/Utilities/hello-world.jakt @@ -0,0 +1,3 @@ +function main() { + println("Hello, World, from jakt!"); +}