1#
2# Copyright 2017, Data61
3# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4# ABN 41 687 119 230.
5#
6# This software may be distributed and modified according to the terms of
7# the BSD 2-Clause license. Note that NO WARRANTY is provided.
8# See "LICENSE_BSD2.txt" for details.
9#
10# @TAG(DATA61_BSD)
11#
12
13cmake_minimum_required(VERSION 3.5.1)
14
15project(libmuslc NONE)
16
17set(LIB_MUSLC_PARALLEL_BUILD true CACHE BOOL "Use `make -j` when building libmuslc")
18
19# Construct the muslc version of our arch
20if(Kernel64)
21    if(${KernelArch} STREQUAL "arm")
22        set(muslc_arch "aarch64")
23    endif()
24    if(${KernelArch} STREQUAL "x86")
25        set(muslc_arch "x86_64")
26    endif()
27    if(${KernelArch} STREQUAL "riscv")
28        set(muslc_arch "riscv")
29    endif()
30else()
31    if(${KernelArch} STREQUAL "arm")
32        set(muslc_arch "arm")
33    endif()
34    if(${KernelArch} STREQUAL "x86")
35        set(muslc_arch "i386")
36    endif()
37    if(${KernelArch} STREQUAL "riscv")
38        set(muslc_arch "riscv")
39    endif()
40endif()
41
42set(
43    LIB_MUSLC_GLOB_SOURCES OFF
44    CACHE BOOL "This flag causes CMake to add lots of source files to its dependency lists
45     which slows down its configuration times.
46     When not making changes in the musllibc directory, it is likely not necessary
47     to have this enabled."
48)
49mark_as_advanced(LIB_MUSLC_PARALLEL_BUILD LIB_MUSLC_GLOB_SOURCES)
50if(LIB_MUSLC_GLOB_SOURCES)
51    file(
52        GLOB_RECURSE
53            deps
54            **/*.c
55            **/*.h
56            **/*.S
57            **/*.s
58    )
59endif()
60
61set(parallel "")
62if(LIB_MUSLC_PARALLEL_BUILD)
63    include(ProcessorCount)
64    ProcessorCount(N)
65    if(NOT N EQUAL 0)
66        # We set tasks to number of CPUs + 2 to account for blocking IO
67        # this is a similar heuristic to what Ninja uses by default.
68        # Note that this gets used in a rule generated by add_custom_command and
69        # is additive with any existing Ninja jobs.
70        math(EXPR Nplus2 "${N} + 2")
71        set(parallel "-j${Nplus2}")
72    else()
73        message(WARNING "Could not detect ProcessorCount for building musllibc.")
74    endif()
75endif()
76
77# We make an attempt to extract compiler options from CMake
78get_property(compile_options DIRECTORY PROPERTY COMPILE_OPTIONS)
79
80# Also inherit the CMAKE build type flags from one of the following variables depending on
81# the configured build type:
82# CMAKE_C_FLAGS_DEBUG, CMAKE_C_FLAGS_RELEASE, CMAKE_C_FLAGS_RELWITHDEBINFO, CMAKE_C_FLAGS_MINSIZEREL
83string(TOUPPER CMAKE_BUILD_TYPE build_type)
84set(cmake_built_type_config_name CMAKE_C_FLAGS_${build_type})
85separate_arguments(cmake_c_flags_sep NATIVE_COMMAND "${CMAKE_C_FLAGS};${${cmake_built_type_config_name}}")
86
87list(APPEND compile_options "${cmake_c_flags_sep}")
88
89# Add the target triple to the compile flags if we are using clang
90# It is not part of the CMAKE_C_FLAGS variable
91if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
92    list(APPEND compile_options "${CMAKE_C_COMPILE_OPTIONS_TARGET}${CMAKE_C_COMPILER_TARGET}")
93endif()
94
95include(memoize)
96# memoize this installation rule which will save the resulting artifact in a cache and reuse it across builds.
97# This will rebuild from source if the git directory has changes or has a changed commit hash.
98memoize_add_custom_command(musllibc "${CMAKE_CURRENT_BINARY_DIR}/build-temp/stage" "${CMAKE_CURRENT_SOURCE_DIR}" "${compile_options} ${muslc_arch}" ""
99    OUTPUT
100        build-temp/stage/lib/libc.a
101        # If we have to rebuild, first clear the temporary build directory as
102        # we have no correctly captured the output files or dependencies
103    COMMAND rm -r build-temp
104    COMMAND mkdir -p build-temp
105    COMMAND
106        ${CMAKE_COMMAND} -E env TOOLPREFIX=${CROSS_COMPILER_PREFIX}
107        # TODO: should also pass in the cflags for the CMAKE_BUILD_TYPE ?
108        # Suppress make output by default. Verbose make output can now be achieved
109        # by MAKEFLAGS=V3 ninja (${MAKEFLAGS:--s} expands to -s if MAKEFLAGS is unset).
110        C_COMPILER=${CMAKE_C_COMPILER}
111        "MAKEFLAGS=\$\${MAKEFLAGS:--s}"
112        NK_CFLAGS="${compile_options}" TARGET=${muslc_arch} make -C build-temp ${parallel} -f
113        "${CMAKE_CURRENT_SOURCE_DIR}/Makefile"
114        "STAGE_DIR=${CMAKE_CURRENT_BINARY_DIR}/build-temp/stage"
115        "SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}"
116    DEPENDS ${deps} COMMAND_EXPAND_LISTS
117    COMMENT "Invoking muslc build system"
118)
119
120add_custom_target(
121    muslc_gen
122    DEPENDS build-temp/stage/lib/libc.a
123)
124
125add_library(muslc_imported STATIC IMPORTED GLOBAL)
126add_dependencies(muslc_imported muslc_gen)
127set_property(
128    TARGET muslc_imported
129    PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/build-temp/stage/lib/libc.a"
130)
131
132add_library(muslc INTERFACE)
133add_dependencies(muslc muslc_imported)
134set_property(TARGET muslc PROPERTY INTERFACE_LINK_LIBRARIES muslc_imported)
135target_include_directories(muslc INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/build-temp/stage/include")
136