[libc-commits] [libc] [libc] Add base for target config within cmake (PR #72318)

via libc-commits libc-commits at lists.llvm.org
Thu Nov 16 14:35:46 PST 2023


https://github.com/michaelrj-google updated https://github.com/llvm/llvm-project/pull/72318

>From f89b89f843bdc862227f2a39ff7a0beb61f43f03 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Tue, 14 Nov 2023 14:11:42 -0800
Subject: [PATCH 1/4] [libc] Add base for target config within cmake

Currently the only way to add or remove entrypoints is to modify the
entrypoints.txt file for the current target. This isn't ideal since
a user would have to carry a diff for this file when updating their
checkout. This patch adds a basic mechanism to allow the user to remove
entrypoints without modifying the repository.
---
 libc/CMakeLists.txt        | 21 +++++++++++++++++++++
 libc/config/CMakeLists.txt |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 414be906336bf3f..922209eee8e2edd 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -103,6 +103,8 @@ option(LLVM_LIBC_ENABLE_LINTING "Enables linting of libc source files" OFF)
 option(LIBC_GPU_BUILD "Build libc for the GPU. All CPU build options will be ignored." OFF)
 set(LIBC_TARGET_TRIPLE "" CACHE STRING "The target triple for the libc build.")
 
+option(LIBC_SYSTEM_CONFIG_FILE "The path to user provided cmake file that configures the build for the target system." OFF)
+
 set(LIBC_ENABLE_UNITTESTS ON)
 set(LIBC_ENABLE_HERMETIC_TESTS ${LLVM_LIBC_FULL_BUILD})
 
@@ -262,6 +264,25 @@ elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
   include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
 endif()
 
+if(LIBC_SYSTEM_CONFIG_FILE)
+  if(EXISTS "${LIBC_SYSTEM_CONFIG_FILE}")
+    include("${LIBC_SYSTEM_CONFIG_FILE}")
+  else()
+    message(FATAL_ERROR "System Config File set to unavailable file '${LIBC_SYSTEM_CONFIG_FILE}'")
+  endif()
+
+  #TODO: Set up support for premade configs.
+
+  foreach(removed_entrypoint IN LISTS TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS)
+    if(LIBC_CMAKE_VERBOSE_LOGGING)
+      message(STATUS "Removing entrypoint ${removed_entrypoint}")
+    endif()
+    list(REMOVE_ITEM TARGET_LLVMLIBC_ENTRYPOINTS ${removed_entrypoint})
+    list(REMOVE_ITEM TARGET_LIBC_ENTRYPOINTS ${removed_entrypoint})
+    list(REMOVE_ITEM TARGET_LIBM_ENTRYPOINTS ${removed_entrypoint})
+  endforeach()
+endif()
+
 set(TARGET_ENTRYPOINT_NAME_LIST "")
 foreach(entrypoint IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
   string(FIND ${entrypoint} "." last_dot_loc REVERSE)
diff --git a/libc/config/CMakeLists.txt b/libc/config/CMakeLists.txt
index a1034f9954740fe..853854b03be4e4e 100644
--- a/libc/config/CMakeLists.txt
+++ b/libc/config/CMakeLists.txt
@@ -1 +1,3 @@
+#TODO: Properly select the correct subdirectory.
+
 add_subdirectory(linux)

>From a00fc84a0f366c8b77cd62d573ed15931afa4ff6 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Tue, 14 Nov 2023 14:44:54 -0800
Subject: [PATCH 2/4] Move to completely overwrite the entrypoints path

Instead of having a user-provided file that modifies the list of
entrypoints, now the user-provided file is used instead of the list of
entrypoints.
---
 libc/CMakeLists.txt | 53 ++++++++++++++++++++++++---------------------
 1 file changed, 28 insertions(+), 25 deletions(-)

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 922209eee8e2edd..4460820d86973b3 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -249,40 +249,43 @@ include(CMakeParseArguments)
 include(LLVMLibCCheckCpuFeatures)
 include(LLVMLibCRules)
 
-if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/entrypoints.txt")
-  set(entrypoint_file "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/entrypoints.txt")
-elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/entrypoints.txt")
-  set(entrypoint_file "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/entrypoints.txt")
-else()
-  message(FATAL_ERROR "entrypoints.txt file for the target platform '${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}' not found.")
-endif()
-include(${entrypoint_file})
-
-if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/headers.txt")
-  include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/headers.txt")
-elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
-  include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
-endif()
-
+# If the user wants to provide their own list of entrypoints and headers
 if(LIBC_SYSTEM_CONFIG_FILE)
+  # Use the file provided by the user if it exists
   if(EXISTS "${LIBC_SYSTEM_CONFIG_FILE}")
     include("${LIBC_SYSTEM_CONFIG_FILE}")
   else()
     message(FATAL_ERROR "System Config File set to unavailable file '${LIBC_SYSTEM_CONFIG_FILE}'")
   endif()
+else()
+  # Else use the files in config/OS/CPU/ or config/OS/
+  if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/entrypoints.txt")
+    set(entrypoint_file "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/entrypoints.txt")
+  elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/entrypoints.txt")
+    set(entrypoint_file "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/entrypoints.txt")
+  else()
+    message(FATAL_ERROR "entrypoints.txt file for the target platform '${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}' not found.")
+  endif()
+  include(${entrypoint_file})
 
-  #TODO: Set up support for premade configs.
-
-  foreach(removed_entrypoint IN LISTS TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS)
-    if(LIBC_CMAKE_VERBOSE_LOGGING)
-      message(STATUS "Removing entrypoint ${removed_entrypoint}")
-    endif()
-    list(REMOVE_ITEM TARGET_LLVMLIBC_ENTRYPOINTS ${removed_entrypoint})
-    list(REMOVE_ITEM TARGET_LIBC_ENTRYPOINTS ${removed_entrypoint})
-    list(REMOVE_ITEM TARGET_LIBM_ENTRYPOINTS ${removed_entrypoint})
-  endforeach()
+  if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/headers.txt")
+    include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/headers.txt")
+  elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
+    include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
+  endif()
 endif()
 
+# #TODO: Set up support for premade configs.
+
+# foreach(removed_entrypoint IN LISTS TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS)
+#   if(LIBC_CMAKE_VERBOSE_LOGGING)
+#     message(STATUS "Removing entrypoint ${removed_entrypoint}")
+#   endif()
+#   list(REMOVE_ITEM TARGET_LLVMLIBC_ENTRYPOINTS ${removed_entrypoint})
+#   list(REMOVE_ITEM TARGET_LIBC_ENTRYPOINTS ${removed_entrypoint})
+#   list(REMOVE_ITEM TARGET_LIBM_ENTRYPOINTS ${removed_entrypoint})
+# endforeach()
+
 set(TARGET_ENTRYPOINT_NAME_LIST "")
 foreach(entrypoint IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
   string(FIND ${entrypoint} "." last_dot_loc REVERSE)

>From a910f4e5f006541bb1a7c6b136e47f3c9cb77366 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Wed, 15 Nov 2023 14:19:23 -0800
Subject: [PATCH 3/4] Redesign to support providing a config folder

Instead of the user only providing one file, they now provide a file
with entrypoints, headers, and the new exclude file. It also now
supports them providing their own config.json and properly uses it
instead of the provided ones for the given target.
---
 libc/CMakeLists.txt                  | 99 ++++++++++++++++++----------
 libc/config/linux/x86_64/exclude.txt | 16 +++++
 2 files changed, 81 insertions(+), 34 deletions(-)
 create mode 100644 libc/config/linux/x86_64/exclude.txt

diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
index 4460820d86973b3..3c6a2da7e635577 100644
--- a/libc/CMakeLists.txt
+++ b/libc/CMakeLists.txt
@@ -103,7 +103,7 @@ option(LLVM_LIBC_ENABLE_LINTING "Enables linting of libc source files" OFF)
 option(LIBC_GPU_BUILD "Build libc for the GPU. All CPU build options will be ignored." OFF)
 set(LIBC_TARGET_TRIPLE "" CACHE STRING "The target triple for the libc build.")
 
-option(LIBC_SYSTEM_CONFIG_FILE "The path to user provided cmake file that configures the build for the target system." OFF)
+option(LIBC_CONFIG_PATH "The path to user provided folder that configures the build for the target system." OFF)
 
 set(LIBC_ENABLE_UNITTESTS ON)
 set(LIBC_ENABLE_HERMETIC_TESTS ${LLVM_LIBC_FULL_BUILD})
@@ -111,6 +111,33 @@ set(LIBC_ENABLE_HERMETIC_TESTS ${LLVM_LIBC_FULL_BUILD})
 # Defines LIBC_TARGET_ARCHITECTURE and associated macros.
 include(LLVMLibCArchitectures)
 
+set(LIBC_CONFIG_JSON_FILE_LIST "")
+
+if(NOT LIBC_CONFIG_PATH)
+  list(APPEND LIBC_CONFIG_JSON_FILE_LIST "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}")
+  if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}")
+    list(APPEND LIBC_CONFIG_JSON_FILE_LIST "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}")
+    set(LIBC_CONFIG_PATH "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}")
+  elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}")
+    set(LIBC_CONFIG_PATH "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}")
+  endif()
+else()
+  list(APPEND LIBC_CONFIG_JSON_FILE_LIST "${LIBC_CONFIG_PATH}")
+endif()
+
+if(NOT LIBC_CONFIG_PATH)
+  message(FATAL_ERROR "Configs for the platform '${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}' do not exist and LIBC_CONFIG_PATH is not set.")
+elseif(LIBC_CMAKE_VERBOSE_LOGGING)
+  message(STATUS "Path for config files is: ${LIBC_CONFIG_PATH}")
+endif()
+
+# option(LIBC_ENABLE_WIDE_CHARACTERS 
+# "Whether to enable wide character functions on supported platforms. This may
+# also set flags to enable or disable wide character support within other
+# functions (e.g. printf)." ON)
+
+#TODO: Add carve-out specific config files to the list here.
+
 include(LibcConfig)
 # Config loading happens in three steps:
 # 1. Load the config file config/config.json and set up config vars.
@@ -149,8 +176,14 @@ foreach(opt IN LISTS global_config)
   set(${opt_name} ${opt_value})
 endforeach()
 generate_config_doc(${main_config_file} ${LIBC_SOURCE_DIR}/docs/configure.rst)
-load_libc_config(${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/config.json ${cmd_line_conf})
-load_libc_config(${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/config.json ${cmd_line_conf})
+
+# Load each target specific config.
+foreach(config_path IN LISTS LIBC_CONFIG_JSON_FILE_LIST)
+  if(LIBC_CMAKE_VERBOSE_LOGGING)
+    message(STATUS "Loading additional config: '${config_path}/config.json'")
+  endif()
+  load_libc_config(${config_path}/config.json ${cmd_line_conf})
+endforeach()
 
 if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
   set(LIBC_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include)
@@ -249,42 +282,40 @@ include(CMakeParseArguments)
 include(LLVMLibCCheckCpuFeatures)
 include(LLVMLibCRules)
 
-# If the user wants to provide their own list of entrypoints and headers
-if(LIBC_SYSTEM_CONFIG_FILE)
-  # Use the file provided by the user if it exists
-  if(EXISTS "${LIBC_SYSTEM_CONFIG_FILE}")
-    include("${LIBC_SYSTEM_CONFIG_FILE}")
-  else()
-    message(FATAL_ERROR "System Config File set to unavailable file '${LIBC_SYSTEM_CONFIG_FILE}'")
-  endif()
+set(TARGET_LLVMLIBC_ENTRYPOINTS "")
+set(TARGET_LIBC_ENTRYPOINTS "")
+set(TARGET_LIBM_ENTRYPOINTS "")
+set(TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS "")
+
+# Check entrypoints.txt
+if(EXISTS "${LIBC_CONFIG_PATH}/entrypoints.txt")
+    include("${LIBC_CONFIG_PATH}/entrypoints.txt")
 else()
-  # Else use the files in config/OS/CPU/ or config/OS/
-  if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/entrypoints.txt")
-    set(entrypoint_file "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/entrypoints.txt")
-  elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/entrypoints.txt")
-    set(entrypoint_file "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/entrypoints.txt")
-  else()
-    message(FATAL_ERROR "entrypoints.txt file for the target platform '${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}' not found.")
-  endif()
-  include(${entrypoint_file})
+  message(FATAL_ERROR "${LIBC_CONFIG_PATH}/entrypoints.txt file not found.")
+endif()
 
-  if(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/headers.txt")
-    include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_ARCHITECTURE}/headers.txt")
-  elseif(EXISTS "${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
-    include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/headers.txt")
-  endif()
+# Check headers.txt
+if(EXISTS "${LIBC_CONFIG_PATH}/headers.txt")
+    include("${LIBC_CONFIG_PATH}/headers.txt")
+elseif(LLVM_LIBC_FULL_BUILD)
+  message(FATAL_ERROR "${LIBC_CONFIG_PATH}/headers.txt file not found and fullbuild requested.")
+endif()
+
+# Check exclude.txt that appends to LIBC_EXCLUDE_ENTRYPOINTS list
+if(EXISTS "${LIBC_CONFIG_PATH}/exclude.txt")
+    include("${LIBC_CONFIG_PATH}/exclude.txt")
 endif()
 
-# #TODO: Set up support for premade configs.
+# #TODO: Set up support for premade configs adding their own exclude lists.
 
-# foreach(removed_entrypoint IN LISTS TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS)
-#   if(LIBC_CMAKE_VERBOSE_LOGGING)
-#     message(STATUS "Removing entrypoint ${removed_entrypoint}")
-#   endif()
-#   list(REMOVE_ITEM TARGET_LLVMLIBC_ENTRYPOINTS ${removed_entrypoint})
-#   list(REMOVE_ITEM TARGET_LIBC_ENTRYPOINTS ${removed_entrypoint})
-#   list(REMOVE_ITEM TARGET_LIBM_ENTRYPOINTS ${removed_entrypoint})
-# endforeach()
+foreach(removed_entrypoint IN LISTS TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS)
+  if(LIBC_CMAKE_VERBOSE_LOGGING)
+    message(STATUS "Removing entrypoint ${removed_entrypoint}")
+  endif()
+  list(REMOVE_ITEM TARGET_LLVMLIBC_ENTRYPOINTS ${removed_entrypoint})
+  list(REMOVE_ITEM TARGET_LIBC_ENTRYPOINTS ${removed_entrypoint})
+  list(REMOVE_ITEM TARGET_LIBM_ENTRYPOINTS ${removed_entrypoint})
+endforeach()
 
 set(TARGET_ENTRYPOINT_NAME_LIST "")
 foreach(entrypoint IN LISTS TARGET_LLVMLIBC_ENTRYPOINTS)
diff --git a/libc/config/linux/x86_64/exclude.txt b/libc/config/linux/x86_64/exclude.txt
new file mode 100644
index 000000000000000..c8543046f270814
--- /dev/null
+++ b/libc/config/linux/x86_64/exclude.txt
@@ -0,0 +1,16 @@
+# This optional file is used to exclude entrypoints/headers for specific targets.
+
+try_compile(
+  has_sys_random
+  ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${LIBC_SOURCE_DIR}/src/sys/random/linux/getrandom.cpp
+)
+
+# If sys/random isn't available, then this is likely Ubuntu 14, which also
+# doesn't support the syscall we use for sys/stat.
+if(NOT has_sys_random)
+  list(APPEND TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS 
+    libc.src.sys.random.getrandom
+    libc.src.sys.stat.stat
+  )
+endif()

>From 439d7be3a1b8f3c7375f5e766b410cc81fbe8651 Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Thu, 16 Nov 2023 14:34:55 -0800
Subject: [PATCH 4/4] Properly set up exclude.txt

I had to add a new folder for files to use try_compile on.
---
 .../modules/system_features/check_sys_random.cpp    |  1 +
 libc/config/linux/x86_64/exclude.txt                | 13 +++++++++----
 2 files changed, 10 insertions(+), 4 deletions(-)
 create mode 100644 libc/cmake/modules/system_features/check_sys_random.cpp

diff --git a/libc/cmake/modules/system_features/check_sys_random.cpp b/libc/cmake/modules/system_features/check_sys_random.cpp
new file mode 100644
index 000000000000000..7ab1949f0858d19
--- /dev/null
+++ b/libc/cmake/modules/system_features/check_sys_random.cpp
@@ -0,0 +1 @@
+#include <sys/random.h>
diff --git a/libc/config/linux/x86_64/exclude.txt b/libc/config/linux/x86_64/exclude.txt
index c8543046f270814..efe3eb9f4671b7e 100644
--- a/libc/config/linux/x86_64/exclude.txt
+++ b/libc/config/linux/x86_64/exclude.txt
@@ -1,16 +1,21 @@
 # This optional file is used to exclude entrypoints/headers for specific targets.
 
+# Check if sys/random.h is available. If it isn't that implies we're on an older
+# version of linux, so we probably also don't have the statx syscall.
 try_compile(
   has_sys_random
   ${CMAKE_CURRENT_BINARY_DIR}
-  SOURCES ${LIBC_SOURCE_DIR}/src/sys/random/linux/getrandom.cpp
+  SOURCES ${LIBC_SOURCE_DIR}/cmake/modules/system_features/check_sys_random.cpp
 )
 
-# If sys/random isn't available, then this is likely Ubuntu 14, which also
-# doesn't support the syscall we use for sys/stat.
 if(NOT has_sys_random)
   list(APPEND TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS 
-    libc.src.sys.random.getrandom
     libc.src.sys.stat.stat
   )
+  # If we're doing a fullbuild we provide the random header ourselves.
+  if(NOT LLVM_LIBC_FULL_BUILD)
+    list(APPEND TARGET_LLVMLIBC_REMOVED_ENTRYPOINTS 
+      libc.src.sys.random.getrandom
+    )
+  endif()
 endif()



More information about the libc-commits mailing list