diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -110,6 +110,24 @@ list(APPEND TARGET_ENTRYPOINT_NAME_LIST ${entrypoint_name}) endforeach() +# External entrypoints are only included in TARGET_ENTRYPOINT_NAME_LIST, +# not TARGET_LLVMLIBC_ENTRYPOINTS. +# TARGET_ENTRYPOINT_NAME_LIST just defines which function prototypes are +# included in the generated headers, while TARGET_LLVMLIBC_ENTRYPOINTS is used +# for determining which functions will be built. +if(TARGET_LIBC_EXTERNAL_ENTRYPOINTS) + foreach(entrypoint IN LISTS TARGET_LIBC_EXTERNAL_ENTRYPOINTS) + string(FIND ${entrypoint} "." last_dot_loc REVERSE) + if(${last_dot_loc} EQUAL -1) + message(FATAL "Invalid entrypoint target name ${entrypoint}; Expected a '.' " + "(dot) in the name.") + endif() + math(EXPR name_loc "${last_dot_loc} + 1") + string(SUBSTRING ${entrypoint} ${name_loc} -1 entrypoint_name) + list(APPEND TARGET_ENTRYPOINT_NAME_LIST ${entrypoint_name}) + endforeach() +endif() + if(LLVM_LIBC_FULL_BUILD) # We need to set up hdrgen first since other targets depend on it. add_subdirectory(utils/LibcTableGenUtil) diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake --- a/libc/cmake/modules/LLVMLibCObjectRules.cmake +++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake @@ -258,6 +258,29 @@ endfunction(add_entrypoint_object) +# A rule for external entrypoint targets. +# Usage: +# add_entrypoint_external( +# +# ) +function(add_entrypoint_external target_name) + + get_fq_target_name(${target_name} fq_target_name) + set(entrypoint_name ${target_name}) + + add_custom_target(${fq_target_name}) + set_target_properties( + ${fq_target_name} + PROPERTIES + "ENTRYPOINT_NAME" ${entrypoint_name} + "TARGET_TYPE" ${ENTRYPOINT_OBJ_TARGET_TYPE} + "OBJECT_FILE" "" + "OBJECT_FILE_RAW" "" + "DEPS" "" + ) + +endfunction(add_entrypoint_external) + # Rule build a redirector object file. function(add_redirector_object target_name) cmake_parse_arguments( diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -228,6 +228,14 @@ ) endif() +set(TARGET_LIBC_EXTERNAL_ENTRYPOINTS + # stdlib.h external entrypoints + libc.src.stdlib.malloc + libc.src.stdlib.calloc + libc.src.stdlib.realloc + libc.src.stdlib.free +) + set(TARGET_LLVMLIBC_ENTRYPOINTS ${TARGET_LIBC_ENTRYPOINTS} ${TARGET_LIBM_ENTRYPOINTS} diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -513,6 +513,11 @@ FunctionSpec<"strtoul", RetValSpec, [ArgSpec, ArgSpec, ArgSpec]>, FunctionSpec<"strtoull", RetValSpec, [ArgSpec, ArgSpec, ArgSpec]>, + FunctionSpec<"malloc", RetValSpec, [ArgSpec]>, + FunctionSpec<"calloc", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"realloc", RetValSpec, [ArgSpec, ArgSpec]>, + FunctionSpec<"free", RetValSpec, [ArgSpec]>, + FunctionSpec<"_Exit", RetValSpec, [ArgSpec]>, ] >; diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -181,6 +181,19 @@ libc.include.stdlib ) +add_entrypoint_external( + malloc +) +add_entrypoint_external( + calloc +) +add_entrypoint_external( + realloc +) +add_entrypoint_external( + free +) + if(NOT LLVM_LIBC_FULL_BUILD) return() endif()