configuration.sh 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. #!/bin/bash
  2. #
  3. # Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
  4. #
  5. # This file is licensed under the terms of the GNU General Public
  6. # License version 2. This program is licensed "as is" without any
  7. # warranty of any kind, whether express or implied.
  8. [[ -z $VENDOR ]] && VENDOR="Orange Pi"
  9. [[ -z $ROOTPWD ]] && ROOTPWD="orangepi" # Must be changed @first login
  10. [[ -z $OPI_USERNAME ]] && OPI_USERNAME="orangepi"
  11. [[ -z $OPI_PWD ]] && OPI_PWD="orangepi"
  12. [[ -z $MAINTAINER ]] && MAINTAINER="Orange Pi" # deb signature
  13. [[ -z $MAINTAINERMAIL ]] && MAINTAINERMAIL="leeboby@aliyun.com" # deb signature
  14. [[ -z $DEB_COMPRESS ]] && DEB_COMPRESS="xz" # compress .debs with XZ by default. Use 'none' for faster/larger builds
  15. TZDATA=$(cat /etc/timezone) # Timezone for target is taken from host or defined here.
  16. USEALLCORES=yes # Use all CPU cores for compiling
  17. HOSTRELEASE=$(cat /etc/os-release | grep VERSION_CODENAME | cut -d"=" -f2)
  18. [[ -z $HOSTRELEASE ]] && HOSTRELEASE=$(cut -d'/' -f1 /etc/debian_version)
  19. [[ -z $EXIT_PATCHING_ERROR ]] && EXIT_PATCHING_ERROR="" # exit patching if failed
  20. [[ -z $HOST ]] && HOST="$BOARD" # set hostname to the board
  21. [[ -z $CHINA_DOWNLOAD_MIRROR ]] && CHINA_DOWNLOAD_MIRROR=huawei
  22. cd "${SRC}" || exit
  23. [[ -z "${ROOTFSCACHE_VERSION}" ]] && ROOTFSCACHE_VERSION=11
  24. [[ -z "${CHROOT_CACHE_VERSION}" ]] && CHROOT_CACHE_VERSION=7
  25. [[ -z $PLYMOUTH ]] && PLYMOUTH="yes"
  26. cd ${SRC}/scripts
  27. BUILD_REPOSITORY_URL=$(improved_git remote get-url $(improved_git remote 2>/dev/null | grep origin) 2>/dev/null)
  28. BUILD_REPOSITORY_COMMIT=$(improved_git describe --match=d_e_a_d_b_e_e_f --always --dirty 2>/dev/null)
  29. ROOTFS_CACHE_MAX=200 # max number of rootfs cache, older ones will be cleaned up
  30. DEB_STORAGE=$DEST/debs
  31. DEB_ORANGEPI=$EXTER/cache/debs
  32. # TODO: fixed name can't be used for parallel image building
  33. ROOT_MAPPER="orangepi-root"
  34. [[ -z $ROOTFS_TYPE ]] && ROOTFS_TYPE=ext4 # default rootfs type is ext4
  35. [[ "ext4 f2fs btrfs xfs nfs fel" != *$ROOTFS_TYPE* ]] && exit_with_error "Unknown rootfs type" "$ROOTFS_TYPE"
  36. [[ -z $BTRFS_COMPRESSION ]] && BTRFS_COMPRESSION=zlib # default btrfs filesystem compression method is zlib
  37. [[ ! $BTRFS_COMPRESSION =~ zlib|lzo|zstd|none ]] && exit_with_error "Unknown btrfs compression method" "$BTRFS_COMPRESSION"
  38. # Fixed image size is in 1M dd blocks (MiB)
  39. # to get size of block device /dev/sdX execute as root:
  40. # echo $(( $(blockdev --getsize64 /dev/sdX) / 1024 / 1024 ))
  41. [[ "f2fs" == *$ROOTFS_TYPE* && -z $FIXED_IMAGE_SIZE ]] && exit_with_error "Please define FIXED_IMAGE_SIZE"
  42. # a passphrase is mandatory if rootfs encryption is enabled
  43. if [[ $CRYPTROOT_ENABLE == yes && -z $CRYPTROOT_PASSPHRASE ]]; then
  44. exit_with_error "Root encryption is enabled but CRYPTROOT_PASSPHRASE is not set"
  45. fi
  46. # small SD card with kernel, boot script and .dtb/.bin files
  47. [[ $ROOTFS_TYPE == nfs ]] && FIXED_IMAGE_SIZE=64
  48. # Since we are having too many options for mirror management,
  49. # then here is yet another mirror related option.
  50. # Respecting user's override in case a mirror is unreachable.
  51. case $REGIONAL_MIRROR in
  52. china)
  53. [[ -z $USE_MAINLINE_GOOGLE_MIRROR ]] && [[ -z $MAINLINE_MIRROR ]] && MAINLINE_MIRROR=tuna
  54. [[ -z $USE_GITHUB_UBOOT_MIRROR ]] && [[ -z $UBOOT_MIRROR ]] && UBOOT_MIRROR=gitee
  55. [[ -z $GITHUB_MIRROR ]] && GITHUB_MIRROR=gitclone
  56. [[ -z $DOWNLOAD_MIRROR ]] && DOWNLOAD_MIRROR=china
  57. ;;
  58. *)
  59. ;;
  60. esac
  61. # used by multiple sources - reduce code duplication
  62. [[ $USE_MAINLINE_GOOGLE_MIRROR == yes ]] && MAINLINE_MIRROR=google
  63. case $MAINLINE_MIRROR in
  64. google)
  65. MAINLINE_KERNEL_SOURCE='https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable'
  66. MAINLINE_FIRMWARE_SOURCE='https://kernel.googlesource.com/pub/scm/linux/kernel/git/firmware/linux-firmware.git'
  67. ;;
  68. tuna)
  69. MAINLINE_KERNEL_SOURCE='https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git'
  70. MAINLINE_FIRMWARE_SOURCE='https://mirrors.tuna.tsinghua.edu.cn/git/linux-firmware.git'
  71. ;;
  72. bfsu)
  73. MAINLINE_KERNEL_SOURCE='https://mirrors.bfsu.edu.cn/git/linux-stable.git'
  74. MAINLINE_FIRMWARE_SOURCE='https://mirrors.bfsu.edu.cn/git/linux-firmware.git'
  75. ;;
  76. *)
  77. MAINLINE_KERNEL_SOURCE='git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git'
  78. MAINLINE_FIRMWARE_SOURCE='git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git'
  79. ;;
  80. esac
  81. MAINLINE_KERNEL_DIR="$SRC/kernel"
  82. [[ $USE_GITHUB_UBOOT_MIRROR == yes ]] && UBOOT_MIRROR=github
  83. case $UBOOT_MIRROR in
  84. gitee)
  85. MAINLINE_UBOOT_SOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git'
  86. ;;
  87. github)
  88. MAINLINE_UBOOT_SOURCE='https://github.com/orangepi-xunlong/u-boot-orangepi.git'
  89. ;;
  90. *)
  91. MAINLINE_UBOOT_SOURCE='https://source.denx.de/u-boot/u-boot.git'
  92. ;;
  93. esac
  94. MAINLINE_UBOOT_DIR="$SRC/u-boot"
  95. case $GITHUB_MIRROR in
  96. fastgit)
  97. GITHUB_SOURCE='https://hub.fastgit.xyz'
  98. ;;
  99. gitclone)
  100. GITHUB_SOURCE='https://gitclone.com/github.com'
  101. ;;
  102. *)
  103. GITHUB_SOURCE='https://github.com'
  104. ;;
  105. esac
  106. # Let's set default data if not defined in board configuration above
  107. [[ -z $OFFSET ]] && OFFSET=4 # offset to 1st partition (we use 4MiB boundaries by default)
  108. ARCH=armhf
  109. KERNEL_IMAGE_TYPE=zImage
  110. CAN_BUILD_STRETCH=yes
  111. ATF_COMPILE=yes
  112. [[ -z $CRYPTROOT_SSH_UNLOCK ]] && CRYPTROOT_SSH_UNLOCK=yes
  113. [[ -z $CRYPTROOT_SSH_UNLOCK_PORT ]] && CRYPTROOT_SSH_UNLOCK_PORT=2022
  114. # Default to pdkdf2, this used to be the default with cryptroot <= 2.0, however
  115. # cryptroot 2.1 changed that to Argon2i. Argon2i is a memory intensive
  116. # algorithm which doesn't play well with SBCs (need 1GiB RAM by default !)
  117. # https://gitlab.com/cryptsetup/cryptsetup/-/issues/372
  118. [[ -z $CRYPTROOT_PARAMETERS ]] && CRYPTROOT_PARAMETERS="--pbkdf pbkdf2"
  119. [[ -z $WIREGUARD ]] && WIREGUARD="no"
  120. [[ -z $EXTRAWIFI ]] && EXTRAWIFI="yes"
  121. [[ -z $SKIP_BOOTSPLASH ]] && SKIP_BOOTSPLASH="no"
  122. [[ -z $AUFS ]] && AUFS="yes"
  123. [[ -z $IMAGE_PARTITION_TABLE ]] && IMAGE_PARTITION_TABLE="msdos"
  124. [[ -z $EXTRA_BSP_NAME ]] && EXTRA_BSP_NAME=""
  125. [[ -z $EXTRA_ROOTFS_MIB_SIZE ]] && EXTRA_ROOTFS_MIB_SIZE=0
  126. [[ -z $BUILD_KSRC ]] && BUILD_KSRC="no"
  127. # single ext4 partition is the default and preferred configuration
  128. #BOOTFS_TYPE=''
  129. [[ ! -f ${EXTER}/config/sources/families/$LINUXFAMILY.conf ]] && \
  130. exit_with_error "Sources configuration not found" "$LINUXFAMILY"
  131. source "${EXTER}/config/sources/families/${LINUXFAMILY}.conf"
  132. if [[ -f $USERPATCHES_PATH/sources/families/$LINUXFAMILY.conf ]]; then
  133. display_alert "Adding user provided $LINUXFAMILY overrides"
  134. source "$USERPATCHES_PATH/sources/families/${LINUXFAMILY}.conf"
  135. fi
  136. # load architecture defaults
  137. source "${EXTER}/config/sources/${ARCH}.conf"
  138. ## Extensions: at this point we've sourced all the config files that will be used,
  139. ## and (hopefully) not yet invoked any extension methods. So this is the perfect
  140. ## place to initialize the extension manager. It will create functions
  141. ## like the 'post_family_config' that is invoked below.
  142. initialize_extension_manager
  143. call_extension_method "post_family_config" "config_tweaks_post_family_config" << 'POST_FAMILY_CONFIG'
  144. *give the config a chance to override the family/arch defaults*
  145. This hook is called after the family configuration (`sources/families/xxx.conf`) is sourced.
  146. Since the family can override values from the user configuration and the board configuration,
  147. it is often used to in turn override those.
  148. POST_FAMILY_CONFIG
  149. # Myy : Menu configuration for choosing desktop configurations
  150. show_menu() {
  151. provided_title=$1
  152. provided_backtitle=$2
  153. provided_menuname=$3
  154. # Myy : I don't know why there's a TTY_Y - 8...
  155. #echo "Provided title : $provided_title"
  156. #echo "Provided backtitle : $provided_backtitle"
  157. #echo "Provided menuname : $provided_menuname"
  158. #echo "Provided options : " "${@:4}"
  159. #echo "TTY X: $TTY_X Y: $TTY_Y"
  160. whiptail --title "${provided_title}" --backtitle "${provided_backtitle}" --notags \
  161. --menu "${provided_menuname}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
  162. "${@:4}" \
  163. 3>&1 1>&2 2>&3
  164. }
  165. # Myy : FIXME Factorize
  166. show_select_menu() {
  167. provided_title=$1
  168. provided_backtitle=$2
  169. provided_menuname=$3
  170. #dialog --stdout --title "${provided_title}" --backtitle "${provided_backtitle}" \
  171. #--checklist "${provided_menuname}" $TTY_Y $TTY_X $((TTY_Y - 8)) "${@:4}"
  172. #whiptail --separate-output --title "${provided_title}" --backtitle "${provided_backtitle}" \
  173. # --checklist "${provided_menuname}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
  174. # "${@:4}" \
  175. # 3>&1 1>&2 2>&3
  176. whiptail --title "${provided_title}" --backtitle "${provided_backtitle}" \
  177. --checklist "${provided_menuname}" "${TTY_Y}" "${TTY_X}" $((TTY_Y - 8)) \
  178. "${@:4}" \
  179. 3>&1 1>&2 2>&3
  180. }
  181. # Myy : Once we got a list of selected groups, parse the PACKAGE_LIST inside configuration.sh
  182. DESKTOP_ELEMENTS_DIR="${EXTER}/config/desktop/${RELEASE}"
  183. DESKTOP_CONFIGS_DIR="${DESKTOP_ELEMENTS_DIR}/environments"
  184. DESKTOP_CONFIG_PREFIX="config_"
  185. DESKTOP_APPGROUPS_DIR="${DESKTOP_ELEMENTS_DIR}/appgroups"
  186. desktop_element_available_for_arch() {
  187. local desktop_element_path="${1}"
  188. local targeted_arch="${2}"
  189. local arch_limitation_file="${1}/only_for"
  190. echo "Checking if ${desktop_element_path} is available for ${targeted_arch} in ${arch_limitation_file}" >> "${DEST}"/${LOG_SUBPATH}/output.log
  191. if [[ -f "${arch_limitation_file}" ]]; then
  192. grep -- "${targeted_arch}" "${arch_limitation_file}" > /dev/null
  193. return $?
  194. else
  195. return 0
  196. fi
  197. }
  198. desktop_element_supported() {
  199. local desktop_element_path="${1}"
  200. local support_level_filepath="${desktop_element_path}/support"
  201. if [[ -f "${support_level_filepath}" ]]; then
  202. local support_level="$(cat "${support_level_filepath}")"
  203. if [[ "${support_level}" != "supported" && "${EXPERT}" != "yes" ]]; then
  204. return 65
  205. fi
  206. desktop_element_available_for_arch "${desktop_element_path}" "${ARCH}"
  207. if [[ $? -ne 0 ]]; then
  208. return 66
  209. fi
  210. else
  211. return 64
  212. fi
  213. return 0
  214. }
  215. if [[ $BUILD_DESKTOP == "yes" && -z $DESKTOP_ENVIRONMENT ]]; then
  216. desktop_environments_prepare_menu() {
  217. for desktop_env_dir in "${DESKTOP_CONFIGS_DIR}/"*; do
  218. local desktop_env_name=$(basename ${desktop_env_dir})
  219. local expert_infos=""
  220. [[ "${EXPERT}" == "yes" ]] && expert_infos="[$(cat "${desktop_env_dir}/support" 2> /dev/null)]"
  221. desktop_element_supported "${desktop_env_dir}" "${ARCH}" && options+=("${desktop_env_name}" "${desktop_env_name^} desktop environment ${expert_infos}")
  222. done
  223. }
  224. options=()
  225. desktop_environments_prepare_menu
  226. if [[ "${options[0]}" == "" ]]; then
  227. exit_with_error "No desktop environment seems to be available for your board ${BOARD} (ARCH : ${ARCH} - EXPERT : ${EXPERT})"
  228. fi
  229. DESKTOP_ENVIRONMENT=$(show_menu "Choose a desktop environment" "$backtitle" "Select the default desktop environment to bundle with this image" "${options[@]}")
  230. unset options
  231. if [[ -z "${DESKTOP_ENVIRONMENT}" ]]; then
  232. exit_with_error "No desktop environment selected..."
  233. fi
  234. fi
  235. if [[ $BUILD_DESKTOP == "yes" ]]; then
  236. # Expected environment variables :
  237. # - options
  238. # - ARCH
  239. desktop_environment_check_if_valid() {
  240. local error_msg=""
  241. desktop_element_supported "${DESKTOP_ENVIRONMENT_DIRPATH}" "${ARCH}"
  242. local retval=$?
  243. if [[ ${retval} == 0 ]]; then
  244. return
  245. elif [[ ${retval} == 64 ]]; then
  246. error_msg+="Either the desktop environment ${DESKTOP_ENVIRONMENT} does not exist "
  247. error_msg+="or the file ${DESKTOP_ENVIRONMENT_DIRPATH}/support is missing"
  248. elif [[ ${retval} == 65 ]]; then
  249. error_msg+="Only experts can build an image with the desktop environment \"${DESKTOP_ENVIRONMENT}\", since the Armbian team won't offer any support for it (EXPERT=${EXPERT})"
  250. elif [[ ${retval} == 66 ]]; then
  251. error_msg+="The desktop environment \"${DESKTOP_ENVIRONMENT}\" has no packages for your targeted board architecture (BOARD=${BOARD} ARCH=${ARCH}). "
  252. error_msg+="The supported boards architectures are : "
  253. error_msg+="$(cat "${DESKTOP_ENVIRONMENT_DIRPATH}/only_for")"
  254. fi
  255. # supress error when cache is rebuilding
  256. [[ -n "$ROOT_FS_CREATE_ONLY" ]] && exit 0
  257. exit_with_error "${error_msg}"
  258. }
  259. DESKTOP_ENVIRONMENT_DIRPATH="${DESKTOP_CONFIGS_DIR}/${DESKTOP_ENVIRONMENT}"
  260. desktop_environment_check_if_valid
  261. fi
  262. if [[ $BUILD_DESKTOP == "yes" && -z $DESKTOP_ENVIRONMENT_CONFIG_NAME ]]; then
  263. # FIXME Check for empty folders, just in case the current maintainer
  264. # messed up
  265. # Note, we could also ignore it and don't show anything in the previous
  266. # menu, but that hides information and make debugging harder, which I
  267. # don't like. Adding desktop environments as a maintainer is not a
  268. # trivial nor common task.
  269. options=()
  270. for configuration in "${DESKTOP_ENVIRONMENT_DIRPATH}/${DESKTOP_CONFIG_PREFIX}"*; do
  271. config_filename=$(basename ${configuration})
  272. config_name=${config_filename#"${DESKTOP_CONFIG_PREFIX}"}
  273. options+=("${config_filename}" "${config_name} configuration")
  274. done
  275. DESKTOP_ENVIRONMENT_CONFIG_NAME=$(show_menu "Choose the desktop environment config" "$backtitle" "Select the configuration for this environment.\nThese are sourced from ${desktop_environment_config_dir}" "${options[@]}")
  276. unset options
  277. if [[ -z $DESKTOP_ENVIRONMENT_CONFIG_NAME ]]; then
  278. exit_with_error "No desktop configuration selected... Do you really want a desktop environment ?"
  279. fi
  280. fi
  281. if [[ $BUILD_DESKTOP == "yes" ]]; then
  282. DESKTOP_ENVIRONMENT_PACKAGE_LIST_DIRPATH="${DESKTOP_ENVIRONMENT_DIRPATH}/${DESKTOP_ENVIRONMENT_CONFIG_NAME}"
  283. DESKTOP_ENVIRONMENT_PACKAGE_LIST_FILEPATH="${DESKTOP_ENVIRONMENT_PACKAGE_LIST_DIRPATH}/packages"
  284. fi
  285. # "-z ${VAR+x}" allows to check for unset variable
  286. # Technically, someone might want to build a desktop with no additional
  287. # appgroups.
  288. if [[ $BUILD_DESKTOP == "yes" && -z ${DESKTOP_APPGROUPS_SELECTED+x} && ${RELEASE} != "raspi" ]]; then
  289. options=()
  290. for appgroup_path in "${DESKTOP_APPGROUPS_DIR}/"*; do
  291. appgroup="$(basename "${appgroup_path}")"
  292. options+=("${appgroup}" "${appgroup^}" off)
  293. done
  294. DESKTOP_APPGROUPS_SELECTED=$(\
  295. show_select_menu \
  296. "Choose desktop softwares to add" \
  297. "$backtitle" \
  298. "Select which kind of softwares you'd like to add to your build" \
  299. "${options[@]}")
  300. DESKTOP_APPGROUPS_SELECTED=${DESKTOP_APPGROUPS_SELECTED//\"/}
  301. unset options
  302. fi
  303. #exit_with_error 'Testing'
  304. # Expected variables
  305. # - aggregated_content
  306. # - potential_paths
  307. # - separator
  308. # Write to variables :
  309. # - aggregated_content
  310. aggregate_content() {
  311. LOG_OUTPUT_FILE="${SRC}/output/${LOG_SUBPATH}/potential-paths.log"
  312. echo -e "Potential paths :" >> "${LOG_OUTPUT_FILE}"
  313. show_checklist_variables potential_paths
  314. for filepath in ${potential_paths}; do
  315. if [[ -f "${filepath}" ]]; then
  316. echo -e "${filepath/"$EXTER"\//} yes" >> "${LOG_OUTPUT_FILE}"
  317. aggregated_content+=$(cat "${filepath}")
  318. aggregated_content+="${separator}"
  319. # else
  320. # echo -e "${filepath/"$EXTER"\//} no\n" >> "${LOG_OUTPUT_FILE}"
  321. fi
  322. done
  323. echo "" >> "${LOG_OUTPUT_FILE}"
  324. unset LOG_OUTPUT_FILE
  325. }
  326. # set unique mounting directory
  327. MOUNT_UUID=$(uuidgen)
  328. SDCARD="${SRC}/.tmp/rootfs-${MOUNT_UUID}"
  329. MOUNT="${SRC}/.tmp/mount-${MOUNT_UUID}"
  330. DESTIMG="${SRC}/.tmp/image-${MOUNT_UUID}"
  331. # dropbear needs to be configured differently
  332. [[ $CRYPTROOT_ENABLE == yes && $RELEASE == xenial ]] && exit_with_error "Encrypted rootfs is not supported in Xenial"
  333. [[ $RELEASE == stretch && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Debian Stretch images with selected kernel is not supported"
  334. [[ $RELEASE == bionic && $CAN_BUILD_STRETCH != yes ]] && exit_with_error "Building Ubuntu Bionic images with selected kernel is not supported"
  335. [[ $RELEASE == hirsute && $HOSTRELEASE == focal ]] && exit_with_error "Building Ubuntu Hirsute images requires Hirsute build host. Please upgrade your host or select a different target OS"
  336. [[ -n $ATFSOURCE && -z $ATF_USE_GCC ]] && exit_with_error "Error in configuration: ATF_USE_GCC is unset"
  337. [[ -z $UBOOT_USE_GCC ]] && exit_with_error "Error in configuration: UBOOT_USE_GCC is unset"
  338. [[ -z $KERNEL_USE_GCC ]] && exit_with_error "Error in configuration: KERNEL_USE_GCC is unset"
  339. BOOTCONFIG_VAR_NAME=BOOTCONFIG_${BRANCH^^}
  340. [[ -n ${!BOOTCONFIG_VAR_NAME} ]] && BOOTCONFIG=${!BOOTCONFIG_VAR_NAME}
  341. [[ -z $LINUXCONFIG ]] && LINUXCONFIG="linux-${LINUXFAMILY}-${BRANCH}"
  342. [[ -z $BOOTPATCHDIR ]] && BOOTPATCHDIR="u-boot-$LINUXFAMILY"
  343. [[ -z $ATFPATCHDIR ]] && ATFPATCHDIR="atf-$LINUXFAMILY"
  344. [[ -z $KERNELPATCHDIR ]] && KERNELPATCHDIR="$LINUXFAMILY-$BRANCH"
  345. if [[ "$RELEASE" =~ ^(xenial|bionic|focal|hirsute|impish|jammy|noble)$ ]]; then
  346. DISTRIBUTION="Ubuntu"
  347. elif [[ "$RELEASE" == raspi ]]; then
  348. DISTRIBUTION="Bullseye"
  349. else
  350. DISTRIBUTION="Debian"
  351. fi
  352. CLI_CONFIG_PATH="${EXTER}/config/cli/${RELEASE}"
  353. DEBOOTSTRAP_CONFIG_PATH="${CLI_CONFIG_PATH}/debootstrap"
  354. if [[ $? != 0 ]]; then
  355. exit_with_error "The desktop environment ${DESKTOP_ENVIRONMENT} is not available for your architecture ${ARCH}"
  356. fi
  357. AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS="
  358. ${EXTER}/config
  359. ${EXTER}/config/optional/_any_board/_config
  360. ${EXTER}/config/optional/architectures/${ARCH}/_config
  361. ${EXTER}/config/optional/families/${LINUXFAMILY}/_config
  362. ${EXTER}/config/optional/boards/${BOARD}/_config
  363. ${USERPATCHES_PATH}
  364. "
  365. DEBOOTSTRAP_SEARCH_RELATIVE_DIRS="
  366. cli/_all_distributions/debootstrap
  367. cli/${RELEASE}/debootstrap
  368. "
  369. CLI_SEARCH_RELATIVE_DIRS="
  370. cli/_all_distributions/main
  371. cli/${RELEASE}/main
  372. "
  373. PACKAGES_SEARCH_ROOT_ABSOLUTE_DIRS="
  374. ${EXTER}/packages
  375. ${EXTER}/config/optional/_any_board/_packages
  376. ${EXTER}/config/optional/architectures/${ARCH}/_packages
  377. ${EXTER}/config/optional/families/${LINUXFAMILY}/_packages
  378. ${EXTER}/config/optional/boards/${BOARD}/_packages
  379. "
  380. DESKTOP_ENVIRONMENTS_SEARCH_RELATIVE_DIRS="
  381. desktop/_all_distributions/environments/_all_environments
  382. desktop/_all_distributions/environments/${DESKTOP_ENVIRONMENT}
  383. desktop/_all_distributions/environments/${DESKTOP_ENVIRONMENT}/${DESKTOP_ENVIRONMENT_CONFIG_NAME}
  384. desktop/${RELEASE}/environments/_all_environments
  385. desktop/${RELEASE}/environments/${DESKTOP_ENVIRONMENT}
  386. desktop/${RELEASE}/environments/${DESKTOP_ENVIRONMENT}/${DESKTOP_ENVIRONMENT_CONFIG_NAME}
  387. "
  388. DESKTOP_APPGROUPS_SEARCH_RELATIVE_DIRS="
  389. desktop/_all_distributions/appgroups
  390. desktop/_all_distributions/environments/${DESKTOP_ENVIRONMENT}/appgroups
  391. desktop/${RELEASE}/appgroups
  392. desktop/${RELEASE}/environments/${DESKTOP_ENVIRONMENT}/appgroups
  393. "
  394. get_all_potential_paths() {
  395. local root_dirs="${AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS}"
  396. local rel_dirs="${1}"
  397. local sub_dirs="${2}"
  398. local looked_up_subpath="${3}"
  399. for root_dir in ${root_dirs}; do
  400. for rel_dir in ${rel_dirs}; do
  401. for sub_dir in ${sub_dirs}; do
  402. potential_paths+="${root_dir}/${rel_dir}/${sub_dir}/${looked_up_subpath} "
  403. done
  404. done
  405. done
  406. # for ppath in ${potential_paths}; do
  407. # echo "Checking for ${ppath}"
  408. # if [[ -f "${ppath}" ]]; then
  409. # echo "OK !|"
  410. # else
  411. # echo "Nope|"
  412. # fi
  413. # done
  414. }
  415. # Environment variables expected :
  416. # - aggregated_content
  417. # Arguments :
  418. # 1. File to look up in each directory
  419. # 2. The separator to add between each concatenated file
  420. # 3. Relative directories paths added to ${3}
  421. # 4. Relative directories paths added to ${4}
  422. #
  423. # The function will basically generate a list of potential paths by
  424. # generating all the potential paths combinations leading to the
  425. # looked up file
  426. # ${AGGREGATION_SEARCH_ROOT_ABSOLUTE_DIRS}/${3}/${4}/${1}
  427. # Then it will concatenate the content of all the available files
  428. # into ${aggregated_content}
  429. #
  430. # TODO :
  431. # ${4} could be removed by just adding the appropriate paths to ${3}
  432. # dynamically for each case
  433. # (debootstrap, cli, desktop environments, desktop appgroups, ...)
  434. aggregate_all_root_rel_sub() {
  435. local separator="${2}"
  436. local potential_paths=""
  437. get_all_potential_paths "${3}" "${4}" "${1}"
  438. aggregate_content
  439. }
  440. aggregate_all_debootstrap() {
  441. local sub_dirs_to_check=". "
  442. if [[ ! -z "${SELECTED_CONFIGURATION+x}" ]]; then
  443. sub_dirs_to_check+="config_${SELECTED_CONFIGURATION}"
  444. fi
  445. aggregate_all_root_rel_sub "${1}" "${2}" "${DEBOOTSTRAP_SEARCH_RELATIVE_DIRS}" "${sub_dirs_to_check}"
  446. }
  447. aggregate_all_cli() {
  448. local sub_dirs_to_check=". "
  449. if [[ ! -z "${SELECTED_CONFIGURATION+x}" ]]; then
  450. sub_dirs_to_check+="config_${SELECTED_CONFIGURATION}"
  451. fi
  452. aggregate_all_root_rel_sub "${1}" "${2}" "${CLI_SEARCH_RELATIVE_DIRS}" "${sub_dirs_to_check}"
  453. }
  454. aggregate_all_desktop() {
  455. aggregate_all_root_rel_sub "${1}" "${2}" "${DESKTOP_ENVIRONMENTS_SEARCH_RELATIVE_DIRS}" "."
  456. aggregate_all_root_rel_sub "${1}" "${2}" "${DESKTOP_APPGROUPS_SEARCH_RELATIVE_DIRS}" "${DESKTOP_APPGROUPS_SELECTED}"
  457. }
  458. one_line() {
  459. local aggregate_func_name="${1}"
  460. local aggregated_content=""
  461. shift 1
  462. $aggregate_func_name "${@}"
  463. cleanup_list aggregated_content
  464. }
  465. DEBOOTSTRAP_LIST="$(one_line aggregate_all_debootstrap "packages" " ")"
  466. DEBOOTSTRAP_COMPONENTS="$(one_line aggregate_all_debootstrap "components" " ")"
  467. DEBOOTSTRAP_COMPONENTS="${DEBOOTSTRAP_COMPONENTS// /,}"
  468. PACKAGE_LIST="$(one_line aggregate_all_cli "packages" " ")"
  469. PACKAGE_LIST_ADDITIONAL="$(one_line aggregate_all_cli "packages.additional" " ")"
  470. LOG_OUTPUT_FILE="$SRC/output/${LOG_SUBPATH}/debootstrap-list.log"
  471. show_checklist_variables "DEBOOTSTRAP_LIST DEBOOTSTRAP_COMPONENTS PACKAGE_LIST PACKAGE_LIST_ADDITIONAL PACKAGE_LIST_UNINSTALL"
  472. # Dependent desktop packages
  473. # Myy : Sources packages from file here
  474. # Myy : FIXME Rename aggregate_all to aggregate_all_desktop
  475. if [[ $BUILD_DESKTOP == "yes" ]]; then
  476. PACKAGE_LIST_DESKTOP+="$(one_line aggregate_all_desktop "packages" " ")"
  477. echo -e "\nGroups selected ${DESKTOP_APPGROUPS_SELECTED} -> PACKAGES :" >> "${LOG_OUTPUT_FILE}"
  478. show_checklist_variables PACKAGE_LIST_DESKTOP
  479. fi
  480. unset LOG_OUTPUT_FILE
  481. DEBIAN_MIRROR='deb.debian.org/debian'
  482. DEBIAN_SECURTY='security.debian.org/'
  483. UBUNTU_MIRROR='ports.ubuntu.com/'
  484. RASPI_MIRROR='archive.raspberrypi.org/debian/'
  485. if [[ $DOWNLOAD_MIRROR == "china" ]] ; then
  486. if [[ ${CHINA_DOWNLOAD_MIRROR} == tsinghua ]]; then
  487. DEBIAN_MIRROR='mirrors.tuna.tsinghua.edu.cn/debian'
  488. DEBIAN_SECURTY='mirrors.tuna.tsinghua.edu.cn/debian-security'
  489. UBUNTU_MIRROR='mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/'
  490. fi
  491. if [[ ${CHINA_DOWNLOAD_MIRROR} == huawei ]]; then
  492. DEBIAN_MIRROR='repo.huaweicloud.com/debian'
  493. DEBIAN_SECURTY='repo.huaweicloud.com/debian-security'
  494. UBUNTU_MIRROR='repo.huaweicloud.com/ubuntu-ports/'
  495. fi
  496. RASPI_MIRROR='mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/'
  497. fi
  498. if [[ $DOWNLOAD_MIRROR == "bfsu" ]] ; then
  499. DEBIAN_MIRROR='mirrors.bfsu.edu.cn/debian'
  500. DEBIAN_SECURTY='mirrors.bfsu.edu.cn/debian-security'
  501. UBUNTU_MIRROR='mirrors.bfsu.edu.cn/ubuntu-ports/'
  502. fi
  503. if [[ "${ARCH}" == "amd64" ]]; then
  504. UBUNTU_MIRROR='archive.ubuntu.com/ubuntu' # ports are only for non-amd64, of course.
  505. if [[ -n ${CUSTOM_UBUNTU_MIRROR} ]]; then # ubuntu redirector doesn't work well on amd64
  506. UBUNTU_MIRROR="${CUSTOM_UBUNTU_MIRROR}"
  507. fi
  508. fi
  509. # don't use mirrors that throws garbage on 404
  510. if [[ -z ${ARMBIAN_MIRROR} ]]; then
  511. while true; do
  512. ARMBIAN_MIRROR=$(wget -SO- -T 1 -t 1 https://redirect.armbian.com 2>&1 | egrep -i "Location" | awk '{print $2}' | head -1)
  513. [[ ${ARMBIAN_MIRROR} != *armbian.hosthatch* ]] && break
  514. done
  515. fi
  516. # For (late) user override.
  517. # Notice: it is too late to define hook functions or add extensions in lib.config, since the extension initialization already ran by now.
  518. # in case the user tries to use them in lib.config, hopefully they'll be detected as "wishful hooking" and the user will be wrn'ed.
  519. if [[ -f $USERPATCHES_PATH/lib.config ]]; then
  520. display_alert "Using user configuration override" "$USERPATCHES_PATH/lib.config" "info"
  521. source "$USERPATCHES_PATH"/lib.config
  522. fi
  523. call_extension_method "user_config" << 'USER_CONFIG'
  524. *Invoke function with user override*
  525. Allows for overriding configuration values set anywhere else.
  526. It is called after sourcing the `lib.config` file if it exists,
  527. but before assembling any package lists.
  528. USER_CONFIG
  529. call_extension_method "extension_prepare_config" << 'EXTENSION_PREPARE_CONFIG'
  530. *allow extensions to prepare their own config, after user config is done*
  531. Implementors should preserve variable values pre-set, but can default values an/or validate them.
  532. This runs *after* user_config. Don't change anything not coming from other variables or meant to be configured by the user.
  533. EXTENSION_PREPARE_CONFIG
  534. # apt-cacher-ng mirror configurarion
  535. if [[ $DISTRIBUTION == Ubuntu ]]; then
  536. APT_MIRROR=$UBUNTU_MIRROR
  537. else
  538. APT_MIRROR=$DEBIAN_MIRROR
  539. fi
  540. [[ -n $APT_PROXY_ADDR ]] && display_alert "Using custom apt-cacher-ng address" "$APT_PROXY_ADDR" "info"
  541. # Build final package list after possible override
  542. PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_RELEASE $PACKAGE_LIST_ADDITIONAL"
  543. PACKAGE_MAIN_LIST="$(cleanup_list PACKAGE_LIST)"
  544. [[ $BUILD_DESKTOP == yes ]] && PACKAGE_LIST="$PACKAGE_LIST $PACKAGE_LIST_DESKTOP"
  545. PACKAGE_LIST="$(cleanup_list PACKAGE_LIST)"
  546. # remove any packages defined in PACKAGE_LIST_RM in lib.config
  547. aggregated_content="${PACKAGE_LIST_RM} "
  548. aggregate_all_cli "packages.remove" " "
  549. aggregate_all_desktop "packages.remove" " "
  550. PACKAGE_LIST_RM="$(cleanup_list aggregated_content)"
  551. unset aggregated_content
  552. aggregated_content=""
  553. aggregate_all_cli "packages.uninstall" " "
  554. aggregate_all_desktop "packages.uninstall" " "
  555. PACKAGE_LIST_UNINSTALL="$(cleanup_list aggregated_content)"
  556. unset aggregated_content
  557. if [[ -n $PACKAGE_LIST_RM ]]; then
  558. display_alert "Package remove list ${PACKAGE_LIST_RM}"
  559. # Turns out that \b can be tricked by dashes.
  560. # So if you remove mesa-utils but still want to install "mesa-utils-extra"
  561. # a "\b(mesa-utils)\b" filter will convert "mesa-utils-extra" to "-extra".
  562. # \W is not tricked by this but consumes the surrounding spaces, so we
  563. # replace the occurence by one space, to avoid sticking the next word to
  564. # the previous one after consuming the spaces.
  565. DEBOOTSTRAP_LIST=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${DEBOOTSTRAP_LIST} ")
  566. PACKAGE_LIST=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${PACKAGE_LIST} ")
  567. PACKAGE_MAIN_LIST=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${PACKAGE_MAIN_LIST} ")
  568. if [[ $BUILD_DESKTOP == "yes" ]]; then
  569. PACKAGE_LIST_DESKTOP=$(sed -r "s/\W($(tr ' ' '|' <<< ${PACKAGE_LIST_RM}))\W/ /g" <<< " ${PACKAGE_LIST_DESKTOP} ")
  570. # Removing double spaces... AGAIN, since we might have used a sed on them
  571. # Do not quote the variables. This would defeat the trick.
  572. PACKAGE_LIST_DESKTOP="$(echo ${PACKAGE_LIST_DESKTOP})"
  573. fi
  574. # Removing double spaces... AGAIN, since we might have used a sed on them
  575. # Do not quote the variables. This would defeat the trick.
  576. DEBOOTSTRAP_LIST="$(echo ${DEBOOTSTRAP_LIST})"
  577. PACKAGE_LIST="$(echo ${PACKAGE_LIST})"
  578. PACKAGE_MAIN_LIST="$(echo ${PACKAGE_MAIN_LIST})"
  579. fi
  580. LOG_OUTPUT_FILE="$SRC/output/${LOG_SUBPATH}/debootstrap-list.log"
  581. echo -e "\nVariables after manual configuration" >>$LOG_OUTPUT_FILE
  582. show_checklist_variables "DEBOOTSTRAP_COMPONENTS DEBOOTSTRAP_LIST PACKAGE_LIST PACKAGE_MAIN_LIST"
  583. unset LOG_OUTPUT_FILE
  584. # Give the option to configure DNS server used in the chroot during the build process
  585. [[ -z $NAMESERVER ]] && NAMESERVER="1.0.0.1" # default is cloudflare alternate
  586. call_extension_method "post_aggregate_packages" "user_config_post_aggregate_packages" << 'POST_AGGREGATE_PACKAGES'
  587. *For final user override, using a function, after all aggregations are done*
  588. Called after aggregating all package lists, before the end of `compilation.sh`.
  589. Packages will still be installed after this is called, so it is the last chance
  590. to confirm or change any packages.
  591. POST_AGGREGATE_PACKAGES
  592. # debug
  593. cat <<-EOF >> "${DEST}"/${LOG_SUBPATH}/output.log
  594. ## BUILD SCRIPT ENVIRONMENT
  595. Repository: $REPOSITORY_URL
  596. Version: $REPOSITORY_COMMIT
  597. Host OS: $HOSTRELEASE
  598. Host arch: $(dpkg --print-architecture)
  599. Host system: $(uname -a)
  600. Virtualization type: $(systemd-detect-virt)
  601. ## Build script directories
  602. Build directory is located on:
  603. $(findmnt -o TARGET,SOURCE,FSTYPE,AVAIL -T "${SRC}")
  604. Build directory permissions:
  605. $(getfacl -p "${SRC}")
  606. Temp directory permissions:
  607. $(getfacl -p "${SRC}"/.tmp 2> /dev/null)
  608. ## BUILD CONFIGURATION
  609. Build target:
  610. Board: $BOARD
  611. Branch: $BRANCH
  612. Minimal: $BUILD_MINIMAL
  613. Desktop: $BUILD_DESKTOP
  614. Desktop Environment: $DESKTOP_ENVIRONMENT
  615. Software groups: $DESKTOP_APPGROUPS_SELECTED
  616. Kernel configuration:
  617. Repository: $KERNELSOURCE
  618. Branch: $KERNELBRANCH
  619. Config file: $LINUXCONFIG
  620. U-boot configuration:
  621. Repository: $BOOTSOURCE
  622. Branch: $BOOTBRANCH
  623. Config file: $BOOTCONFIG
  624. Partitioning configuration: $IMAGE_PARTITION_TABLE offset: $OFFSET
  625. Boot partition type: ${BOOTFS_TYPE:-(none)} ${BOOTSIZE:+"(${BOOTSIZE} MB)"}
  626. Root partition type: $ROOTFS_TYPE ${FIXED_IMAGE_SIZE:+"(${FIXED_IMAGE_SIZE} MB)"}
  627. CPU configuration: $CPUMIN - $CPUMAX with $GOVERNOR
  628. EOF