@@ -1350,6 +1350,172 @@ evalsoc的外设配置。
13501350
13511351|image130 |
13521352
1353+ GNU GCC工具链切换为Clang/ZCC工具链
1354+ ----------------------------------
1355+
1356+ Nuclei Studio IDE 支持三种工具链:``RISC-V GCC/Newlib ``、``RISC-V Clang/Newlib `` 和 ``Terapines ZCC ``。
1357+ 创建工程时,可以直接在 ``Toolchain `` 下拉框中选择所需工具链。
1358+
1359+ |image-gcc2llvm-1 |
1360+
1361+ 如果当前工程使用的是 GCC 工具链,而你希望切换到 Clang 或 ZCC 工具链,可以按以下步骤完成迁移:
1362+
1363+ 1. :ref: `切换工具链 <change_toolchain >` ;
1364+ 2. :ref: `调整编译选项和链接选项 <adjust_flags >` ;
1365+ 3. :ref: `调整链接库 <adjust_libs >` ;
1366+
1367+ .. _change_toolchain :
1368+
1369+ 切换工具链
1370+ ~~~~~~~~~~
1371+
1372+ 在 ``Project Explorer `` 中选中工程,右键选择 ``Properties `` 打开工程属性,然后进入 ``C/C++ Build -> Settings -> Toolchains ``。在 ``Name `` 下拉框中选择目标工具链即可。
1373+
1374+ |image-gcc2llvm-2 |
1375+
1376+ .. _adjust_flags :
1377+
1378+ 调整编译和链接选项
1379+ ~~~~~~~~~~~~~~~~~~
1380+
1381+ RISC-V Clang/Newlib
1382+ ^^^^^^^^^^^^^^^^^^^
1383+
1384+ 如果切换到 Clang 工具链,需要同步调整编译和链接选项,因为 Clang 并不完全兼容 GCC 的所有参数。
1385+
1386+ 以 CoreMark 工程为例,不同 CPU 系列使用的参数可能略有差异,但通常建议做以下调整:
1387+
1388+ 1. 将 ``Optimization Level `` 从 ``-Ofast `` 调整为 ``-O3 ``;
1389+ 2. 将 ``Extra Common Flags `` 替换为 ``-flto ``;
1390+ 3. 删除链接选项中的 ``-Wl,--no-warn-rwx-segments ``。
1391+
1392+ |image-gcc2llvm-3 |
1393+
1394+ Terapines ZCC
1395+ ^^^^^^^^^^^^^
1396+
1397+ 如果切换到 ZCC 工具链,建议按以下方式调整编译和链接选项:
1398+
1399+ 1. 将 ``Optimization Level `` 从 ``-Ofast `` 调整为 ``-O3 ``;
1400+ 2. 将 ``Extra Common Flags `` 替换为 ``-flto -falign-functions=4 -falign-loops=4 -flate-loop-unroll -malign-branch ``;
1401+ 3. 删除链接选项中的 ``-Wl,--no-warn-rwx-segments ``;
1402+ 4. 将链接选项改为 ``-Wl,-mllvm,--align-all-nofallthru-blocks=2 ``。
1403+
1404+ |image-gcc2llvm-4 |
1405+
1406+ .. _adjust_libs :
1407+
1408+ 调整链接库
1409+ ~~~~~~~~~~
1410+
1411+ 不同工具链依赖的库可能不同,因此切换后还需要检查并调整链接库。链接库可以在工程属性中的 ``C/C++ Build -> Settings -> Tool Settings -> GNU RISC-V Cross C++ Linker -> Libraries `` 中修改。
1412+
1413+ |image-gcc2llvm-5 |
1414+
1415+ 对于 Clang 工具链,Nuclei Studio 使用的仍是同一套 C 标准库,一般不需要额外修改链接库。因此,从 GCC 迁移到 Clang 时,通常只需完成前面的 :ref: `切换工具链<change_toolchain> ` 和 :ref: `调整编译和链接选项 <adjust_flags >` 两步,即可尝试重新编译工程。
1416+
1417+ 对于 ZCC 工具链,则需要进一步调整链接库名称。ZCC 仅支持 ``newlib_small `` 库,因此无论当前 GCC 工程使用的是 ``newlib_small `` 还是 ``libncrt_small ``,都可以将链接库统一改为 ``c_small `` 和 ``clang_rt.builtins_small ``。
1418+
1419+ |image-gcc2llvm-6 |
1420+
1421+ 如果当前工程链接的是 ``libncrt_small ``,还需要将 ``stubs.c `` 替换为 newlib 版本;如果工程原本使用的就是 newlib 库,则无需执行这一步。
1422+
1423+ 以基于 Nuclei SDK 创建的 EvalSoC 工程为例,可以先将 libncrt 版本的 ``stubs.c `` 排除构建。选中 ``SoC\\evalsoc\\Common\\Source\\Stubs\\libncrt ``,右键选择 ``Resource Configurations -> Exclude from Build... ``,然后从其他使用 newlib 库的工程中复制一份 newlib 版本的 ``stubs.c `` 到 ``Stubs `` 目录中。
1424+
1425+ |image-gcc2llvm-7 |
1426+
1427+ 完成 ``stubs.c `` 的调整后,从 GCC 迁移到 ZCC 的过程就完成了,此时可以尝试重新编译工程。
1428+
1429+ newlib_small 与 libncrt_small 的转换
1430+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1431+
1432+ 前面提到,ZCC 不支持 ``libncrt_small ``。因此,当工具链从 GCC 切换到 ZCC 时,如果工程原本使用的是 ``libncrt_small ``,就需要同步切换到 ``newlib_small ``。
1433+
1434+ 在 Nuclei Studio 中选择 ``newlib_small `` 时,实际对应的链接库是 ``c_nano `` 并且支持浮点打印。链接选项中会默认添加 ``-u _printf_float ``。可以按照下图检查该选项是否已经添加。
1435+
1436+ |image-gcc2llvm-8 |
1437+
1438+ 下表汇总了不同工具链与 C 库组合的支持情况。调整工具链或链接库时,请同时检查 ``库列表 ``、``链接选项 `` 和 ``stubs 文件 `` 是否匹配。
1439+
1440+ +------------+----------------+----------+---------------------------+------------------+-----------------+
1441+ | 工具链 | 链接库 | 是否支持 | 库列表 | 链接选项 | stubs 文件 |
1442+ +============+================+==========+===========================+==================+=================+
1443+ | GCC/Clang | newlib_small | 支持 | - c++ | -u _printf_float | newlib/stubs.c |
1444+ | | | | - c_nano | | |
1445+ | | | | - gcc | | |
1446+ +------------+----------------+----------+---------------------------+------------------+-----------------+
1447+ | GCC/Clang | libncrt_small | 支持 | - ncrt_small | | libncrt/stubs.c |
1448+ | | | | - heapops_basic | | |
1449+ | | | | - fileops_uart | | |
1450+ +------------+----------------+----------+---------------------------+------------------+-----------------+
1451+ | ZCC | newlib_small | 支持 | - c_small | | newlib/stubs.c |
1452+ | | | | - clang_rt.builtins_small | | |
1453+ +------------+----------------+----------+---------------------------+------------------+-----------------+
1454+ | ZCC | libncrt_small | 不支持 | | | |
1455+ +------------+----------------+----------+---------------------------+------------------+-----------------+
1456+
1457+ 常见问题
1458+ ~~~~~~~~
1459+
1460+ Clang/ZCC 与 GCC 的不兼容性
1461+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1462+
1463+ Clang/ZCC 工具链并不完全兼容 GCC 的编译选项。如果编译时报错,请参考 :ref: `调整编译和链接选项 <adjust_flags >` 进行调整。
1464+
1465+ .. code-block :: console
1466+
1467+ riscv64-unknown-elf-clang: error: unknown argument: '-fno-code-hoisting'
1468+ riscv64-unknown-elf-clang: error: unknown argument: '-fno-if-conversion'
1469+ riscv64-unknown-elf-clang: error: unknown argument: '-fno-if-conversion2'
1470+ riscv64-unknown-elf-clang: error: unknown argument: '-fselective-scheduling'
1471+ riscv64-unknown-elf-clang: error: unknown argument: '-fno-tree-loop-distribute-patterns'
1472+ riscv64-unknown-elf-clang: error: unknown argument: '-mbranch-cost=1'
1473+
1474+ Clang/ZCC 工具链不支持 ``-Wl,--no-warn-rwx-segments `` 链接选项。如果链接时报错,请参考 :ref: `调整编译和链接选项 <adjust_flags >` 进行调整。
1475+
1476+ .. code-block :: console
1477+
1478+ ld.lld: error: unknown argument '--no-warn-rwx-segments'
1479+ riscv64-unknown-elf-clang++: error: ld command failed with exit code 1 (use -v to see invocation)
1480+ make: *** [makefile:92: coremark.elf] Error 1
1481+
1482+ ZCC 链接失败
1483+ ^^^^^^^^^^^^
1484+
1485+ 从 GCC 切换到 ZCC 工具链时,如果没有正确调整链接库,可能会出现以下问题。可参考 :ref: `调整链接库 <adjust_libs >` 进行修改。
1486+
1487+ 如果原工程使用的是 ``newlib_small ``,但没有修改链接库,可能会出现以下错误:
1488+
1489+ .. code-block :: console
1490+
1491+ ld.lld: error: unable to find library -lstdc++
1492+ z++: error: ld command failed with exit code 1 (use -v to see invocation)
1493+ make: *** [makefile:92: coremark.elf] Error 1
1494+
1495+ 如果原工程使用的是 ``libncrt_small ``,但没有修改链接库,可能会出现以下错误:
1496+
1497+ .. code-block :: console
1498+
1499+ ld.lld: error: unable to find library -lncrt_small
1500+ ld.lld: error: unable to find library -lheapops_basic
1501+ ld.lld: error: unable to find library -lfileops_uart
1502+ ld.lld: error: unable to find library -lncrt_small
1503+ z++: error: ld command failed with exit code 1 (use -v to see invocation)
1504+ make: *** [makefile:92: coremark.elf] Error 1
1505+
1506+ 如果原工程使用的是 ``libncrt_small ``,虽然已经修改了链接库,但没有同步替换 ``stubs.c ``,则可能出现以下错误:
1507+
1508+ .. code-block :: console
1509+
1510+ ld.lld: error: undefined symbol: _read
1511+ >>> referenced by ld-temp.o
1512+ >>> coremark.elf.lto.o:(sys_semihost_getc)
1513+
1514+ ld.lld: error: undefined symbol: _write
1515+ >>> referenced by ld-temp.o
1516+ >>> coremark.elf.lto.o:(sys_semihost_putc)
1517+ z++: error: ld command failed with exit code 1 (use -v to see invocation)
1518+ make: *** [makefile:92: coremark.elf] Error 1
13531519
13541520 .. |image1 | image :: /asserts/nucleistudio/advanceusage/image2.png
13551521
@@ -1633,5 +1799,18 @@ evalsoc的外设配置。
16331799
16341800.. |image-nice-10 | image :: /asserts/nucleistudio/advanceusage/nice-10.png
16351801
1802+ .. |image-gcc2llvm-1 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-1.png
1803+
1804+ .. |image-gcc2llvm-2 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-2.png
1805+
1806+ .. |image-gcc2llvm-3 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-3.png
1807+
1808+ .. |image-gcc2llvm-4 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-4.png
1809+
1810+ .. |image-gcc2llvm-5 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-5.png
1811+
1812+ .. |image-gcc2llvm-6 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-6.png
16361813
1814+ .. |image-gcc2llvm-7 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-7.png
16371815
1816+ .. |image-gcc2llvm-8 | image :: /asserts/nucleistudio/advanceusage/gcc2llvm-8.png
0 commit comments