cmake_minimum_required(VERSION 3.10) project(musl C ASM) set(S "${CMAKE_SOURCE_DIR}") set(GEN "${CMAKE_BINARY_DIR}/obj") if(NOT DEFINED MUSL_ARCH) set(MUSL_ARCH "x86_64") endif() if(NOT DEFINED MUSL_SYSLIBDIR) set(MUSL_SYSLIBDIR "${CMAKE_INSTALL_PREFIX}/lib") endif() if(MUSL_ARCH STREQUAL "x86_64") set(MUSL_LDSO "ld-musl-x86_64.so.1") elseif(MUSL_ARCH STREQUAL "aarch64") set(MUSL_LDSO "ld-musl-aarch64.so.1") elseif(MUSL_ARCH STREQUAL "i386") set(MUSL_LDSO "ld-musl-i386.so.1") else() set(MUSL_LDSO "ld-musl-${MUSL_ARCH}.so.1") endif() # ── Generated headers ──────────────────────────────────────────────────── file(MAKE_DIRECTORY "${GEN}/include/bits") file(MAKE_DIRECTORY "${GEN}/src/internal") execute_process( COMMAND sed -f "${S}/tools/mkalltypes.sed" "${S}/arch/${MUSL_ARCH}/bits/alltypes.h.in" "${S}/include/alltypes.h.in" OUTPUT_FILE "${GEN}/include/bits/alltypes.h" RESULT_VARIABLE alltypes_res ) if(NOT alltypes_res EQUAL 0) message(FATAL_ERROR "musl: failed to generate bits/alltypes.h") endif() file(READ "${S}/arch/${MUSL_ARCH}/bits/syscall.h.in" _syscall_in) file(WRITE "${GEN}/include/bits/syscall.h" "${_syscall_in}") execute_process( COMMAND sed -n -e "s/__NR_/SYS_/p" "${S}/arch/${MUSL_ARCH}/bits/syscall.h.in" OUTPUT_VARIABLE _syscall_aliases ) file(APPEND "${GEN}/include/bits/syscall.h" "${_syscall_aliases}") execute_process( COMMAND sh "${S}/tools/version.sh" WORKING_DIRECTORY "${S}" OUTPUT_VARIABLE MUSL_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) if(MUSL_VERSION STREQUAL "") set(MUSL_VERSION "unknown") endif() file(WRITE "${GEN}/src/internal/version.h" "#define VERSION \"${MUSL_VERSION}\"\n") # ── Include search path ────────────────────────────────────────────────── set(MUSL_INCLUDES "${GEN}/include" "${S}/arch/${MUSL_ARCH}" "${S}/arch/generic" "${GEN}/src/internal" "${S}/src/include" "${S}/src/internal" "${S}/include" ) # ── Compile flags ───────────────────────────────────────────────────────── set(MUSL_CFLAGS -std=c99 -nostdinc -ffreestanding -fexcess-precision=standard -frounding-math -fno-stack-protector -fno-strict-aliasing -fPIC -D_XOPEN_SOURCE=700 -Os -pipe -Wno-implicit-function-declaration -Wno-parentheses ) # ── Source selection with per-arch overrides ────────────────────────────── file(GLOB_RECURSE ALL_REL RELATIVE "${S}/src" "${S}/src/*.c" "${S}/src/*.s") # Discover valid arch names from the arch/ directory file(GLOB _arch_dirs "${S}/arch/*") set(MUSL_ALL_ARCHS "") foreach(_ad ${_arch_dirs}) get_filename_component(_aname "${_ad}" NAME) list(APPEND MUSL_ALL_ARCHS "${_aname}") endforeach() # First pass: find which generic files are overridden by our target arch set(ARCH_KEYS "") foreach(rel ${ALL_REL}) string(REPLACE "/" ";" parts "${rel}") list(LENGTH parts n) if(n EQUAL 3) list(GET parts 0 sub) list(GET parts 1 mid) list(GET parts 2 fname) list(FIND MUSL_ALL_ARCHS "${mid}" _is_arch) if(_is_arch GREATER -1 AND mid STREQUAL "${MUSL_ARCH}") get_filename_component(base "${fname}" NAME_WE) list(APPEND ARCH_KEYS "${sub}|${base}") endif() endif() endforeach() # Second pass: build the source list set(MUSL_SRCS "") foreach(rel ${ALL_REL}) string(REPLACE "/" ";" parts "${rel}") list(LENGTH parts n) if(n EQUAL 2) list(GET parts 0 sub) list(GET parts 1 fname) get_filename_component(base "${fname}" NAME_WE) list(FIND ARCH_KEYS "${sub}|${base}" found) if(found EQUAL -1) list(APPEND MUSL_SRCS "${S}/src/${rel}") endif() elseif(n EQUAL 3) list(GET parts 0 sub) list(GET parts 1 mid) list(FIND MUSL_ALL_ARCHS "${mid}" _is_arch) if(_is_arch GREATER -1) if(mid STREQUAL "${MUSL_ARCH}") list(APPEND MUSL_SRCS "${S}/src/${rel}") endif() else() # Non-arch subdir: include, but skip oldmalloc (musl defaults to mallocng) if(NOT (sub STREQUAL "malloc" AND mid STREQUAL "oldmalloc")) list(APPEND MUSL_SRCS "${S}/src/${rel}") endif() endif() endif() endforeach() # Dynamic-linker sources file(GLOB LDSO_SRCS "${S}/ldso/*.c" "${S}/ldso/*.s" "${S}/ldso/${MUSL_ARCH}/*.c" "${S}/ldso/${MUSL_ARCH}/*.s") # ── Shared libc ────────────────────────────────────────────────────────── add_library(c SHARED ${MUSL_SRCS} ${LDSO_SRCS}) target_include_directories(c PRIVATE ${MUSL_INCLUDES}) target_compile_options(c PRIVATE ${MUSL_CFLAGS}) target_compile_definitions(c PRIVATE _XOPEN_SOURCE=700) set_target_properties(c PROPERTIES OUTPUT_NAME c PREFIX "lib" SUFFIX ".so") target_link_options(c PRIVATE -nostdlib -shared -Wl,-e,_dlstart -Wl,-Bsymbolic-functions -Wl,--exclude-libs=ALL ) # ── Static libc.a ──────────────────────────────────────────────────────── add_library(c-static STATIC ${MUSL_SRCS}) target_include_directories(c-static PRIVATE ${MUSL_INCLUDES}) target_compile_options(c-static PRIVATE ${MUSL_CFLAGS}) target_compile_definitions(c-static PRIVATE _XOPEN_SOURCE=700) set_target_properties(c-static PROPERTIES OUTPUT_NAME c) # ── crt objects ─────────────────────────────────────────────────────────── set(_inc_flags "") foreach(d ${MUSL_INCLUDES}) list(APPEND _inc_flags "-I${d}") endforeach() set(CRT_OBJS "") function(musl_crt out src) set(extra ${ARGN}) add_custom_command( OUTPUT "${CMAKE_BINARY_DIR}/${out}" COMMAND ${CMAKE_C_COMPILER} ${MUSL_CFLAGS} ${_inc_flags} -DCRT ${extra} -c "${src}" -o "${CMAKE_BINARY_DIR}/${out}" DEPENDS "${src}" COMMENT "musl crt: ${out}" VERBATIM ) set(CRT_OBJS ${CRT_OBJS} "${CMAKE_BINARY_DIR}/${out}" PARENT_SCOPE) endfunction() musl_crt(crt1.o "${S}/crt/crt1.c") musl_crt(Scrt1.o "${S}/crt/Scrt1.c") musl_crt(rcrt1.o "${S}/crt/rcrt1.c") musl_crt(crti.o "${S}/crt/${MUSL_ARCH}/crti.s") musl_crt(crtn.o "${S}/crt/${MUSL_ARCH}/crtn.s") add_custom_target(crt ALL DEPENDS ${CRT_OBJS}) # ── Install ─────────────────────────────────────────────────────────────── install(TARGETS c c-static LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION lib) install(FILES ${CRT_OBJS} DESTINATION lib) install(DIRECTORY "${S}/include/" DESTINATION include FILES_MATCHING PATTERN "*.h") install(DIRECTORY "${S}/arch/generic/bits/" DESTINATION include/bits FILES_MATCHING PATTERN "*.h") install(DIRECTORY "${S}/arch/${MUSL_ARCH}/bits/" DESTINATION include/bits FILES_MATCHING PATTERN "*.h") install(FILES "${GEN}/include/bits/alltypes.h" "${GEN}/include/bits/syscall.h" DESTINATION include/bits)