Skip to content

Meta: Pass compiler's builtin includes to jakt too #25573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions Meta/CMake/get_cxx_includes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import argparse
import os
import subprocess
import sys


def get_includes_from_version_output(compiler, target_args):
try:
output = subprocess.check_output(
[compiler, *target_args, "-xc++", "/dev/null", "-E", "-Wp,-v"], stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as e:
print("Error getting includes from compiler version output: " + e.output)
sys.exit(1)

includes = []
in_search_list = False
for line in output.splitlines():
line = line.strip()
if not in_search_list:
if line == "#include <...> search starts here:":
in_search_list = True
continue
continue
if line == "End of search list.":
break
includes.append(line)

return includes


def get_includes_from_preprocessor_output(compiler, test_file, target_args):
try:
output = subprocess.check_output(
[compiler, *target_args, "-E", test_file], stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as e:
print(b"Error getting includes from preprocessor output: " + e.output)
sys.exit(1)

includes = []
for line in output.splitlines():
if not line.startswith(b"# 1 "):
continue
include = line.removeprefix(b"# 1 ")
include = include[1:-1] # Remove quotes
includes.append(include)

return includes


def convert_includes_to_dirs(includes):
dirs = []
for include in includes:
if not os.path.isabs(include):
continue
include_dir = os.path.dirname(include)
if include_dir.endswith(b"/bits"):
include_dir = os.path.dirname(include_dir)

while not os.path.isdir(include_dir):
include_dir = os.path.dirname(include_dir)

if os.path.basename(include_dir).startswith(b"_"):
continue

dirs.append(include_dir)

return dirs


def main():
parser = argparse.ArgumentParser(
description="Extract System Includes from C++ Compiler"
)

parser.add_argument("--compiler", required=True, help="Specify C++ compiler to extract includes from")
parser.add_argument("--target", help="Specify target platform for compiler")

parser.add_argument(
"--test-file", required=True, help="Specify the path to the test file containing '#include' directives"
)

args = parser.parse_args()
compiler = args.compiler
test_file = args.test_file
target = args.target

target_args = []
if target is not None and target != "":
target_args = [f"--target={target}"]

includes = get_includes_from_version_output(compiler, target_args)
system_includes = get_includes_from_preprocessor_output(compiler, test_file, target_args)
system_includes = convert_includes_to_dirs(system_includes)

out = []
seen = set()
for p in system_includes + includes:
if p in seen:
continue
seen.add(p)
out.append(p.decode("utf-8"))

print(";".join(out), end="")


if __name__ == "__main__":
main()
27 changes: 27 additions & 0 deletions Meta/CMake/jakt.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ if (NOT ENABLE_JAKT)
return()
endif()

find_package(Python COMPONENTS Interpreter REQUIRED)
file(WRITE ${CMAKE_BINARY_DIR}/jakt_test.cpp "#include <new>")
execute_process(
COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/get_cxx_includes.py
--compiler ${CMAKE_CXX_COMPILER}
--test-file "${CMAKE_BINARY_DIR}/jakt_test.cpp"
--target "${CMAKE_CXX_COMPILER_TARGET}"
OUTPUT_VARIABLE CXX_SYSTEM_INCLUDES_CLEAN
)

# Remove duplicates
list(REMOVE_DUPLICATES CXX_SYSTEM_INCLUDES_CLEAN)

cmake_host_system_information(RESULT JAKT_PROCESSOR_COUNT QUERY NUMBER_OF_PHYSICAL_CORES)
set_property(GLOBAL PROPERTY JOB_POOLS jakt_pool=1)

Expand All @@ -98,6 +111,12 @@ function(add_jakt_executable target source)
foreach(config IN LISTS JAKT_EXECUTABLE_CONFIGS)
list(APPEND configs "--config" "${config}")
endforeach()
foreach(include IN LISTS CXX_COMPILER_INCLUDES)
list(APPEND includes "-I" "${include}")
endforeach()
foreach(include IN LISTS CXX_SYSTEM_INCLUDES_CLEAN)
list(APPEND includes "--extra-cpp-flag-isystem${include}")
endforeach()
foreach(include IN LISTS JAKT_EXECUTABLE_INCLUDES)
list(APPEND includes "-I" "${include}")
endforeach()
Expand All @@ -123,6 +142,12 @@ function(add_jakt_executable target source)

set(extra_cpp_flags "--extra-cpp-flag-std=c++2b") # FIXME: CMake should be setting this, but sometimes (e.g. macOS /usr/bin/c++ for lagom) it doesn't;
# Passing it here allows us to build on AppleClang 15, and if CMake starts setting it, it will be overridden by later flags.

if (os STREQUAL "serenity")
list(APPEND extra_cpp_flags "--extra-cpp-flag-D__serenity__")
list(APPEND extra_cpp_flags "--extra-cpp-flag-D__unix")
list(APPEND extra_cpp_flags "--extra-cpp-flag-D__unix__")
endif()
foreach(flag IN LISTS compile_flags)
list(APPEND extra_cpp_flags "--extra-cpp-flag${flag}")
endforeach()
Expand Down Expand Up @@ -198,6 +223,7 @@ function(serenity_jakt_app target_name source)
${PROJECT_BINARY_DIR}/Userland/Services
${PROJECT_BINARY_DIR}/Userland/Libraries
${PROJECT_BINARY_DIR}/Userland
${CMAKE_SYSROOT}/usr/include
${SERENITY_JAKT_EXECUTABLE_INCLUDES}
CONFIGS ${SERENITY_JAKT_EXECUTABLE_CONFIGS}
LINK_LIBRARIES ${SERENITY_JAKT_EXECUTABLE_LINK_LIBRARIES}
Expand All @@ -223,6 +249,7 @@ function(serenity_jakt_executable target_name)
${PROJECT_BINARY_DIR}/Userland/Services
${PROJECT_BINARY_DIR}/Userland/Libraries
${PROJECT_BINARY_DIR}/Userland
${CMAKE_SYSROOT}/usr/include
${SERENITY_JAKT_EXECUTABLE_INCLUDES}
CONFIGS ${SERENITY_JAKT_EXECUTABLE_CONFIGS}
LINK_LIBRARIES ${SERENITY_JAKT_EXECUTABLE_LINK_LIBRARIES}
Expand Down
2 changes: 1 addition & 1 deletion Toolchain/BuildJakt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ buildstep_ninja() {

mkdir -p "$DIR/Tarballs"

JAKT_COMMIT_HASH="1fed928d0abf08188e48fe765ab68e5047c05ec2"
JAKT_COMMIT_HASH="bf6e9ce89206fb744d8acc6e700e31e4330a5f25"
JAKT_NAME="jakt-${JAKT_COMMIT_HASH}"
JAKT_TARBALL="${JAKT_NAME}.tar.gz"
JAKT_GIT_URL="https://github.com/serenityos/jakt"
Expand Down
Loading