.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_CN.rst :Original: Documentation/kbuild/reproducible-builds.rst :Translator: 慕冬亮 Dongliang Mu <dzm91@hust.edu.cn> ============ å¯é‡çŽ°çš„构建 ============ 通常希望使用相åŒå·¥å…·é›†æž„建相åŒæºä»£ç 是å¯é‡çŽ°çš„,å³ï¼Œè¾“出始终完全相åŒã€‚è¿™ä½¿å¾—èƒ½å¤ŸéªŒè¯ äºŒè¿›åˆ¶åˆ†å‘或嵌入å¼ç³»ç»Ÿçš„æž„å»ºåŸºç¡€è®¾æ–½æœªè¢«ç¯¡æ”¹ã€‚è¿™æ ·ä¹Ÿæ›´å®¹æ˜“éªŒè¯æºä»£ç 或工具的更改ä¸ä¼š å½±å“最终生æˆçš„二进制文件。 `å¯é‡çŽ°æž„建项目`_ æ供了有关该主题的更多信æ¯ã€‚æœ¬æ–‡æ¡£æ¶µç›–äº†æž„å»ºå†…æ ¸å¯èƒ½ä¸å¯é‡çŽ°çš„ å„ç§åŽŸå› ,以åŠå¦‚何é¿å…这些问题。 时间戳 ------ å†…æ ¸åœ¨ä¸‰ä¸ªåœ°æ–¹åµŒå…¥æ—¶é—´æˆ³ï¼š * 通过 ``uname()`` 显示与包å«åœ¨ ``/proc/version`` ä¸çš„版本å—符串 * initramfs ä¸çš„文件时间戳 * 如果å¯åŠ¨ ``CONFIG_IKHEADERS``ï¼Œå†…æ ¸æˆ–ç›¸åº”æ¨¡å—ä¸åµŒå…¥çš„å†…æ ¸å¤´æ–‡ä»¶çš„æ—¶é—´æˆ³ï¼Œ 通过 ``/sys/kernel/kheaders.tar.xz`` 显示 默认情况下,时间戳为当å‰æ—¶é—´æˆ–å†…æ ¸å¤´æ–‡ä»¶çš„ä¿®æ”¹æ—¶é—´ã€‚è¿™ä¸ªå†…å®¹å¿…é¡»ä½¿ç”¨ `KBUILD_BUILD_TIMESTAMP`_ å˜é‡è¿›è¡Œè¦†ç›–ã€‚å¦‚æžœä½ ä»ŽæŸä¸ª git æ交进行构建, å¯ä»¥ä½¿ç”¨å…¶æ交日期。 å†…æ ¸ *ä¸* 使用 ``__DATE__`` å’Œ ``__TIME__`` å®ï¼Œå¹¶åœ¨ä½¿ç”¨è¿™äº›å®æ—¶å¯ç”¨è¦å‘Šã€‚ å¦‚æžœä½ åˆå¹¶çš„外部代ç 使用这些å®ï¼Œåˆ™å¿…须通过设置 `SOURCE_DATE_EPOCH`_ 环境 å˜é‡æ¥è¦†ç›–它们对应的时间戳。 用户,主机 ---------- å†…æ ¸åœ¨ ``/proc/version`` ä¸åµŒå…¥æž„建用户和主机å。必须使用 `KBUILD_BUILD_USER å’Œ KBUILD_BUILD_HOST`_ å˜é‡æ¥è¦†ç›–这些设置。如果 您从æŸä¸ª git æ交进行构建,å¯ä»¥ä½¿ç”¨å…¶æ交者地å€ã€‚ ç»å¯¹æ–‡ä»¶å ---------- å½“å†…æ ¸åœ¨æ ‘å¤–æž„å»ºæ—¶ï¼Œè°ƒè¯•ä¿¡æ¯å¯èƒ½åŒ…括æºæ–‡ä»¶çš„ç»å¯¹æ–‡ä»¶å。这些信æ¯å¿…须通过在 `KCFLAGS`_ å˜é‡ä¸åŒ…å« ``-fdebug-prefix-map`` 选项æ¥è¦†ç›–。 æ ¹æ®ä½¿ç”¨çš„编译器,``__FILE__`` å®åœ¨æ ‘外构建ä¸ä¹Ÿå¯èƒ½æ‰©å±•ä¸ºç»å¯¹æ–‡ä»¶å。Kbuild 自动使用 ``-fmacro-prefix-map`` 选项æ¥é˜²æ¢è¿™ç§æƒ…况,å‰æ是它被支æŒã€‚ å¯é‡çŽ°æž„建网站æ供了有关这些 `prefix-map 选项`_ 的更多信æ¯ã€‚ 在æºåŒ…ä¸çš„生æˆæ–‡ä»¶ ------------------ 在 ``tools/`` å目录下,一些程åºçš„构建过程并ä¸å®Œå…¨æ”¯æŒæ ‘外构建。这å¯èƒ½å¯¼è‡´åŽç» 使用如 ``make rpm-pkg`` 构建的æºç 包包å«ç”Ÿæˆçš„文件。在构建æºç 包之å‰ï¼Œæ‚¨åº”该通过 è¿è¡Œ ``make mrproper`` 或 ``git clean -d -f -x`` æ¥ç¡®ä¿æºç æ ‘æ˜¯å¹²å‡€çš„ã€‚ 模å—ç¾å -------- å¦‚æžœä½ å¯ç”¨ ``CONFIG_MODULE_SIG_ALL``,默认行为是为æ¯æ¬¡æž„建生æˆä¸åŒçš„临时密钥, 从而导致模å—ä¸å¯é‡çŽ°ã€‚然而,将ç¾å密钥包å«åœ¨æºä»£ç ä¸æ˜¾ç„¶ä¼šè¿èƒŒç¾å模å—的目的。 一ç§æ–¹æ³•æ˜¯å°†æž„å»ºè¿‡ç¨‹åˆ†ä¸ºå‡ ä¸ªéƒ¨åˆ†ï¼Œä»¥ä¾¿ä¸å¯é‡çŽ°çš„部分å¯ä»¥ä½œä¸ºæºå¤„ç†ï¼š 1. 生æˆä¸€ä¸ªæŒä¹…çš„ç¾å密钥。将该密钥的è¯ä¹¦æ·»åŠ åˆ°å†…æ ¸æºä»£ç ä¸ã€‚ 2. å°† ``CONFIG_SYSTEM_TRUSTED_KEYS`` 符å·è®¾ç½®ä¸ºåŒ…括ç¾å密钥的è¯ä¹¦ï¼Œå°† ``CONFIG_MODULE_SIG_KEY`` 设置为空å—符串,并ç¦ç”¨ ``CONFIG_MODULE_SIG_ALL``。 最åŽï¼Œæž„å»ºå†…æ ¸å’Œæ¨¡å—。 3. 为模å—创建分离的ç¾å,并将它们作为æºå‘布。 4. é™„åŠ æ¨¡å—ç¾å并进行第二次构建。这å¯ä»¥é‡å»ºæ¨¡å—,或使用æ¥éª¤ 2 的输出。 结构éšæœºåŒ– ---------- å¦‚æžœä½ å¯ç”¨ ``CONFIG_RANDSTRUCT``,则需è¦åœ¨ ``scripts/basic/randstruct.seed`` ä¸é¢„生æˆéšæœºç§å,以便æ¯æ¬¡æž„建都使用相åŒçš„值。有关详细信æ¯ï¼Œè¯·å‚è§ ``scripts/gen-randstruct-seed.sh``。 调试信æ¯å†²çª ------------ 这并éžæ˜¯ä¸ªä¸å¯é‡çŽ°æ€§çš„问题,而是生æˆçš„文件 *过于* å¯é‡çŽ°çš„问题。 ä¸€æ—¦ä½ è®¾ç½®äº†æ‰€æœ‰å¿…è¦çš„å˜é‡æ¥å¼€å±•å¯é‡çŽ°æž„建,vDSO 的调试信æ¯å¯èƒ½å³ä½¿å¯¹äºŽä¸åŒçš„å†…æ ¸ç‰ˆ 本也是相åŒçš„。这会导致ä¸åŒå†…æ ¸ç‰ˆæœ¬çš„è°ƒè¯•ä¿¡æ¯è½¯ä»¶åŒ…之间å‘生文件冲çªã€‚ 为了é¿å…è¿™ç§æƒ…å†µï¼Œä½ å¯ä»¥é€šè¿‡åœ¨ vDSO ä¸åŒ…å«ä¸€ä¸ªä»»æ„çš„ salt å—符串,使其对于ä¸åŒçš„ å†…æ ¸ç‰ˆæœ¬æ˜¯ä¸åŒçš„。这ç§æœºåˆ¶ç”± Kconfig ç¬¦å· ``CONFIG_BUILD_SALT`` 指定。 Git --- 未æ交的更改或 Git ä¸çš„ä¸åŒæ交 ID 也å¯èƒ½å¯¼è‡´ä¸åŒçš„编译结果。例如,在执行 ``git reset HEAD^`` åŽï¼Œå³ä½¿ä»£ç 相åŒï¼Œç¼–译期间生æˆçš„ ``include/config/kernel.release`` 也会ä¸åŒï¼Œå¯¼è‡´æœ€ç»ˆç”Ÿæˆçš„二进制文件也ä¸å°½ç›¸åŒã€‚ 有关详细信æ¯ï¼Œè¯·å‚è§ ``scripts/setlocalversion``。 .. _KBUILD_BUILD_TIMESTAMP: kbuild.html#kbuild-build-timestamp .. _KBUILD_BUILD_USER å’Œ KBUILD_BUILD_HOST: kbuild.html#kbuild-build-user-kbuild-build-host .. _KCFLAGS: kbuild.html#kcflags .. _prefix-map 选项: https://reproducible-builds.org/docs/build-path/ .. _å¯é‡çŽ°æž„建项目: https://reproducible-builds.org/ .. _SOURCE_DATE_EPOCH: https://reproducible-builds.org/docs/source-date-epoch/