已合并
feat: add asc-comm development run package #61
Hyunbin创建于 7月31日
feat: add asc-comm development run package #61
已合并
Hyunbin创建于 7月31日
共 13 个文件变更+2284-5
@@ -1,4 +1,5 @@
1build/1build/
2+build_out/
2oat_reports/3oat_reports/
3log/4log/
4AGENTS.md5AGENTS.md
MOAT.xml+2-0
@@ -23,6 +23,7 @@
23 </filefilter>23 </filefilter>
24 <filefilter name="defaultPolicyFilter" desc="Filters for compatibility, license header policies">24 <filefilter name="defaultPolicyFilter" desc="Filters for compatibility, license header policies">
25 <filteritem type="filename" name="*.gitignore" desc="git ignore file"/>25 <filteritem type="filename" name="*.gitignore" desc="git ignore file"/>
26+ <filteritem type="filename" name="*.info" desc="metadata file"/>
26 <filteritem type="filename" name="*.md" desc="documentation file"/>27 <filteritem type="filename" name="*.md" desc="documentation file"/>
27 <filteritem type="filename" name="*.xml" desc="configuration file"/>28 <filteritem type="filename" name="*.xml" desc="configuration file"/>
28 <filteritem type="filename" name="*.yaml" desc="configuration file"/>29 <filteritem type="filename" name="*.yaml" desc="configuration file"/>
@@ -36,6 +37,7 @@
36 </filefilter>37 </filefilter>
37 <filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">38 <filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">
38 <filteritem type="filename" name="*.gitignore" desc="git ignore file"/>39 <filteritem type="filename" name="*.gitignore" desc="git ignore file"/>
40+ <filteritem type="filename" name="*.info" desc="metadata file"/>
39 <filteritem type="filename" name="*.md" desc="documentation file"/>41 <filteritem type="filename" name="*.md" desc="documentation file"/>
40 <filteritem type="filename" name="*.xml" desc="configuration file"/>42 <filteritem type="filename" name="*.xml" desc="configuration file"/>
41 <filteritem type="filename" name="*.yaml" desc="configuration file"/>43 <filteritem type="filename" name="*.yaml" desc="configuration file"/>
MREADME.md+10-1
@@ -157,6 +157,15 @@ bash build.sh --make_clean
157bash build.sh -t157bash build.sh -t
158```158```
159 159 
160+将仓库中当前Hcomm与Ain头文件制作为开发验证run包,并安装到已有CANN环境:
161+ 
162+```bash
163+bash build.sh --pkg
164+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --full
165+```
166+ 
167+制包脚本会递归收集`include/aicore/hcomm/`、`src/aicore/hcomm/`、`include/aicore/ain/`和`src/aicore/ain/`中的头文件,目录映射及Hcomm软链与asc-devkit当前出包逻辑一致。安装时会备份目标CANN中的原文件和软链状态;对于安装前不存在的新增内容,卸载时会将其删除。详细的目录映射、参数和限制见[构建与测试](./docs/zh/guide/build_and_test.md)。
168+ 
160如需直接使用CMake构建UT,可指定CANN三方依赖目录:169如需直接使用CMake构建UT,可指定CANN三方依赖目录:
161 170 
162```bash171```bash
@@ -183,7 +192,7 @@ cmake --build build/ut-hcomm
183 | [快速开始](./docs/quick_start.md) | 环境准备、源码编译和UT验证。 |192 | [快速开始](./docs/quick_start.md) | 环境准备、源码编译和UT验证。 |
184 | [API参考](./docs/zh/api/README.md) | asc-comm当前公开接口列表。 |193 | [API参考](./docs/zh/api/README.md) | asc-comm当前公开接口列表。 |
185 | [Hcomm使用说明](./docs/zh/guide/hcomm_usage.md) | Hcomm点对点通信接口的基本使用流程。 |194 | [Hcomm使用说明](./docs/zh/guide/hcomm_usage.md) | Hcomm点对点通信接口的基本使用流程。 |
186- | [构建与测试](./docs/zh/guide/build_and_test.md) | CANN环境、构建脚本、UT构建和样例构建说明。 |195+ | [构建与测试](./docs/zh/guide/build_and_test.md) | CANN环境、开发验证run包、UT构建和样例构建说明。 |
187 | [三方依赖与兼容性](./docs/zh/guide/dependencies.md) | 本仓直接依赖、样例运行依赖、安装配置和集成依赖边界。 |196 | [三方依赖与兼容性](./docs/zh/guide/dependencies.md) | 本仓直接依赖、样例运行依赖、安装配置和集成依赖边界。 |
188 | [样例目录](./examples/README.md) | asc-comm API样例入口。 |197 | [样例目录](./examples/README.md) | asc-comm API样例入口。 |
189 198 
@@ -138,6 +138,15 @@ Build and execute Hcomm and Ain unit tests:
138bash build.sh -t138bash build.sh -t
139```139```
140 140 
141+Build the current Hcomm and Ain headers into a development run package and install it into an existing CANN environment:
142+ 
143+```bash
144+bash build.sh --pkg
145+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --full
146+```
147+ 
148+The packaging script recursively collects headers under `include/aicore/hcomm/`, `src/aicore/hcomm/`, `include/aicore/ain/`, and `src/aicore/ain/`. Its directory mapping and Hcomm symbolic links match the current asc-devkit packaging logic. Installation backs up existing target files and link state, while content that did not exist before installation is removed during uninstallation. See [Build & Test](./docs/en/guide/build_and_test.md) for directory mappings, options, and limitations.
149+ 
141To build UTs directly via CMake, specify the CANN third-party library path:150To build UTs directly via CMake, specify the CANN third-party library path:
142```bash151```bash
143cmake -S tests/ut -B build/ut-hcomm -DCANN_3RD_LIB_PATH=<third_party_path>152cmake -S tests/ut -B build/ut-hcomm -DCANN_3RD_LIB_PATH=<third_party_path>
@@ -161,7 +170,7 @@ See [Quick Start](./docs/quick_start_en.md) and [Build & Test](./docs/en/guide/b
161 | [Quick Start](./docs/quick_start_en.md) | Environment setup, source compilation and UT verification. |170 | [Quick Start](./docs/quick_start_en.md) | Environment setup, source compilation and UT verification. |
162 | [API Reference](./docs/en/api/README.md) | List of published asc-comm interfaces. |171 | [API Reference](./docs/en/api/README.md) | List of published asc-comm interfaces. |
163 | [Hcomm Usage Guide](./docs/en/guide/hcomm_usage.md) | Basic workflow for Hcomm point-to-point communication interfaces. |172 | [Hcomm Usage Guide](./docs/en/guide/hcomm_usage.md) | Basic workflow for Hcomm point-to-point communication interfaces. |
164- | [Build & Test](./docs/en/guide/build_and_test.md) | CANN environment, build scripts, UT and sample build instructions. |173+ | [Build & Test](./docs/en/guide/build_and_test.md) | CANN environment, development run package, UT and sample build instructions. |
165 | [Third-party Dependencies & Compatibility](./docs/en/guide/dependencies.md) | Direct dependencies, sample runtime dependencies, installation configuration and integration boundaries. |174 | [Third-party Dependencies & Compatibility](./docs/en/guide/dependencies.md) | Direct dependencies, sample runtime dependencies, installation configuration and integration boundaries. |
166 | [Samples Directory](./examples/README_en.md) | Entry point for asc-comm API samples. |175 | [Samples Directory](./examples/README_en.md) | Entry point for asc-comm API samples. |
167 176 
Mbuild.sh+14-1
@@ -31,6 +31,7 @@ dotted_line="----------------------------------------"
31 31 
32TEST=false32TEST=false
33COV=false33COV=false
34+PACKAGE=false
34 35 
35LOG_LEVEL=036LOG_LEVEL=0
36 37 
@@ -84,6 +85,7 @@ usage() {
84 echo "$dotted_line"85 echo "$dotted_line"
85 echo " -h, --help Display help information"86 echo " -h, --help Display help information"
86 echo " -t, --test Build and run all unit tests"87 echo " -t, --test Build and run all unit tests"
88+ echo " --pkg, --package Build an asc-comm development run package"
87 echo " --cov Enable code coverage for unit tests"89 echo " --cov Enable code coverage for unit tests"
88 echo " --make_clean Clean build artifacts"90 echo " --make_clean Clean build artifacts"
89 echo " --cann_3rd_lib_path=<PATH>"91 echo " --cann_3rd_lib_path=<PATH>"
@@ -101,6 +103,10 @@ parse_args() {
101 TEST=true103 TEST=true
102 shift104 shift
103 ;;105 ;;
106+ --pkg|--package)
107+ PACKAGE=true
108+ shift
109+ ;;
104 --cov)110 --cov)
105 COV=true111 COV=true
106 shift112 shift
@@ -164,8 +170,15 @@ main(){
164 echo "${CUSTOM_OPTION[@]}"170 echo "${CUSTOM_OPTION[@]}"
165 local ut_build_dir="${BUILD_DIR}/ut-hcomm"171 local ut_build_dir="${BUILD_DIR}/ut-hcomm"
166 172 
173+ if [[ "${PACKAGE}" == true ]]; then
174+ bash "${SCRIPT_DIR}/scripts/package/build_package.sh" \
175+ --cann-path="${Ascend_CANN_PACKAGE_PATH}" || return $?
176+ fi
177+ 
167 if [[ "${TEST}" != true ]]; then178 if [[ "${TEST}" != true ]]; then
168- log "INFO" "use -t/--test to build hcomm UT"179+ if [[ "${PACKAGE}" != true ]]; then
180+ log "INFO" "use -t/--test to build hcomm UT"
181+ fi
169 exit 0182 exit 0
atomgit-bot
atomgit-botatomgit-bot7月31日

🟡 Medium Priority

build.sh 没有 set -e,当仅使用 --pkg(不带 -t)且 build_package.sh 执行失败时,build.sh 在第 193 行以硬编码的 exit 0 退出,吞掉了制包失败的错误码。这会导致 CI/脚本无法检测到制包失败。

触发条件:bash build.sh --pkg 时 build_package.sh 因任何原因失败(CANN 路径无效、makeself 未找到、头文件缺失、版本号格式错误等)。

失败模式:build_package.sh 向 stderr 输出了错误信息,但 build.sh 仍然返回退出码 0,调用方误以为成功。

建议:在调用 build_package.sh 后检查返回值:将 bash ... 改为 bash ... || exit 1,或在整个 build.sh 顶部添加 set -e(需评估对原有逻辑的影响)。

改动建议
182
+ if [[ "${PACKAGE}" == true ]]; then
183
+ bash "${SCRIPT_DIR}/scripts/package/build_package.sh" \
184
+ --cann-path="${Ascend_CANN_PACKAGE_PATH}" || exit 1
182
- exit 0
185
+ fi
应用建议
likedislike
不准确?
Hyunbin
Hyunbin
8月18日 评论:
170 fi183 fi
171 184 
@@ -20,7 +20,7 @@ docs/
20| [快速开始](./quick_start.md) | asc-comm环境准备、源码编译和UT验证。 |20| [快速开始](./quick_start.md) | asc-comm环境准备、源码编译和UT验证。 |
21| [API参考](./zh/api/README.md) | asc-comm当前公开接口列表。 |21| [API参考](./zh/api/README.md) | asc-comm当前公开接口列表。 |
22| [Hcomm使用说明](./zh/guide/hcomm_usage.md) | Hcomm点对点通信接口的基本使用流程。 |22| [Hcomm使用说明](./zh/guide/hcomm_usage.md) | Hcomm点对点通信接口的基本使用流程。 |
23-| [构建与测试](./zh/guide/build_and_test.md) | CANN环境、构建脚本、UT构建和样例构建说明。 |23+| [构建与测试](./zh/guide/build_and_test.md) | CANN环境、开发验证run包、UT构建和样例构建说明。 |
24| [三方依赖与兼容性](./zh/guide/dependencies.md) | 本仓直接依赖、样例运行依赖、安装配置和集成依赖边界。 |24| [三方依赖与兼容性](./zh/guide/dependencies.md) | 本仓直接依赖、样例运行依赖、安装配置和集成依赖边界。 |
25| [API文档贡献指南](./api_contributing.md) | 新增或修改API文档时的结构、约束和检查要求。 |25| [API文档贡献指南](./api_contributing.md) | 新增或修改API文档时的结构、约束和检查要求。 |
26| [资料贡献指南](./doc_contributing.md) | README、docs、examples等资料文档的补充规范。 |26| [资料贡献指南](./doc_contributing.md) | README、docs、examples等资料文档的补充规范。 |
@@ -18,7 +18,7 @@ docs/
18| [Quick Start](./quick_start_en.md) | Environment setup, source compilation and UT verification for asc-comm. |18| [Quick Start](./quick_start_en.md) | Environment setup, source compilation and UT verification for asc-comm. |
19| [API Reference](./en/api/README.md) | List of currently published asc-comm APIs. |19| [API Reference](./en/api/README.md) | List of currently published asc-comm APIs. |
20| [Hcomm Usage Guide](./en/guide/hcomm_usage.md) | Basic workflow for Hcomm point-to-point communication interfaces. |20| [Hcomm Usage Guide](./en/guide/hcomm_usage.md) | Basic workflow for Hcomm point-to-point communication interfaces. |
21-| [Build & Test](./en/guide/build_and_test.md) | CANN environment, build scripts, UT compilation and sample build instructions. |21+| [Build & Test](./en/guide/build_and_test.md) | CANN environment, development run package, UT compilation and sample build instructions. |
22| [Third-party Dependencies & Compatibility](./en/guide/dependencies.md) | Direct repository dependencies, sample runtime dependencies, installation configuration and integration boundaries. |22| [Third-party Dependencies & Compatibility](./en/guide/dependencies.md) | Direct repository dependencies, sample runtime dependencies, installation configuration and integration boundaries. |
23| [API Documentation Contribution Guide](./api_contributing_en.md) | Structure, constraints and checklist for adding or updating API documents. |23| [API Documentation Contribution Guide](./api_contributing_en.md) | Structure, constraints and checklist for adding or updating API documents. |
24| [Documentation Contribution Guide](./doc_contributing_en.md) | Standards for maintaining README, docs, examples and other documentation. |24| [Documentation Contribution Guide](./doc_contributing_en.md) | Standards for maintaining README, docs, examples and other documentation. |
@@ -31,6 +31,129 @@ Default build directory:
31build/ut-hcomm31build/ut-hcomm
32```32```
33 33 
34+## Build a Development Run Package
35+ 
36+After modifying Hcomm or Ain headers locally, build a lightweight development package to install the relevant headers from the current worktree into an existing CANN environment without rebuilding the complete toolkit package:
37+ 
38+```bash
39+bash build.sh --pkg
40+```
41+ 
42+The generated file is placed in `build_out/` by default:
43+ 
44+```text
45+cann-asc-comm_1.0.0_linux-<arch>.run
46+```
47+ 
48+`<arch>` is `aarch64` or `x86_64`. At packaging time, every `.h` file under the following directories is collected recursively:
49+ 
50+| Repository scan directory | CANN installation directory |
51+| --- | --- |
52+| `include/aicore/hcomm/` | `asc/include/adv_api/hcomm/` |
53+| `src/aicore/hcomm/` | `asc/impl/adv_api/detail/hcomm/` |
54+| `include/aicore/ain/` | `asc/include/comm_api/aicore/ain/` |
55+| `src/aicore/ain/` | `asc/impl/comm_api/aicore/ain/` |
56+ 
57+This mapping matches the current packaging rules in asc-devkit's `cmake/third_party/asc-comm.cmake`, and relative subdirectories within each source directory are preserved. Installation also creates these Hcomm symbolic links:
58+ 
59+```text
60+asc/include/comm_api/aicore/hcomm -> ../../adv_api/hcomm
61+asc/impl/comm_api/aicore/hcomm -> ../../adv_api/detail/hcomm
62+```
63+ 
64+Consequently, a new `.h` file under any scan directory is automatically included the next time the package is built. File names, source file counts, and installed file counts are not fixed; other file types are excluded. The package manifest describes only headers present at packaging time and does not represent a complete mirror of the target directories. On a first installation, a path already deleted or renamed in the repository is absent from the manifest, so the installer cannot remove the corresponding old path from CANN. Do not rely solely on this run package to verify the final directory state of deletions or renames.
65+ 
66+Common options are listed below:
67+ 
68+| Option | Description |
69+| --- | --- |
70+| `--full` | Install or update all packaged Hcomm and Ain headers and Hcomm links in full mode. |
71+| `--uninstall` | Restore original files from the baseline and remove files that were previously absent. |
72+| `--check` | Verify the run archive, payload, and dependency compatibility without modifying CANN. |
73+| `--install-path=<PATH>` | Select the Ascend installation root; defaults to `/usr/local/Ascend` for root or `$HOME/Ascend` for non-root users. |
74+| `--force` | Override installed-patch file consistency checks. |
75+| `--list` | List files in the run package; provided by the makeself wrapper. |
76+| `-h`, `--help` | Display help information. |
77+ 
78+`--full`, `--uninstall`, and `--check` are mutually exclusive operations; specify exactly one at a time.
79+ 
80+### Inspect the Package
81+ 
82+Before installation, verify the archive and payload checksums and print the package version, source commit, architecture, required asc-devkit, hcomm, and runtime versions, and file count. This does not modify CANN:
83+ 
84+```bash
85+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --check
86+```
87+ 
88+List the files embedded in the run package:
89+ 
90+```bash
91+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --list
92+```
93+ 
94+### Install and Uninstall
95+ 
96+Install into the default Ascend root:
97+ 
98+```bash
99+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --full
100+```
101+ 
102+Alternatively, select an installation location with an absolute path:
103+ 
104+```bash
105+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run \
106+ --full --install-path=/path/to/cann
107+```
108+ 
109+The installer tries the `--install-path` value itself, `<install-path>/cann`, and `<install-path>/ascend-toolkit/latest` as the CANN root. The resolved directory must contain `asc/include/adv_api/`, `asc/impl/adv_api/detail/`, and `share/info/`. The current user must own the resolved CANN root.
110+ 
111+On the first installation, baseline state is stored under the resolved CANN root:
112+ 
113+```text
114+var/asc-comm-dev-patch/baseline/
115+```
116+ 
117+- If a target file already exists, the installer saves the original before replacement. Uninstallation restores the original file and its permissions.
118+- If a target file does not exist, the installer records it as `absent` before creating it. Uninstallation removes that file.
119+- For a non-root installation, AICore Hcomm and Ain files use mode `550`, Hcomm directories use mode `750`, and managed directories under `comm_api` use mode `550`. Consistent with the devkit and hcomm packages, a root installation automatically enables access for all users and changes these modes to `555`, `755`, and `555`, respectively. The installer records original directory permissions; reinstallation, uninstallation, or failed-operation rollback restores them without recursively changing unrelated directories.
120+- The installer records whether each Hcomm link existed before the first installation. Uninstallation preserves a pre-existing correct link and removes a link created by this package. A wrong-target link, regular file, or directory occupying either link path is never overwritten.
121+- On repeated installation into the same CANN directory, the installer first restores the previous patch and then rebuilds the baseline for the new package from the restored CANN tree. Files from the previous patch are never saved as originals.
122+- If a path from the previous asc-comm patch is absent from a new package, repeated installation restores that path and stops managing it; later uninstallation does not touch it. The installer cannot handle an old CANN file that was never recorded by a patch and is also absent from the current package.
123+ 
124+Restore the files to their pre-installation state. If `--install-path` was used for installation, pass the same path when uninstalling:
125+ 
126+```bash
127+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --uninstall
128+# Corresponding command for an installation with an explicit path
129+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run \
130+ --uninstall --install-path=/path/to/cann
131+```
132+ 
133+The package records the major and minor versions of asc-devkit, hcomm, and runtime, as well as the system architecture, at build time. Installation requires a matching system architecture. Incompatible dependency versions follow the CANN package convention: a warning is emitted and installation continues. Before a repeated installation or uninstallation, the installer also verifies the currently installed patch files so that direct modifications under CANN are not silently overwritten or discarded.
134+ 
135+Use `--force` only when the overwrite risk is understood. During installation, it can override modifications to installed patch files. During uninstallation, it can discard modifications to installed patch files and restore the baseline. `--force` cannot override the system architecture check or payload checksum verification.
136+ 
137+Install, upgrade, and uninstall operations write logs using the CANN package convention. Root writes under `/var/log/ascend_seclog`, while non-root users write under `$HOME/var/log/ascend_seclog`. Process logs are appended to `ascend_install.log`, and operation audit records are appended to `operation.log`.
138+ 
139+After installation, recompile the target Ascend C kernel before verification. Existing `.o` and `.bin` files are not updated automatically.
140+ 
141+To specify the package version, output directory, and CANN environment used for packaging, invoke the packaging script directly:
142+ 
143+```bash
144+bash scripts/package/build_package.sh \
145+ --cann-path=/path/to/cann \
146+ --package-version=1.0.0 \
147+ --output-dir=/path/to/output
148+```
149+ 
150+To verify installation, repeated installation, file protection, and uninstall restoration against a temporary CANN directory:
151+ 
152+```bash
153+bash tests/package/test_run_package.sh \
154+ build_out/cann-asc-comm_1.0.0_linux-<arch>.run
155+```
156+ 
34## CMake Entry157## CMake Entry
35The CMake entry for unit tests is:158The CMake entry for unit tests is:
36```text159```text
@@ -37,6 +37,129 @@ bash build.sh -t
37build/ut-hcomm37build/ut-hcomm
38```38```
39 39 
40+## 构建开发验证run包
41+ 
42+本地修改Hcomm或Ain头文件后,可生成轻量开发验证包,将当前工作树中的相关头文件安装到已有CANN环境,无需重新生成完整toolkit包:
43+ 
44+```bash
45+bash build.sh --pkg
46+```
47+ 
48+生成文件默认位于`build_out/`:
49+ 
50+```text
51+cann-asc-comm_1.0.0_linux-<arch>.run
52+```
53+ 
54+其中`<arch>`为`aarch64`或`x86_64`。制包时会递归扫描以下目录中的全部`.h`文件:
55+ 
56+| 仓库扫描目录 | CANN安装目录 |
57+| --- | --- |
58+| `include/aicore/hcomm/` | `asc/include/adv_api/hcomm/` |
59+| `src/aicore/hcomm/` | `asc/impl/adv_api/detail/hcomm/` |
60+| `include/aicore/ain/` | `asc/include/comm_api/aicore/ain/` |
61+| `src/aicore/ain/` | `asc/impl/comm_api/aicore/ain/` |
62+ 
63+该映射与asc-devkit当前`cmake/third_party/asc-comm.cmake`中的出包规则一致,各扫描目录内部的相对目录结构会保留。安装时还会创建以下Hcomm软链:
64+ 
65+```text
66+asc/include/comm_api/aicore/hcomm -> ../../adv_api/hcomm
67+asc/impl/comm_api/aicore/hcomm -> ../../adv_api/detail/hcomm
68+```
69+ 
70+因此,在上述扫描目录中新增`.h`文件后重新制包,新文件会自动进入run包。文件名、源码文件数量和安装文件数量均不固定,其他类型的文件不会进入包。run包清单只描述制包时存在的头文件,不是目标目录的完整镜像。首次安装时,仓库中已经删除或重命名的路径不会出现在清单中,安装器无法据此删除CANN中原有的旧路径文件。涉及删除或重命名时,不应仅依赖该run包验证目录最终状态。
71+ 
72+常用参数如下:
73+ 
74+| 参数 | 说明 |
75+| --- | --- |
76+| `--full` | 以full模式安装或更新包内全部Hcomm与Ain头文件及Hcomm软链。 |
77+| `--uninstall` | 恢复基线中的原文件,并删除安装前不存在的文件。 |
78+| `--check` | 校验run包归档、payload和依赖兼容性,不修改CANN。 |
79+| `--install-path=<PATH>` | 指定Ascend安装根目录;root默认使用`/usr/local/Ascend`,非root默认使用`$HOME/Ascend`。 |
80+| `--force` | 忽略已安装补丁文件的一致性检查。 |
81+| `--list` | 列出run包中的文件,由run包的makeself外层提供。 |
82+| `-h`、`--help` | 显示帮助信息。 |
83+ 
84+`--full`、`--uninstall`和`--check`是互斥操作,一次只能指定一个。
85+ 
86+### 检查包内容
87+ 
88+安装前可以检查归档和payload校验和,并查看包版本、源码提交、架构、要求的asc-devkit、hcomm、runtime版本及文件数量。该操作不会修改CANN:
89+ 
90+```bash
91+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --check
92+```
93+ 
94+列出run包内的文件:
95+ 
96+```bash
97+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --list
98+```
99+ 
100+### 安装与卸载
101+ 
102+安装到默认Ascend根目录:
103+ 
104+```bash
105+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --full
106+```
107+ 
108+也可以通过绝对路径明确指定安装位置:
109+ 
110+```bash
111+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run \
112+ --full --install-path=/path/to/cann
113+```
114+ 
115+安装器依次尝试将`--install-path`本身、`<install-path>/cann`或`<install-path>/ascend-toolkit/latest`解析为CANN根目录。解析后的目录必须包含`asc/include/adv_api/`、`asc/impl/adv_api/detail/`和`share/info/`,且当前用户必须是该CANN根目录的属主。
116+ 
117+首次安装时,备份状态保存在解析后的CANN根目录下:
118+ 
119+```text
120+var/asc-comm-dev-patch/baseline/
121+```
122+ 
123+- 如果目标文件已经存在,安装器会保存原文件后再替换;卸载时恢复原文件及其权限。
124+- 如果目标文件原本不存在,安装器会将其记录为`absent`后创建;卸载时删除该文件。
125+- 非root安装时,AICore Hcomm和Ain文件权限为`550`,Hcomm目录权限为`750`,`comm_api`下的受管目录权限为`550`。与devkit和hcomm包一致,root安装会自动启用全用户访问,将上述权限分别调整为`555`、`755`和`555`。安装器会记录目录原有权限;重复安装、卸载或安装失败回滚时会恢复原权限,不会递归修改无关目录。
126+- 安装器会记录两条Hcomm软链在首次安装前是否存在。卸载时,安装器会保留原本已存在且指向正确的软链,删除由本包新建的软链;目标错误的软链或占用软链路径的普通文件、目录不会被覆盖。
127+- 同一CANN目录中重复安装run包时,安装器会先恢复上一个补丁,再基于恢复后的CANN为新包重建基线,不会把上一次安装的补丁文件保存为原文件。
128+- 如果上一个asc-comm补丁中的路径不再出现在新包中,重复安装会将该路径恢复到原始状态并停止管理;后续卸载不会再处理该路径。但安装器无法处理从未被补丁记录、且本次包中也不存在的旧CANN文件。
129+ 
130+恢复安装前的文件。使用过`--install-path`安装时,卸载也应传入相同路径:
131+ 
132+```bash
133+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run --uninstall
134+# 指定路径安装对应的卸载方式
135+./build_out/cann-asc-comm_1.0.0_linux-<arch>.run \
136+ --uninstall --install-path=/path/to/cann
137+```
138+ 
139+制包时会记录asc-devkit、hcomm、runtime的主次版本和系统架构。安装时要求系统架构匹配;依赖版本不兼容时按CANN正式包行为输出告警并继续。重复安装或卸载前还会校验当前已安装的补丁文件,防止覆盖或丢弃用户在CANN目录中直接进行的修改。
140+ 
141+仅在明确了解数据覆盖风险时使用`--force`。安装时,该参数可以跳过已安装补丁文件被修改的检查;卸载时,可以强制丢弃已安装补丁文件上的修改并恢复基线。`--force`不能绕过系统架构检查或包内payload校验。
142+ 
143+安装、升级和卸载过程会按CANN包约定写入日志。root用户日志目录为`/var/log/ascend_seclog`,非root用户为`$HOME/var/log/ascend_seclog`;过程日志写入`ascend_install.log`,操作审计写入`operation.log`。
144+ 
145+安装完成后需要重新编译待验证的Ascend C Kernel,已有`.o`或`.bin`不会自动更新。
146+ 
147+可以直接调用制包脚本指定版本、输出目录和制包所用CANN:
148+ 
149+```bash
150+bash scripts/package/build_package.sh \
151+ --cann-path=/path/to/cann \
152+ --package-version=1.0.0 \
153+ --output-dir=/path/to/output
154+```
155+ 
156+在临时构造的CANN目录中验证安装、重复安装、文件保护和卸载恢复:
157+ 
158+```bash
159+bash tests/package/test_run_package.sh \
160+ build_out/cann-asc-comm_1.0.0_linux-<arch>.run
161+```
162+ 
40## CMake入口163## CMake入口
41 164 
42UT的CMake入口为:165UT的CMake入口为:
@@ -0,0 +1,292 @@
1+#!/bin/bash
2+# ----------------------------------------------------------------------------------------------------------
3+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
4+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
5+# CANN Open Software License Agreement Version 2.0 (the "License").
6+# Please refer to the License for details. You may not use this file except in compliance with the License.
7+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
8+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
9+# See LICENSE in the root of the software repository for the full text of the License.
10+# ----------------------------------------------------------------------------------------------------------
11+ 
12+set -euo pipefail
13+ 
14+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
15+PROJECT_ROOT=$(cd -- "${SCRIPT_DIR}/../.." && pwd)
16+ 
17+CANN_PATH=${ASCEND_HOME_PATH:-}
18+OUTPUT_DIR="${PROJECT_ROOT}/build_out"
19+PACKAGE_VERSION=${ASCCOMM_PACKAGE_VERSION:-1.0.0}
20+STAGING_DIR="${PROJECT_ROOT}/build/package/asc-comm"
21+PACKAGE_INPUT_PATHS=(
22+ build.sh
23+ include/aicore/ain
24+ include/aicore/hcomm
25+ src/aicore/ain
26+ src/aicore/hcomm
27+ scripts/package
28+)
29+ 
30+usage()
31+{
32+ cat <<EOF
33+Usage: bash scripts/package/build_package.sh [OPTION]...
34+ 
35+Options:
36+ --cann-path=<PATH> CANN installation root. Default: ASCEND_HOME_PATH
37+ --output-dir=<PATH> Output directory. Default: ${OUTPUT_DIR}
38+ --package-version=<VER> Package version. Default: ${PACKAGE_VERSION}
39+ -h, --help Display this help
40+EOF
41+}
42+ 
43+log()
44+{
45+ echo "[asc-comm package] $*"
46+}
47+ 
48+fail()
49+{
50+ echo "[asc-comm package] ERROR: $*" >&2
51+ exit 1
52+}
53+ 
54+parse_args()
55+{
56+ while [[ $# -gt 0 ]]; do
57+ case "$1" in
58+ --cann-path=*)
59+ CANN_PATH=${1#*=}
60+ ;;
61+ --output-dir=*)
62+ OUTPUT_DIR=${1#*=}
63+ ;;
64+ --package-version=*)
65+ PACKAGE_VERSION=${1#*=}
66+ ;;
67+ -h|--help)
68+ usage
69+ exit 0
70+ ;;
71+ *)
72+ fail "unknown argument: $1"
73+ ;;
74+ esac
75+ shift
76+ done
77+}
78+ 
79+normalize_arch()
80+{
81+ case "$(uname -m)" in
82+ x86_64)
83+ echo "x86_64"
84+ ;;
85+ aarch64|arm64)
86+ echo "aarch64"
87+ ;;
88+ *)
89+ fail "unsupported architecture: $(uname -m)"
90+ ;;
91+ esac
92+}
93+ 
94+find_makeself_dir()
95+{
96+ local candidate
97+ local candidates=(
98+ "${CANN_PATH}/toolkit/tools/op_project_templates/ascendc/customize/cmake/util/makeself"
99+ "${CANN_PATH}/tools/tikcpp/ascendc_kernel_cmake/fwk_modules/util/makeself"
100+ )
101+ 
102+ for candidate in "${candidates[@]}"; do
103+ if [[ -x "${candidate}/makeself.sh" && -f "${candidate}/makeself-header.sh" ]]; then
104+ echo "${candidate}"
105+ return 0
106+ fi
107+ done
108+ fail "makeself was not found under CANN path: ${CANN_PATH}"
109+}
110+ 
111+find_version_checker_dir()
112+{
113+ local package
114+ local candidate_dir
115+ 
116+ for package in asc-devkit hcomm runtime; do
117+ candidate_dir="${CANN_PATH}/share/info/${package}/script"
118+ if [[ -f "${candidate_dir}/version_compatiable.inc" && \
119+ -f "${candidate_dir}/check_version_required.awk" ]]; then
120+ echo "${candidate_dir}"
121+ return 0
122+ fi
123+ done
124+ fail "CANN package version compatibility scripts were not found under: ${CANN_PATH}/share/info"
125+}
126+ 
127+read_package_version()
128+{
129+ local package=$1
130+ local version_file="${CANN_PATH}/share/info/${package}/version.info"
131+ local version
132+ [[ -f "${version_file}" ]] || fail "${package} version file not found: ${version_file}"
133+ version=$(awk -F= '$1 == "Version" {print $2; exit}' "${version_file}")
134+ [[ -n "${version}" ]] || fail "failed to read ${package} version from ${version_file}"
135+ echo "${version}"
136+}
137+ 
138+read_package_compat_version()
139+{
140+ local package=$1
141+ local version
142+ local compat_version
143+ 
144+ version=$(read_package_version "${package}")
145+ compat_version=$(echo "${version%%-*}" | cut -d. -f1-2)
146+ [[ "${compat_version}" == *.* ]] || \
147+ fail "failed to derive ${package} compatibility version from ${version}"
148+ echo "${compat_version}"
149+}
150+ 
151+copy_headers()
152+{
153+ local source_root=$1
154+ local destination_root=$2
155+ local mode=$3
156+ local source_file
157+ local relative_path
158+ local count=0
159+ 
160+ while IFS= read -r -d '' source_file; do
161+ relative_path=${source_file#"${source_root}/"}
162+ install -D -m "${mode}" "${source_file}" "${destination_root}/${relative_path}"
163+ count=$((count + 1))
164+ done < <(find "${source_root}" -type f -name '*.h' -print0 | sort -z)
165+ 
166+ [[ ${count} -gt 0 ]] || fail "no header files found under ${source_root}"
167+}
168+ 
169+write_manifest()
170+{
171+ local file
172+ (
173+ cd "${STAGING_DIR}/payload"
174+ while IFS= read -r -d '' file; do
175+ sha256sum "${file}"
176+ done < <(find asc -type f -name '*.h' -print0 | sort -z)
177+ ) > "${STAGING_DIR}/manifest.sha256"
178+}
179+ 
180+write_link_manifest()
181+{
182+ cat > "${STAGING_DIR}/links.tsv" <<EOF
183+asc/include/comm_api/aicore/hcomm ../../adv_api/hcomm
184+asc/impl/comm_api/aicore/hcomm ../../adv_api/detail/hcomm
185+EOF
186+}
187+ 
188+write_version_info()
189+{
190+ local arch=$1
191+ local required_asc_devkit_version=$2
192+ local required_hcomm_version=$3
193+ local required_runtime_version=$4
194+ local commit="unknown"
195+ local dirty="true"
196+ 
197+ if git -C "${PROJECT_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
198+ commit=$(git -C "${PROJECT_ROOT}" rev-parse HEAD)
199+ if [[ -z "$(git -C "${PROJECT_ROOT}" status --porcelain --untracked-files=all -- \
200+ "${PACKAGE_INPUT_PATHS[@]}")" ]]; then
201+ dirty="false"
202+ fi
203+ fi
204+ 
205+ cat > "${STAGING_DIR}/version.info" <<EOF
206+PackageName=cann-asc-comm
207+PackageVersion=${PACKAGE_VERSION}
208+Version=${PACKAGE_VERSION}
209+version_dir=cann
210+Arch=${arch}
211+GitCommit=${commit}
212+GitDirty=${dirty}
213+required_package_asc-devkit_version="${required_asc_devkit_version}"
214+required_package_hcomm_version="${required_hcomm_version}"
215+required_package_runtime_version="${required_runtime_version}"
216+BuildTime=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
217+EOF
218+}
219+ 
220+build_package()
221+{
222+ local arch
223+ local required_asc_devkit_version
224+ local required_hcomm_version
225+ local required_runtime_version
226+ local makeself_dir
227+ local version_checker_dir
228+ local run_file
229+ 
230+ [[ -n "${CANN_PATH}" ]] || fail "CANN path is not set; source set_env.sh or use --cann-path"
231+ [[ "${CANN_PATH}" = /* ]] || fail "CANN path must be absolute: ${CANN_PATH}"
232+ CANN_PATH=$(readlink -f -- "${CANN_PATH}")
233+ [[ -d "${CANN_PATH}" ]] || fail "CANN path does not exist: ${CANN_PATH}"
234+ [[ "${PACKAGE_VERSION}" =~ ^[0-9A-Za-z._+-]+$ ]] || fail "invalid package version: ${PACKAGE_VERSION}"
235+ 
236+ arch=$(normalize_arch)
237+ required_asc_devkit_version=$(read_package_compat_version "asc-devkit")
238+ required_hcomm_version=$(read_package_compat_version "hcomm")
239+ required_runtime_version=$(read_package_compat_version "runtime")
240+ makeself_dir=$(find_makeself_dir)
241+ version_checker_dir=$(find_version_checker_dir)
242+ 
243+ mkdir -p "$(dirname -- "${STAGING_DIR}")" "${OUTPUT_DIR}"
244+ rm -rf -- "${STAGING_DIR}"
245+ mkdir -p "${STAGING_DIR}/payload"
246+ 
247+ # Match the Hcomm layout installed by asc-devkit's asc-comm integration.
248+ copy_headers \
249+ "${PROJECT_ROOT}/include/aicore/hcomm" \
250+ "${STAGING_DIR}/payload/asc/include/adv_api/hcomm" \
251+ 550
252+ copy_headers \
253+ "${PROJECT_ROOT}/src/aicore/hcomm" \
254+ "${STAGING_DIR}/payload/asc/impl/adv_api/detail/hcomm" \
255+ 550
256+ copy_headers \
257+ "${PROJECT_ROOT}/include/aicore/ain" \
258+ "${STAGING_DIR}/payload/asc/include/comm_api/aicore/ain" \
259+ 550
260+ copy_headers \
261+ "${PROJECT_ROOT}/src/aicore/ain" \
262+ "${STAGING_DIR}/payload/asc/impl/comm_api/aicore/ain" \
263+ 550
264+ write_manifest
265+ write_link_manifest
266+ write_version_info \
267+ "${arch}" \
268+ "${required_asc_devkit_version}" \
269+ "${required_hcomm_version}" \
270+ "${required_runtime_version}"
271+ install -m 550 "${SCRIPT_DIR}/install.sh" "${STAGING_DIR}/install.sh"
272+ install -D -m 440 \
273+ "${version_checker_dir}/version_compatiable.inc" \
274+ "${STAGING_DIR}/script/version_compatiable.inc"
275+ install -m 440 \
276+ "${version_checker_dir}/check_version_required.awk" \
277+ "${STAGING_DIR}/script/check_version_required.awk"
278+ 
279+ run_file="${OUTPUT_DIR}/cann-asc-comm_${PACKAGE_VERSION}_linux-${arch}.run"
280+ rm -f -- "${run_file}"
281+ "${makeself_dir}/makeself.sh" \
282+ --header "${makeself_dir}/makeself-header.sh" \
283+ --help-header "${SCRIPT_DIR}/help.info" \
284+ --gzip --complevel 4 --nomd5 --sha256 --chown \
285+ "${STAGING_DIR}" "${run_file}" "cann-asc-comm development patch" ./install.sh
286+ 
287+ log "generated ${run_file}"
288+ log "required package versions: asc-devkit=${required_asc_devkit_version}, hcomm=${required_hcomm_version}, runtime=${required_runtime_version}"
289+}
290+ 
291+parse_args "$@"
292+build_package
@@ -0,0 +1,18 @@
1+asc-comm development patch package
2+ 
3+ --full Install or update packaged Hcomm and Ain headers
4+ --uninstall Restore first-install originals and remove new files
5+ --check Verify payload and dependencies without modifying CANN
6+ --install-path=<ASCEND_ROOT> Select the Ascend install root; default follows
7+ CANN packages (/usr/local/Ascend or $HOME/Ascend)
8+ --force Override installed-file consistency checks
9+ 
10+Hcomm headers are installed under asc/include/adv_api/hcomm/ and
11+asc/impl/adv_api/detail/hcomm/. Ain headers are installed under
12+asc/include/comm_api/aicore/ain/ and asc/impl/comm_api/aicore/ain/. Hcomm
13+links are created under comm_api/aicore/. Existing files and link state are
14+backed up under var/asc-comm-dev-patch/baseline/. This package is intended
15+only for local development verification. Recompile the target Ascend C kernel
16+after installation. Only paths present in the package manifest are managed;
17+this is not a full directory mirror. --force does not override architecture
18+or payload checksum checks.
@@ -0,0 +1,352 @@
1+#!/bin/bash
2+# ----------------------------------------------------------------------------------------------------------
3+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
4+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
5+# CANN Open Software License Agreement Version 2.0 (the "License").
6+# Please refer to the License for details. You may not use this file except in compliance with the License.
7+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
8+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
9+# See LICENSE in the root of the software repository for the full text of the License.
10+# ----------------------------------------------------------------------------------------------------------
11+ 
12+set -euo pipefail
13+ 
14+SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
15+PROJECT_ROOT=$(cd -- "${SCRIPT_DIR}/../.." && pwd)
16+RUN_FILE=${1:-}
17+ 
18+[[ -n "${RUN_FILE}" ]] || { echo "Usage: $0 <asc-comm.run>" >&2; exit 1; }
19+RUN_FILE=$(readlink -f -- "${RUN_FILE}")
20+[[ -x "${RUN_FILE}" ]] || { echo "Run package is missing or not executable: ${RUN_FILE}" >&2; exit 1; }
21+ 
22+TEST_ROOT=$(mktemp -d)
23+trap 'rm -rf -- "${TEST_ROOT}"' EXIT
24+EXTRACT_DIR="${TEST_ROOT}/extracted"
25+FAKE_CANN="${TEST_ROOT}/cann"
26+BASELINE_DIR="${TEST_ROOT}/baseline"
27+ERROR_LOG="${TEST_ROOT}/expected-error.log"
28+TEST_HOME="${TEST_ROOT}/home"
29+LOG_DIR="${TEST_HOME}/var/log/ascend_seclog"
30+ 
31+if [[ $(id -u) -eq 0 ]]; then
32+ EXPECTED_FILE_MODE=555
33+ EXPECTED_HCOMM_DIR_MODE=755
34+ EXPECTED_COMM_API_DIR_MODE=555
35+else
36+ EXPECTED_FILE_MODE=550
37+ EXPECTED_HCOMM_DIR_MODE=750
38+ EXPECTED_COMM_API_DIR_MODE=550
39+fi
40+ 
41+run_package()
42+{
43+ env HOME="${TEST_HOME}" "${RUN_FILE}" "$@"
44+}
45+ 
46+expect_failure()
47+{
48+ if "$@" > "${ERROR_LOG}" 2>&1; then
49+ echo "Command unexpectedly succeeded: $*" >&2
50+ exit 1
51+ fi
52+}
53+ 
54+read_required_version()
55+{
56+ local package=$1
57+ awk -F= -v key="required_package_${package}_version" \
58+ '$1 == key {gsub(/"/, "", $2); print $2; exit}' "${EXTRACT_DIR}/version.info"
59+}
60+ 
61+write_dependency_versions()
62+{
63+ local cann_root=$1
64+ 
65+ mkdir -p \
66+ "${cann_root}/share/info/asc-devkit" \
67+ "${cann_root}/share/info/hcomm" \
68+ "${cann_root}/share/info/runtime"
69+ printf 'Version=%s\n' "${REQUIRED_ASC_DEVKIT_VERSION}" > \
70+ "${cann_root}/share/info/asc-devkit/version.info"
71+ printf 'Version=%s\n' "${REQUIRED_HCOMM_VERSION}" > \
72+ "${cann_root}/share/info/hcomm/version.info"
73+ printf 'Version=%s\n' "${REQUIRED_RUNTIME_VERSION}" > \
74+ "${cann_root}/share/info/runtime/version.info"
75+}
76+ 
77+# build.sh must propagate packaging failures to CI and other callers.
78+expect_failure env ASCEND_HOME_PATH="${TEST_ROOT}/missing-cann" \
79+ bash "${PROJECT_ROOT}/build.sh" --pkg
80+ 
81+"${RUN_FILE}" --noexec --extract="${EXTRACT_DIR}" >/dev/null
82+REQUIRED_ASC_DEVKIT_VERSION=$(read_required_version "asc-devkit")
83+REQUIRED_HCOMM_VERSION=$(read_required_version "hcomm")
84+REQUIRED_RUNTIME_VERSION=$(read_required_version "runtime")
85+[[ -n "${REQUIRED_ASC_DEVKIT_VERSION}" && \
86+ -n "${REQUIRED_HCOMM_VERSION}" && \
87+ -n "${REQUIRED_RUNTIME_VERSION}" ]] || \
88+ { echo "Failed to read package dependency metadata" >&2; exit 1; }
89+PACKAGE_GIT_DIRTY=$(awk -F= '$1 == "GitDirty" {print $2; exit}' "${EXTRACT_DIR}/version.info")
90+EXPECTED_GIT_DIRTY=true
91+if [[ -z "$(git -C "${PROJECT_ROOT}" status --porcelain --untracked-files=all -- \
92+ build.sh include/aicore/ain include/aicore/hcomm \
93+ src/aicore/ain src/aicore/hcomm scripts/package)" ]]; then
94+ EXPECTED_GIT_DIRTY=false
95+fi
96+[[ "${PACKAGE_GIT_DIRTY}" == "${EXPECTED_GIT_DIRTY}" ]]
97+ 
98+# Reject module-directory links that would redirect package writes outside CANN_ROOT.
99+EXTERNAL_LINK_CANN="${TEST_ROOT}/external-link-cann"
100+EXTERNAL_HEADER_DIR="${TEST_ROOT}/outside-cann/hcomm"
101+mkdir -p \
102+ "${EXTERNAL_LINK_CANN}/asc/include/adv_api" \
103+ "${EXTERNAL_LINK_CANN}/asc/impl/adv_api/detail" \
104+ "${EXTERNAL_HEADER_DIR}"
105+ln -s "${EXTERNAL_HEADER_DIR}" "${EXTERNAL_LINK_CANN}/asc/include/adv_api/hcomm"
106+write_dependency_versions "${EXTERNAL_LINK_CANN}"
107+expect_failure run_package --full --install-path="${EXTERNAL_LINK_CANN}"
108+grep -q 'target path resolves outside CANN root' "${ERROR_LOG}"
109+[[ ! -e "${EXTERNAL_HEADER_DIR}/hcomm.h" ]]
110+[[ ! -e "${EXTERNAL_LINK_CANN}/var/asc-comm-dev-patch" ]]
111+ 
112+# Reject an invalid pre-existing backup target without deleting it during rollback.
113+INVALID_STATE_CANN="${TEST_ROOT}/invalid-state-cann"
114+INVALID_STATE_PATH="${INVALID_STATE_CANN}/var/asc-comm-dev-patch"
115+mkdir -p \
116+ "${INVALID_STATE_CANN}/asc/include/adv_api" \
117+ "${INVALID_STATE_CANN}/asc/impl/adv_api/detail" \
118+ "${INVALID_STATE_CANN}/var"
119+write_dependency_versions "${INVALID_STATE_CANN}"
120+printf 'pre-existing marker\n' > "${INVALID_STATE_PATH}"
121+expect_failure run_package --full --install-path="${INVALID_STATE_CANN}"
122+grep -q 'backup state path is invalid' "${ERROR_LOG}"
123+grep -qx 'pre-existing marker' "${INVALID_STATE_PATH}"
124+[[ ! -e "${INVALID_STATE_CANN}/asc/include/adv_api/hcomm/hcomm.h" ]]
125+ 
126+# Preserve support for links whose resolved destination remains inside CANN_ROOT.
127+INTERNAL_LINK_CANN="${TEST_ROOT}/internal-link-cann"
128+INTERNAL_HEADER_DIR="${INTERNAL_LINK_CANN}/shared/hcomm"
129+mkdir -p \
130+ "${INTERNAL_LINK_CANN}/asc/include/adv_api" \
131+ "${INTERNAL_LINK_CANN}/asc/impl/adv_api/detail" \
132+ "${INTERNAL_HEADER_DIR}"
133+ln -s "${INTERNAL_HEADER_DIR}" "${INTERNAL_LINK_CANN}/asc/include/adv_api/hcomm"
134+write_dependency_versions "${INTERNAL_LINK_CANN}"
135+run_package --full --install-path="${INTERNAL_LINK_CANN}"
136+cmp "${EXTRACT_DIR}/payload/asc/include/adv_api/hcomm/hcomm.h" \
137+ "${INTERNAL_HEADER_DIR}/hcomm.h"
138+run_package --uninstall --install-path="${INTERNAL_LINK_CANN}"
139+[[ ! -e "${INTERNAL_HEADER_DIR}/hcomm.h" ]]
140+[[ -L "${INTERNAL_LINK_CANN}/asc/include/adv_api/hcomm" ]]
141+ 
142+HCOMM_PUBLIC_HEADER_COUNT=$(find "${PROJECT_ROOT}/include/aicore/hcomm" -type f -name '*.h' | wc -l)
143+HCOMM_IMPL_HEADER_COUNT=$(find "${PROJECT_ROOT}/src/aicore/hcomm" -type f -name '*.h' | wc -l)
144+AIN_PUBLIC_HEADER_COUNT=$(find "${PROJECT_ROOT}/include/aicore/ain" -type f -name '*.h' | wc -l)
145+AIN_IMPL_HEADER_COUNT=$(find "${PROJECT_ROOT}/src/aicore/ain" -type f -name '*.h' | wc -l)
146+EXPECTED_FILE_COUNT=$((HCOMM_PUBLIC_HEADER_COUNT + HCOMM_IMPL_HEADER_COUNT + \
147+ AIN_PUBLIC_HEADER_COUNT + AIN_IMPL_HEADER_COUNT))
148+[[ "$(wc -l < "${EXTRACT_DIR}/manifest.sha256")" -eq "${EXPECTED_FILE_COUNT}" ]]
149+[[ ! -e "${EXTRACT_DIR}/payload/asc/include/adv_api/ain" ]]
150+[[ ! -e "${EXTRACT_DIR}/payload/asc/impl/adv_api/hcomm" ]]
151+[[ ! -e "${EXTRACT_DIR}/payload/asc/impl/adv_api/detail/ain" ]]
152+[[ ! -e "${EXTRACT_DIR}/payload/aarch64-linux" ]]
153+[[ ! -e "${EXTRACT_DIR}/payload/x86_64-linux" ]]
154+diff -u <(printf '%s\t%s\n' \
155+ 'asc/include/comm_api/aicore/hcomm' '../../adv_api/hcomm' \
156+ 'asc/impl/comm_api/aicore/hcomm' '../../adv_api/detail/hcomm') \
157+ "${EXTRACT_DIR}/links.tsv"
158+ 
159+while IFS= read -r -d '' source_file; do
160+ relative_path=${source_file#"${PROJECT_ROOT}/include/aicore/hcomm/"}
161+ cmp "${source_file}" "${EXTRACT_DIR}/payload/asc/include/adv_api/hcomm/${relative_path}"
162+done < <(find "${PROJECT_ROOT}/include/aicore/hcomm" -type f -name '*.h' -print0 | sort -z)
163+ 
164+while IFS= read -r -d '' source_file; do
165+ relative_path=${source_file#"${PROJECT_ROOT}/src/aicore/hcomm/"}
166+ cmp "${source_file}" "${EXTRACT_DIR}/payload/asc/impl/adv_api/detail/hcomm/${relative_path}"
167+done < <(find "${PROJECT_ROOT}/src/aicore/hcomm" -type f -name '*.h' -print0 | sort -z)
168+ 
169+while IFS= read -r -d '' source_file; do
170+ relative_path=${source_file#"${PROJECT_ROOT}/include/aicore/ain/"}
171+ cmp "${source_file}" \
172+ "${EXTRACT_DIR}/payload/asc/include/comm_api/aicore/ain/${relative_path}"
173+done < <(find "${PROJECT_ROOT}/include/aicore/ain" -type f -name '*.h' -print0 | sort -z)
174+ 
175+while IFS= read -r -d '' source_file; do
176+ relative_path=${source_file#"${PROJECT_ROOT}/src/aicore/ain/"}
177+ cmp "${source_file}" \
178+ "${EXTRACT_DIR}/payload/asc/impl/comm_api/aicore/ain/${relative_path}"
179+done < <(find "${PROJECT_ROOT}/src/aicore/ain" -type f -name '*.h' -print0 | sort -z)
180+ 
181+RELATIVE_DETAIL_INCLUDE_COUNT=0
182+while IFS= read -r -d '' source_file; do
183+ relative_path=${source_file#"${PROJECT_ROOT}/include/aicore/hcomm/"}
184+ packaged_header="${EXTRACT_DIR}/payload/asc/include/adv_api/hcomm/${relative_path}"
185+ while IFS= read -r include_path; do
186+ case "${include_path}" in
187+ ../../../impl/adv_api/detail/*)
188+ [[ -f "$(dirname -- "${packaged_header}")/${include_path}" ]]
189+ RELATIVE_DETAIL_INCLUDE_COUNT=$((RELATIVE_DETAIL_INCLUDE_COUNT + 1))
190+ ;;
191+ esac
192+ done < <(awk -F '"' '/^[[:space:]]*#[[:space:]]*include[[:space:]]*"/ {print $2}' "${packaged_header}")
193+done < <(find "${PROJECT_ROOT}/include/aicore/hcomm" -type f -name '*.h' -print0 | sort -z)
194+[[ ${RELATIVE_DETAIL_INCLUDE_COUNT} -gt 0 ]]
195+ 
196+mkdir -p \
197+ "${FAKE_CANN}/asc/include/adv_api/hcomm" \
198+ "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/common" \
199+ "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/unmanaged" \
200+ "${BASELINE_DIR}"
201+write_dependency_versions "${FAKE_CANN}"
202+ 
203+while read -r _ path; do
204+ mkdir -p "$(dirname -- "${FAKE_CANN}/${path}")"
205+ printf 'baseline: %s\n' "${path}" > "${FAKE_CANN}/${path}"
206+ chmod 540 "${FAKE_CANN}/${path}"
207+done < "${EXTRACT_DIR}/manifest.sha256"
208+chmod 751 "${FAKE_CANN}/asc/include/adv_api/hcomm"
209+chmod 711 "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm"
210+chmod 700 "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/common"
211+chmod 701 "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/unmanaged"
212+cp -a "${FAKE_CANN}/asc" "${BASELINE_DIR}/asc"
213+ 
214+expect_failure run_package --install --install-path="${FAKE_CANN}"
215+[[ ! -e "${FAKE_CANN}/var/asc-comm-dev-patch" ]]
216+ 
217+run_package --full --install-path="${FAKE_CANN}"
218+ 
219+while read -r _ path; do
220+ cmp "${EXTRACT_DIR}/payload/${path}" "${FAKE_CANN}/${path}"
221+ [[ "$(stat -c %a -- "${FAKE_CANN}/${path}")" == "${EXPECTED_FILE_MODE}" ]]
222+done < "${EXTRACT_DIR}/manifest.sha256"
223+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/include/adv_api/hcomm")" == "${EXPECTED_HCOMM_DIR_MODE}" ]]
224+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm")" == "${EXPECTED_HCOMM_DIR_MODE}" ]]
225+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/common")" == "${EXPECTED_HCOMM_DIR_MODE}" ]]
226+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/unmanaged")" == "701" ]]
227+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/include/comm_api")" == "${EXPECTED_COMM_API_DIR_MODE}" ]]
228+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/include/comm_api/aicore")" == "${EXPECTED_COMM_API_DIR_MODE}" ]]
229+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/include/comm_api/aicore/ain")" == "${EXPECTED_COMM_API_DIR_MODE}" ]]
230+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/comm_api")" == "${EXPECTED_COMM_API_DIR_MODE}" ]]
231+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/comm_api/aicore")" == "${EXPECTED_COMM_API_DIR_MODE}" ]]
232+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/comm_api/aicore/ain")" == "${EXPECTED_COMM_API_DIR_MODE}" ]]
233+[[ -L "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm" ]]
234+[[ "$(readlink -- "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm")" == "../../adv_api/hcomm" ]]
235+[[ -L "${FAKE_CANN}/asc/impl/comm_api/aicore/hcomm" ]]
236+[[ "$(readlink -- "${FAKE_CANN}/asc/impl/comm_api/aicore/hcomm")" == "../../adv_api/detail/hcomm" ]]
237+ 
238+# Relative Ain includes must resolve from their deeper comm_api/aicore layout.
239+while IFS= read -r installed_header; do
240+ while IFS= read -r include_path; do
241+ case "${include_path}" in
242+ ../*)
243+ [[ -f "$(dirname -- "${installed_header}")/${include_path}" ]]
244+ ;;
245+ esac
246+ done < <(awk -F '"' '/^[[:space:]]*#[[:space:]]*include[[:space:]]*"/ {print $2}' \
247+ "${installed_header}")
248+done < <(find \
249+ "${FAKE_CANN}/asc/include/comm_api/aicore/ain" \
250+ "${FAKE_CANN}/asc/impl/comm_api/aicore/ain" \
251+ -type f -name '*.h' | sort)
252+ 
253+[[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/active.manifest.sha256" ]]
254+[[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/active.links.tsv" ]]
255+grep -qx 'FormatVersion=3' "${FAKE_CANN}/var/asc-comm-dev-patch/state.info"
256+[[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/baseline/directories.tsv" ]]
257+[[ -f "${FAKE_CANN}/var/asc-comm-dev-patch/baseline/links.tsv" ]]
258+ 
259+# Missing managed links are protected like modified managed files.
260+chmod 750 "${FAKE_CANN}/asc/include/comm_api/aicore"
261+rm -f -- "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm"
262+expect_failure run_package --full --install-path="${FAKE_CANN}"
263+run_package --full --install-path="${FAKE_CANN}" --force
264+[[ "$(readlink -- "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm")" == "../../adv_api/hcomm" ]]
265+ 
266+# Protect local changes made directly in an already patched CANN tree.
267+chmod 750 "${FAKE_CANN}/asc/include/adv_api/hcomm/hcomm.h"
268+printf 'external change\n' > "${FAKE_CANN}/asc/include/adv_api/hcomm/hcomm.h"
269+expect_failure run_package --uninstall --install-path="${FAKE_CANN}"
270+grep -q '^external change$' "${FAKE_CANN}/asc/include/adv_api/hcomm/hcomm.h"
271+[[ -d "${FAKE_CANN}/var/asc-comm-dev-patch" ]]
272+expect_failure run_package --full --install-path="${FAKE_CANN}"
273+grep -q '^external change$' "${FAKE_CANN}/asc/include/adv_api/hcomm/hcomm.h"
274+ 
275+run_package --full --install-path="${FAKE_CANN}" --force
276+ 
277+# Reinstalling must retain the original baseline rather than backing up patched files.
278+run_package --full --install-path="${FAKE_CANN}"
279+run_package --uninstall --install-path="${FAKE_CANN}"
280+ 
281+while read -r _ path; do
282+ cmp "${BASELINE_DIR}/${path}" "${FAKE_CANN}/${path}"
283+ [[ "$(stat -c %a -- "${FAKE_CANN}/${path}")" == "540" ]]
284+done < "${EXTRACT_DIR}/manifest.sha256"
285+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/include/adv_api/hcomm")" == "751" ]]
286+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm")" == "711" ]]
287+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/common")" == "700" ]]
288+[[ "$(stat -c %a -- "${FAKE_CANN}/asc/impl/adv_api/detail/hcomm/unmanaged")" == "701" ]]
289+[[ ! -L "${FAKE_CANN}/asc/include/comm_api/aicore/hcomm" ]]
290+[[ ! -L "${FAKE_CANN}/asc/impl/comm_api/aicore/hcomm" ]]
291+[[ ! -e "${FAKE_CANN}/var/asc-comm-dev-patch" ]]
292+ 
293+# Correct links that predate the patch remain after uninstall.
294+PREEXISTING_LINK_CANN="${TEST_ROOT}/preexisting-link-cann"
295+mkdir -p \
296+ "${PREEXISTING_LINK_CANN}/asc/include/adv_api" \
297+ "${PREEXISTING_LINK_CANN}/asc/impl/adv_api/detail" \
298+ "${PREEXISTING_LINK_CANN}/asc/include/comm_api/aicore" \
299+ "${PREEXISTING_LINK_CANN}/asc/impl/comm_api/aicore"
300+ln -s ../../adv_api/hcomm \
301+ "${PREEXISTING_LINK_CANN}/asc/include/comm_api/aicore/hcomm"
302+ln -s ../../adv_api/detail/hcomm \
303+ "${PREEXISTING_LINK_CANN}/asc/impl/comm_api/aicore/hcomm"
304+write_dependency_versions "${PREEXISTING_LINK_CANN}"
305+run_package --full --install-path="${PREEXISTING_LINK_CANN}"
306+run_package --uninstall --install-path="${PREEXISTING_LINK_CANN}"
307+[[ "$(readlink -- "${PREEXISTING_LINK_CANN}/asc/include/comm_api/aicore/hcomm")" == \
308+ "../../adv_api/hcomm" ]]
309+[[ "$(readlink -- "${PREEXISTING_LINK_CANN}/asc/impl/comm_api/aicore/hcomm")" == \
310+ "../../adv_api/detail/hcomm" ]]
311+ 
312+# Wrong links and non-link occupants are never overwritten, including with --force.
313+INVALID_LINK_CANN="${TEST_ROOT}/invalid-link-cann"
314+mkdir -p \
315+ "${INVALID_LINK_CANN}/asc/include/adv_api" \
316+ "${INVALID_LINK_CANN}/asc/impl/adv_api/detail" \
317+ "${INVALID_LINK_CANN}/asc/include/comm_api/aicore"
318+ln -s ../wrong-target "${INVALID_LINK_CANN}/asc/include/comm_api/aicore/hcomm"
319+write_dependency_versions "${INVALID_LINK_CANN}"
320+expect_failure run_package --full --force --install-path="${INVALID_LINK_CANN}"
321+[[ "$(readlink -- "${INVALID_LINK_CANN}/asc/include/comm_api/aicore/hcomm")" == \
322+ "../wrong-target" ]]
323+[[ ! -e "${INVALID_LINK_CANN}/var/asc-comm-dev-patch" ]]
324+ 
325+OCCUPIED_LINK_CANN="${TEST_ROOT}/occupied-link-cann"
326+mkdir -p \
327+ "${OCCUPIED_LINK_CANN}/asc/include/adv_api" \
328+ "${OCCUPIED_LINK_CANN}/asc/impl/adv_api/detail" \
329+ "${OCCUPIED_LINK_CANN}/asc/impl/comm_api/aicore/hcomm"
330+write_dependency_versions "${OCCUPIED_LINK_CANN}"
331+expect_failure run_package --full --force --install-path="${OCCUPIED_LINK_CANN}"
332+[[ -d "${OCCUPIED_LINK_CANN}/asc/impl/comm_api/aicore/hcomm" ]]
333+[[ ! -e "${OCCUPIED_LINK_CANN}/var/asc-comm-dev-patch" ]]
334+ 
335+# A dependency mismatch follows the CANN package convention: warn and continue.
336+printf 'Version=0.0.0\n' > "${FAKE_CANN}/share/info/asc-devkit/version.info"
337+run_package --check --install-path="${FAKE_CANN}" > "${ERROR_LOG}" 2>&1
338+grep -q 'Version compatibility check failed' "${ERROR_LOG}"
339+cmp "${BASELINE_DIR}/asc/include/adv_api/hcomm/hcomm.h" \
340+ "${FAKE_CANN}/asc/include/adv_api/hcomm/hcomm.h"
341+[[ ! -e "${FAKE_CANN}/var/asc-comm-dev-patch" ]]
342+ 
343+if [[ $(id -u) -ne 0 ]]; then
344+ [[ "$(stat -c %a -- "${LOG_DIR}")" == "740" ]]
345+ [[ "$(stat -c %a -- "${LOG_DIR}/ascend_install.log")" == "640" ]]
346+ [[ "$(stat -c %a -- "${LOG_DIR}/operation.log")" == "640" ]]
347+ grep -q '^Install SUGGESTION .* succeeded installmode=full;' "${LOG_DIR}/operation.log"
348+ grep -q '^Upgrade MINOR .* succeeded installmode=full;' "${LOG_DIR}/operation.log"
349+ grep -q '^Uninstall MAJOR .* succeeded installmode=uninstall;' "${LOG_DIR}/operation.log"
350+fi
351+ 
352+echo "asc-comm run package install/reinstall/uninstall test passed"