kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

common.sh (5517B)


      1 #!/bin/sh
      2 
      3 set -eu
      4 
      5 : "${KIT:=./build/kit}"
      6 
      7 c_source() {
      8     "$KIT" build source "$1"
      9 }
     10 
     11 c_config() {
     12     key=$1
     13     def=$2
     14     "$KIT" build config-get --default "$def" "$key"
     15 }
     16 
     17 c_config_merge() {
     18     key=$1
     19     def=$2
     20     profile=$(c_config profile "")
     21     base=$(c_config "$key" "$def")
     22     prof=""
     23     extra=$(c_config "$key.extra" "")
     24     if [ -n "$profile" ]; then
     25         prof=$(c_config "profile.$profile.$key" "")
     26     fi
     27     printf '%s\n' "$base $prof $extra" | awk '{$1=$1; print}'
     28 }
     29 
     30 c_toolchain_init() {
     31     C_CC=$(c_config tool.c.cc "$(c_config cc "${CC:-cc}")")
     32     C_AR=$(c_config tool.c.ar "$(c_config ar "${AR:-ar}")")
     33     C_CFLAGS=$(c_config_merge tool.c.cflags "")
     34     C_LDFLAGS=$(c_config_merge tool.c.ldflags "")
     35     C_LDLIBS=$(c_config_merge tool.c.ldlibs "")
     36 }
     37 
     38 c_glob() {
     39     "$KIT" build glob "$1"
     40 }
     41 
     42 c_depfile() {
     43     if [ -s "$1" ]; then
     44         dep=$1
     45         if command -v c_depfile_filter >/dev/null 2>&1; then
     46             norm="$dep.norm"
     47             c_depfile_filter "$dep" > "$norm"
     48             dep=$norm
     49         fi
     50         "$KIT" build depfile "$dep" >/dev/null
     51         rm -f "$1" "${1}.norm"
     52     fi
     53 }
     54 
     55 c_compile() {
     56     src=$1
     57     obj=$2
     58     flags=$3
     59     mkdir -p "$(dirname "$obj")"
     60     dep="$obj.d"
     61     "$C_CC" $C_CFLAGS $flags -MMD -MP -MF "$dep" -c "$src" -o "$obj"
     62     c_depfile "$dep"
     63 }
     64 
     65 c_need() {
     66     label=$1
     67     case "$label" in
     68         :*|//*|@*) "$KIT" build need "$label" ;;
     69         *) "$KIT" build need ":$label" ;;
     70     esac
     71 }
     72 
     73 c_target_local() {
     74     if [ -n "${KIT_BUILD_LOCAL:-}" ]; then
     75         printf '%s\n' "$KIT_BUILD_LOCAL"
     76     else
     77         printf '%s\n' "${KIT_BUILD_TARGET##*:}"
     78     fi
     79 }
     80 
     81 c_require_hook() {
     82     if ! command -v "$1" >/dev/null 2>&1; then
     83         echo "missing C rule hook: $1" >&2
     84         exit 1
     85     fi
     86 }
     87 
     88 c_flags_init_default() {
     89     if command -v c_flags_init >/dev/null 2>&1; then
     90         c_flags_init
     91     else
     92         c_toolchain_init
     93     fi
     94 }
     95 
     96 c_default_object() {
     97     c_flags_init_default
     98     c_require_hook c_object_plan_find
     99     local=$(c_target_local)
    100     line=$(c_object_plan_find "$local") || {
    101         echo "no C object plan for target: $KIT_BUILD_TARGET" >&2
    102         exit 1
    103     }
    104 
    105     target=${line%%|*}
    106     rest=${line#*|}
    107     src=${rest%%|*}
    108     rest=${rest#*|}
    109     obj_rel=${rest%%|*}
    110     flags=${rest#*|}
    111 
    112     [ "$target" = "$local" ] || exit 1
    113 
    114     mkdir -p "$KIT_BUILD_OUT/obj"
    115     c_compile "$src" "$KIT_BUILD_OUT/obj/$local" "$flags"
    116     printf '%s\n' "obj/$local" > "$KIT_BUILD_OUT/object.list"
    117     printf '%s\n' "$obj_rel" > "$KIT_BUILD_OUT/object.rel"
    118     printf '%s\n' "$src" > "$KIT_BUILD_OUT/source.txt"
    119 }
    120 
    121 c_default_objects() {
    122     c_flags_init_default
    123     c_require_hook c_object_plan
    124     local=$(c_target_local)
    125     mkdir -p "$KIT_BUILD_OUT"
    126     objects="$KIT_BUILD_OUT/objects.list"
    127     : > "$objects"
    128 
    129     c_object_plan "$local" | while IFS='|' read -r _target src obj_rel flags; do
    130         [ -n "$src" ] || continue
    131         dst="$KIT_BUILD_OUT/$obj_rel"
    132         mkdir -p "$(dirname "$dst")"
    133         c_compile "$src" "$dst" "$flags"
    134         printf '%s\n' "$obj_rel" >> "$objects"
    135     done
    136 }
    137 
    138 c_default_archive() {
    139     c_flags_init_default
    140     c_require_hook c_archive_output
    141     c_require_hook c_archive_object_sets
    142     local=$(c_target_local)
    143     mkdir -p "$KIT_BUILD_OUT"
    144     archive=$(c_archive_output "$local")
    145     objects="$KIT_BUILD_OUT/archive-objects.list"
    146     : > "$objects"
    147 
    148     c_archive_object_sets "$local" | while IFS= read -r set_target; do
    149         [ -n "$set_target" ] || continue
    150         dep=$(c_need "$set_target")
    151         while IFS= read -r obj; do
    152             [ -n "$obj" ] || continue
    153             printf '%s/%s\n' "$dep" "$obj" >> "$objects"
    154         done < "$dep/objects.list"
    155     done
    156 
    157     rm -f "$KIT_BUILD_OUT/$archive"
    158     # shellcheck disable=SC2046
    159     "$C_AR" rcs "$KIT_BUILD_OUT/$archive" $(cat "$objects")
    160     rm -f "$objects"
    161 }
    162 
    163 c_default_executable() {
    164     c_flags_init_default
    165     c_require_hook c_executable_output
    166     local=$(c_target_local)
    167     mkdir -p "$KIT_BUILD_OUT"
    168     exe=$(c_executable_output "$local")
    169     objs=
    170     libs=
    171 
    172     if command -v c_executable_object_sets >/dev/null 2>&1; then
    173         for set_target in $(c_executable_object_sets "$local"); do
    174             dep=$(c_need "$set_target")
    175             while IFS= read -r obj; do
    176                 [ -n "$obj" ] || continue
    177                 objs="$objs $dep/$obj"
    178             done < "$dep/objects.list"
    179         done
    180     fi
    181 
    182     if command -v c_executable_libraries >/dev/null 2>&1; then
    183         c_executable_libraries "$local" | while IFS='|' read -r label file; do
    184             [ -n "$label" ] || continue
    185             dep=$(c_need "$label")
    186             printf '%s/%s\n' "$dep" "$file" >> "$KIT_BUILD_OUT/.link-libs"
    187         done
    188         if [ -f "$KIT_BUILD_OUT/.link-libs" ]; then
    189             while IFS= read -r lib; do
    190                 libs="$libs $lib"
    191             done < "$KIT_BUILD_OUT/.link-libs"
    192             rm -f "$KIT_BUILD_OUT/.link-libs"
    193         fi
    194     fi
    195 
    196     target_ldflags=""
    197     target_ldlibs=""
    198     if command -v c_executable_ldflags >/dev/null 2>&1; then
    199         target_ldflags=$(c_executable_ldflags "$local")
    200     fi
    201     if command -v c_executable_ldlibs >/dev/null 2>&1; then
    202         target_ldlibs=$(c_executable_ldlibs "$local")
    203     fi
    204 
    205     # shellcheck disable=SC2086
    206     "$C_CC" $C_LDFLAGS $target_ldflags -o "$KIT_BUILD_OUT/$exe" \
    207         $objs $libs $target_ldlibs $C_LDLIBS
    208 
    209     if command -v c_executable_after_link >/dev/null 2>&1; then
    210         c_executable_after_link "$local"
    211     fi
    212 }