Skip to content

Commit

Permalink
Add CMake build system
Browse files Browse the repository at this point in the history
  • Loading branch information
loganek committed Sep 30, 2022
1 parent f2a618f commit f9d135e
Show file tree
Hide file tree
Showing 17 changed files with 1,072 additions and 0 deletions.
32 changes: 32 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.16.3)

project(wasi-libc LANGUAGES C)

enable_testing()

if("${CMAKE_C_COMPILER}" MATCHES "(.*)clang(-[0-9]+)?$")
set(CMAKE_NM "${CMAKE_MATCH_1}llvm-nm${CMAKE_MATCH_2}")
endif()

find_package(Python COMPONENTS Interpreter REQUIRED)

set(TARGET_TRIPLE wasm32-wasi)
set(MULTIARCH_TRIPLE wasm32-wasi)

set(CMAKE_C_COMPILER_TARGET ${TARGET_TRIPLE} CACHE STRING "The target to compile for")

# note that pthread support is still a work-in-progress.
set(THREAD_MODEL "single" CACHE STRING "single or posix")

set(MALLOC_IMPL "dlmalloc" CACHE STRING "dlmalloc or none")

option(BUILD_LIBC_TOP_HALF "Build libc top half" ON)

# When the length is no larger than this threshold, we consider the
# overhead of bulk memory opcodes to outweigh the performance benefit,
# and fall back to the original musl implementation. See
# https://github.com/WebAssembly/wasi-libc/pull/263 for relevant
# discussion
set(BULK_MEMORY_THRESHOLD "32" CACHE STRING "bulk memory threshold")

add_subdirectory(cmake)
112 changes: 112 additions & 0 deletions cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
set(LIBC_BOTTOM_HALF_HEADERS_PUBLIC_DIR ${PROJECT_SOURCE_DIR}/libc-bottom-half/headers/public)
set(LIBC_TOP_HALF_MUSL_DIR ${PROJECT_SOURCE_DIR}/libc-top-half/musl)
set(LIBC_TOP_HALF_MUSL_SRC_DIR ${LIBC_TOP_HALF_MUSL_DIR}/src)
set(LIBC_BOTTOM_HALF_DIR ${PROJECT_SOURCE_DIR}/libc-bottom-half)
set(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_DIR ${LIBC_BOTTOM_HALF_DIR}/cloudlibc/src)

set(INSTALL_LIB_DIR lib/${MULTIARCH_TRIPLE})
set(INSTALL_SHARE_DIR share/${MULTIARCH_TRIPLE})

include(global-compiler-options.cmake)
include(local-sysroot.cmake)
include(predefined-macros.cmake)
include(libc-imports.cmake)

add_subdirectory(libc-bottom-half)
add_subdirectory(libc-top-half)

if(${MALLOC_IMPL} STREQUAL "dlmalloc")
add_subdirectory(dlmalloc)
endif()

add_library(wasi-emulated-signal)
target_link_libraries(wasi-emulated-signal
wasi-emulated-signal-musl-objs
wasi-emulated-signal-objs
)
add_custom_command(TARGET wasi-emulated-signal POST_BUILD
COMMAND ${CMAKE_C_COMPILER_AR} crs $<TARGET_FILE:c>
)

add_library(c)

set (LIBC_LINK_LIBRARIES
libc-bottom-half
)

if(${BUILD_LIBC_TOP_HALF} STREQUAL "ON")
list(APPEND LIBC_LINK_LIBRARIES
libc-top-half
)
endif()

if(${MALLOC_IMPL} STREQUAL "dlmalloc")
list(APPEND LIBC_LINK_LIBRARIES
dlmalloc)
elseif(${MALLOC_IMPL} STREQUAL "none")
# nothing to do here
else()
message(FATAL_ERROR "unknown malloc implementation ${MALLOC_IMPL}")
endif()

target_link_libraries(c
PRIVATE
${LIBC_LINK_LIBRARIES}
)

add_custom_command(TARGET c POST_BUILD
COMMAND ${CMAKE_C_COMPILER_AR} crs $<TARGET_FILE:c>
)

add_dependencies(c sysroot-headers)

# Create empty placeholder libraries.
foreach(stub m rt pthread crypt util xnet resolve dl)
set(lib_path ${SYSROOT_LIB_DIR}/lib${stub}.a)
add_custom_command(OUTPUT ${lib_path}
COMMAND ${CMAKE_COMMAND} -E make_directory ${SYSROOT_LIB_DIR}
COMMAND ${CMAKE_C_COMPILER_AR} crs ${lib_path})
add_custom_target(${stub} ALL
DEPENDS ${lib_path})
endforeach()

install(
TARGETS
c
c-printscan-long-double
c-printscan-no-floating-point
wasi-emulated-mman
wasi-emulated-process-clocks
wasi-emulated-getpid
wasi-emulated-signal
ARCHIVE DESTINATION ${INSTALL_LIB_DIR}
LIBRARY DESTINATION ${INSTALL_LIB_DIR}
)

install(
DIRECTORY ${SYSROOT_INC_DIR}
DESTINATION .
)

install(
DIRECTORY ${SYSROOT_SHARE_DIR}
DESTINATION share
)

install(
DIRECTORY ${SYSROOT_LIB_DIR}
DESTINATION lib
)

add_test(NAME check-metadata
COMMAND diff -wur
${PROJECT_SOURCE_DIR}/expected/${MULTIARCH_TRIPLE}/${THREAD_MODEL}/predefined-macros.txt
${CMAKE_BINARY_DIR}/sysroot/share/${MULTIARCH_TRIPLE}/predefined-macros.txt)

add_test(NAME check-headers
COMMAND ${CMAKE_C_COMPILER}
-target ${CMAKE_C_COMPILER_TARGET}
--sysroot=${CMAKE_BINARY_DIR}/sysroot
-fsyntax-only
"-Wno#warnings"
${CMAKE_BINARY_DIR}/sysroot/share/${MULTIARCH_TRIPLE}/include-all.c)
10 changes: 10 additions & 0 deletions cmake/dlmalloc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
set(DLMALLOC_DIR ${PROJECT_SOURCE_DIR}/dlmalloc)

add_library(dlmalloc OBJECT
${DLMALLOC_DIR}/src/dlmalloc.c)

target_include_directories(dlmalloc
PRIVATE
${DLMALLOC_DIR}/include)

add_dependencies(dlmalloc sysroot-headers)
39 changes: 39 additions & 0 deletions cmake/global-compiler-options.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# WebAssembly floating-point match doesn't trap.
# TODO: Add -fno-signaling-nans when the compiler supports it.
add_compile_options(-fno-trapping-math)

# Add all warnings, but disable a few which occur in third-party code.
add_compile_options(
-Wall -Wextra -Werror
-Wno-null-pointer-arithmetic
-Wno-unused-parameter
-Wno-sign-compare
-Wno-unused-variable
-Wno-unused-function
-Wno-ignored-attributes
-Wno-missing-braces
-Wno-ignored-pragmas
-Wno-unused-but-set-variable
-Wno-unknown-warning-option
)

# Configure support for threads
if("${THREAD_MODEL}" STREQUAL "single")
add_compile_options(-mthread-model single)
elseif("${THREAD_MODEL}" STREQUAL "posix")
add_compile_options(-mthread-model posix -pthread -ftls-model=local-exec)
endif()

# Expose the public headers to the implementation. We use `-isystem` for
# purpose for two reasons:
#
# 1. It only does `<...>` not `"...."` lookup. We are making a libc,
# which is a system library, so all public headers should be
# accessible via `<...>` and never also need `"..."`. `-isystem` main
# purpose is to only effect `<...>` lookup.
#
# 2. The `-I` for private headers added for specific C files below
# should come earlier in the search path, so they can "override"
# and/or `#include_next` the public headers. `-isystem` (like
# `-idirafter`) comes later in the search path than `-I`.
include_directories(SYSTEM ${CMAKE_BINARY_DIR}/sysroot/include)
41 changes: 41 additions & 0 deletions cmake/libc-bottom-half/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
set(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC_DIR ${LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_DIR}/include)
set(LIBC_BOTTOM_HALF_SRC_DIR ${LIBC_BOTTOM_HALF_DIR}/sources)
set(LIBC_BOTTOM_HALF_HEADERS_PRIVATE_DIR ${LIBC_BOTTOM_HALF_DIR}/headers/private)

file(GLOB_RECURSE
LIBC_BOTTOM_HALF_ALL_SOURCES
CONFIGURE_DEPENDS
${LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_DIR}/*.c
${LIBC_BOTTOM_HALF_SRC_DIR}/*.c)

set(LIBC_BOTTOM_HALF_INC_DIRS
${LIBC_BOTTOM_HALF_HEADERS_PRIVATE_DIR}
${LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC_DIR}
${LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_DIR}
${LIBC_TOP_HALF_MUSL_SRC_DIR}/include
${LIBC_TOP_HALF_MUSL_SRC_DIR}/internal
)

# FIXME(https://reviews.llvm.org/D85567) - due to a bug in LLD the weak
# references to a function defined in `chdir.c` only work if `chdir.c` is at the
# end of the archive, but once that LLD review lands and propagates into LLVM
# then we don't have to do this.
set(CHDIR_SRC "${LIBC_BOTTOM_HALF_SRC_DIR}/chdir.c")
list(REMOVE_ITEM LIBC_BOTTOM_HALF_ALL_SOURCES ${CHDIR_SRC})
list(APPEND LIBC_BOTTOM_HALF_ALL_SOURCES ${CHDIR_SRC})

add_library(libc-bottom-half OBJECT
${LIBC_BOTTOM_HALF_ALL_SOURCES})
add_dependencies(libc-bottom-half sysroot-headers)
target_include_directories(libc-bottom-half
PRIVATE
${LIBC_BOTTOM_HALF_INC_DIRS}
SYSTEM
${SYSROOT_INC_DIR}
)

add_subdirectory(clocks)
add_subdirectory(getpid)
add_subdirectory(mman)
add_subdirectory(signal)
add_subdirectory(crt1)
16 changes: 16 additions & 0 deletions cmake/libc-bottom-half/clocks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
file(GLOB_RECURSE
CLOCKS_SOURCES
${LIBC_BOTTOM_HALF_DIR}/clocks/*.c)

add_library(wasi-emulated-process-clocks STATIC
${CLOCKS_SOURCES})

target_include_directories(wasi-emulated-process-clocks
PRIVATE
${LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_DIR})

add_dependencies(wasi-emulated-process-clocks sysroot-headers)

add_custom_command(TARGET wasi-emulated-process-clocks POST_BUILD
COMMAND ${CMAKE_C_COMPILER_AR} crs $<TARGET_FILE:c>
)
26 changes: 26 additions & 0 deletions cmake/libc-bottom-half/crt1/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
file(GLOB
LIBC_BOTTOM_HALF_CRT_SOURCES
CONFIGURE_DEPENDS
${LIBC_BOTTOM_HALF_DIR}/crt/*.c)

foreach(crt_path ${LIBC_BOTTOM_HALF_CRT_SOURCES})
get_filename_component(crt_name ${crt_path} NAME_WLE)
add_library(${crt_name} OBJECT ${crt_path})

target_include_directories(${crt_name}
PRIVATE
${LIBC_BOTTOM_HALF_INC_DIRS}
)

add_dependencies(${crt_name} sysroot-headers)

add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/sysroot/lib/${crt_name}.o
COMMAND ${CMAKE_COMMAND} -E make_directory ${SYSROOT_LIB_DIR}
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_OBJECTS:${crt_name}> ${SYSROOT_LIB_DIR}/${crt_name}.o
COMMAND_EXPAND_LISTS
)

add_custom_target(${crt_name}.o ALL
DEPENDS ${CMAKE_BINARY_DIR}/sysroot/lib/${crt_name}.o)
add_dependencies(${crt_name}.o ${crt_name})
endforeach()
17 changes: 17 additions & 0 deletions cmake/libc-bottom-half/getpid/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
file(GLOB_RECURSE
GETPID_SOURCES
${LIBC_BOTTOM_HALF_DIR}/getpid/*.c)

add_library(wasi-emulated-getpid STATIC
${GETPID_SOURCES})

set_target_properties(wasi-emulated-getpid
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/sysroot/lib
)

add_dependencies(wasi-emulated-getpid sysroot-headers)

add_custom_command(TARGET wasi-emulated-getpid POST_BUILD
COMMAND ${CMAKE_C_COMPILER_AR} crs $<TARGET_FILE:c>
)
12 changes: 12 additions & 0 deletions cmake/libc-bottom-half/mman/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
file(GLOB_RECURSE
MMAN_SOURCES
${LIBC_BOTTOM_HALF_DIR}/mman/*.c)

add_library(wasi-emulated-mman STATIC
${MMAN_SOURCES})

add_dependencies(wasi-emulated-mman sysroot-headers)

add_custom_command(TARGET wasi-emulated-mman POST_BUILD
COMMAND ${CMAKE_C_COMPILER_AR} crs $<TARGET_FILE:c>
)
10 changes: 10 additions & 0 deletions cmake/libc-bottom-half/signal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
file(GLOB_RECURSE
SIGNAL_SOURCES
${LIBC_BOTTOM_HALF_DIR}/signal/*.c)

add_library(wasi-emulated-signal-objs
OBJECT
${SIGNAL_SOURCES}
)

add_dependencies(wasi-emulated-signal-objs sysroot-headers)
34 changes: 34 additions & 0 deletions cmake/libc-imports.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
add_custom_command(OUTPUT ${SYSROOT_LIB_DIR}/libc.imports
COMMAND
${Python_EXECUTABLE} ${PROJECT_SOURCE_DIR}/tools/gen-imports.py
--nm ${CMAKE_NM}
--libc-imports-output ${SYSROOT_LIB_DIR}/libc.imports
--defined-symbols-output ${SYSROOT_SHARE_DIR}/defined-symbols.txt
--undefined-symbols-output ${SYSROOT_SHARE_DIR}/undefined-symbols.txt
$<TARGET_FILE:c>
$<TARGET_FILE:c-printscan-long-double>
$<TARGET_FILE:c-printscan-no-floating-point>
$<TARGET_FILE:wasi-emulated-mman>
$<TARGET_FILE:wasi-emulated-process-clocks>
$<TARGET_FILE:wasi-emulated-getpid>
$<TARGET_FILE:wasi-emulated-signal>
$<TARGET_OBJECTS:crt1>
$<TARGET_OBJECTS:crt1-command>
$<TARGET_OBJECTS:crt1-reactor>
DEPENDS
${PROJECT_SOURCE_DIR}/tools/gen-imports.py)

add_custom_target(libc.imports ALL
DEPENDS ${SYSROOT_LIB_DIR}/libc.imports)
add_dependencies(libc.imports
c
c-printscan-long-double
c-printscan-no-floating-point
wasi-emulated-mman
wasi-emulated-process-clocks
wasi-emulated-getpid
wasi-emulated-signal
crt1
crt1-command
crt1-reactor
)
Loading

0 comments on commit f9d135e

Please sign in to comment.