diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..119d72a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 3.14.1) #cmake最低版本要求 + +project(UniProton LANGUAGES C ASM) #项目名字为UniProton + + +############################## 外部传入变量 ############################## +set(CPU_TYPE "$ENV{CPU_TYPE}" ) +set(PLAM_TYPE "$ENV{PLAM_TYPE}" ) +set(LIB_TYPE "$ENV{LIB_TYPE}" ) +set(UNIPROTON_PACKING_PATH "$ENV{UNIPROTON_PACKING_PATH}" ) #UNIPROTON_PACKING_PATH +set(COMPILE_OPTION "$ENV{COMPILE_OPTION}" ) #编译选项 空为默认全编译 还有coverity/fortify +set(CONFIG_FILE_PATH "$ENV{CONFIG_FILE_PATH}" ) #defconfig及其头文件所在目录 +string(TOUPPER ${PLAM_TYPE} PLAM_TYPE_UP) #转大写 +set(SYSTEM "$ENV{SYSTEM}" ) +set(CORE "$ENV{CORE}" ) +set(LIB_RUN_TYPE "$ENV{LIB_RUN_TYPE}" ) +set(HOME_PATH "$ENV{HOME_PATH}" ) +set(BUILD_MACHINE_PLATFORM "$ENV{BUILD_MACHINE_PLATFORM}" ) +set(RPROTON_BINARY_DIR "$ENV{RPROTON_BINARY_DIR}" ) + +if("${RPROTON_BINARY_DIR}" STREQUAL "") + # this branch will be taken + set(RPROTON_BINARY_DIR ${PROJECT_SOURCE_DIR}/build/output) +else() + set(RPROTON_BINARY_DIR ${RPROTON_BINARY_DIR}/UniProton/tmp/output) +endif() + +message("UniProton BINARY_DIR=${RPROTON_BINARY_DIR}") + +######该参数的判断逻辑脚本来实现一个XCache的开关###### +if (CACHE) + find_program(CACHE_FOUND ${CACHE}) + set(CACHE_TOOL "${CACHE}") +endif() +if(CACHE_FOUND) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CACHE_TOOL}) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CACHE_TOOL}) +endif() + +############################## 公共函数定义导入 ############################## +include(${HOME_PATH}/cmake/functions/uniproton_functions.cmake) + +############################## 编译参数 ################################## +#下述这些参数的设置要放在项目设置之后! +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${RPROTON_BINARY_DIR}/${CPU_TYPE}/${PLAM_TYPE}/${LIB_RUN_TYPE}") #库文件输出路径 +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}) + +############################## 调试打印 ############################## +message("CMAKE_C_COMPILER is ${CMAKE_C_COMPILER}") +message("CMAKE_AR is ${CMAKE_AR}") +message("CMAKE_LINKER is ${CMAKE_LINKER}") +message("CMAKE_INSTALL_PREFIX is ${CMAKE_INSTALL_PREFIX}") +message("BUILD_MACHINE_PLATFORM= ${BUILD_MACHINE_PLATFORM}") +message("CONFIG_FILE_PATH= ${CONFIG_FILE_PATH}") + +if (${COMPILE_MODE} STREQUAL "debug") +add_compile_options("-g") #编译 -g 选项,打开后可以在sdk调试时看到调试信息 +endif() +message("=============== COMPILE_MODE is ${COMPILE_MODE} ===============") +############################## 通过.config文件引入编译宏 ################## +# #函数import_kconfig把.config文件中的定义转换为cmake变量,用于后续子文件夹中决定是否编译某库 +import_kconfig(${CONFIG_FILE_PATH}/defconfig) +##############################include 头文件############################## +#可能和平台相关 +include_directories( + ${CONFIG_FILE_PATH} + ./src/arch/include + ./src/core/ipc/include + ./src/core/kernel/include + ./src/include/uapi + ./src/mem/include + ./src/om/include + ./src/utility/lib/include + ./platform/libboundscheck/include +) + + +if (NOT ${COMPILE_OPTION} STREQUAL "UniProton") +###添加安全库的cmakelists +add_subdirectory(platform) +endif() + +if (NOT ${COMPILE_OPTION} STREQUAL "sec") +###添加源码目录的cmakelists +add_subdirectory(src) + +##############################不同平台,根据需要链接出不同的lib库############ +include(./cmake/tool_chain/${CPU_TYPE}_${PLAM_TYPE}.cmake) +endif() diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..67ad8ef --- /dev/null +++ b/LICENSE @@ -0,0 +1,127 @@ + 木兰宽松许可证, 第2版 + + 木兰宽松许可证, 第2版 + 2020年1月 http://license.coscl.org.cn/MulanPSL2 + + + 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: + + 0. 定义 + + “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 + + “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 + + “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 + + “法人实体”是指提交贡献的机构及其“关联实体”。 + + “关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 + + 1. 授予版权许可 + + 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 + + 2. 授予专利许可 + + 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 + + 3. 无商标许可 + + “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 + + 4. 分发限制 + + 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 + + 5. 免责声明与责任限制 + + “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 + + 6. 语言 + “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 + + 条款结束 + + 如何将木兰宽松许可证,第2版,应用到您的软件 + + 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: + + 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; + + 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; + + 3, 请将如下声明文本放入每个源文件的头部注释中。 + + Copyright (c) [Year] [name of copyright holder] + [Software Name] is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + + + Mulan Permissive Software License,Version 2 + + Mulan Permissive Software License,Version 2 (Mulan PSL v2) + January 2020 http://license.coscl.org.cn/MulanPSL2 + + Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: + + 0. Definition + + Software means the program and related documents which are licensed under this License and comprise all Contribution(s). + + Contribution means the copyrightable work licensed by a particular Contributor under this License. + + Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. + + Legal Entity means the entity making a Contribution and all its Affiliates. + + Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. + + 1. Grant of Copyright License + + Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. + + 2. Grant of Patent License + + Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. + + 3. No Trademark License + + No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. + + 4. Distribution Restriction + + You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. + + 5. Disclaimer of Warranty and Limitation of Liability + + THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + 6. Language + + THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. + + END OF THE TERMS AND CONDITIONS + + How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software + + To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: + + i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; + + ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package; + + iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. + + + Copyright (c) [Year] [name of copyright holder] + [Software Name] is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..1f5b081 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +## UniProton介绍 + +UniProton主要目的在于为上层业务软件提供一个统一的操作系统平台,屏蔽底层硬件差异,并提供强大的调试功能。使得业务软件可在不同的硬件平台之间快速移植,方便产品芯片选型,降低硬件采购成本和软件维护成本。 + +一、搭建UniProton开发环境 +---------- +#### 1、下载源码 +```bash +git clone https://gitee.com/openeuler/UniProton.git +``` + +##### 源码目录 +[源码目录介绍](./doc/design/architecture_design.md) + +#### 2、创建开发工程 + +[hello word示例](./doc/getting_started.md) + +#### 3、编译 + +[编译步骤](./doc/UniProton_build.md) + +二、功能介绍 +---------- + +- [任务](./doc/design/task.md) +- [中断](./doc/design/hwi.md) +- [事件](./doc/design/event.md) +- [队列](./doc/design/queue.md) +- [信号量](./doc/design/sem.md) +- [内存管理](./doc/design/mem.md) +- [软件定时器](./doc/design/timer.md) +- [异常](./doc/design/exc.md) +- [错误处理](./doc/design/err.md) +- [cpu占用率](./doc/design/cpup.md) + +三、免责声明 +---------- +1. 当前开源版本仅支持cortex_m4芯片,默认编译脚本的安全编译选项仅支持栈保护,其他选项由用户根据需要自行添加。 +2. 遵循MulanPSL2开源许可协议 + +四、如何贡献 +---------- +我们非常欢迎新贡献者加入到项目中来,也非常高兴能为新加入贡献者提供指导和帮助。在您贡献代码前,需要先签署[CLA](https://openeuler.org/en/cla.html)。 diff --git a/build.py b/build.py new file mode 100644 index 0000000..b457dd9 --- /dev/null +++ b/build.py @@ -0,0 +1,259 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# The build entrance of UniProton. +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. + +import os +import sys +import time +import shutil +import subprocess +import platform +from sys import argv +UniProton_home = os.path.dirname(os.path.abspath(__file__)) +sys.path.insert(0, "%s/cmake/common/build_auxiliary_script"%UniProton_home) +from make_buildef import make_buildef +sys.path.insert(0, "%s/build/uniproton_ci_lib"%UniProton_home) +import globle +from logs import BuilderNolog, log_msg +from get_config_info import * + + +class Compile: + + # 根据makechoice获取config的配置的环境,compile_mode, lib_type, + def get_config(self, cpu_type, cpu_plat): + self.compile_mode = get_compile_mode() + self.lib_type, self.plam_type, self.hcc_path, self.kconf_dir, self.system, self.core = get_cpu_info(cpu_type, cpu_plat, self.build_machine_platform) + if not self.compile_mode and self.lib_type and self.plam_type and self.hcc_path and self.kconf_dir: + log_msg('error', 'load config.xml env error') + sys.exit(0) + self.config_file_path = '%s/build/uniproton_config/config_%s'%(self.home_path, self.kconf_dir) + + self.objcopy_path = self.hcc_path + + def setCmdEnv(self): + self.build_time_tag = time.strftime('%Y-%m-%d_%H:%M:00') + self.log_dir = '%s/logs/%s' % (self.build_dir, self.cpu_type) + self.log_file = '%s.log' % self.kconf_dir + + def SetCMakeEnviron(self): + os.environ["CPU_TYPE"] = self.cpu_type + os.environ["PLAM_TYPE"] = self.plam_type + os.environ["LIB_TYPE"] = self.lib_type + os.environ["COMPILE_OPTION"] = self.compile_option + os.environ["HCC_PATH"] = self.hcc_path + os.environ["UNIPROTON_PACKING_PATH"] = self.UniProton_packing_path + os.environ["CONFIG_FILE_PATH"] = self.config_file_path + os.environ["LIB_RUN_TYPE"] = self.lib_run_type + os.environ["HOME_PATH"] = self.home_path + os.environ["COMPILE_MODE"] = self.compile_mode + os.environ["BUILD_MACHINE_PLATFORM"] = self.build_machine_platform + os.environ["SYSTEM"] = self.system + os.environ["CORE"] = self.core + os.environ["OBJCOPY_PATH"] = self.objcopy_path + os.environ['PATH'] = '%s:%s' % (self.hcc_path, os.getenv('PATH')) + + # 环境准备,准备执行cmake,make,makebuildfile,CmakeList需要的环境 + # 每次compile之前请调用该函数 + def prepare_env(self, cpu_type, choice): + # makebuildfile需要的环境kconf_dir + # cmake需要的环境cmake_env_path,home_path(cmakelist所在的路径),home_path, + # make cmd拼接需要的环境:home_path,UniProton_make_jx,log_dir,log_file,build_time_tag, UniProton_make_jx + + #根据cpu_type, choice从config文件中获取并初始化初始化hcc_path, plam_type, kconf_dir + #根据输入分支获取 + #从编译镜像环境获取 + self.get_config(cpu_type, choice) + self.setCmdEnv() + self.SetCMakeEnviron() + + #获取编译环境是arm64还是x86,用户不感知,并将其写入环境变量。 + def getOsPlatform(self): + self.cmake_env_path = get_tool_info('cmake', 'tool_path') + + if platform.uname()[-1] == 'aarch64': + self.build_machine_platform = 'arm64' + else: + self.build_machine_platform = 'x86' + + # 获取当前编译的路径信息,配置文件信息,编译选项信息 + def __init__(self, cpu_type: str, make_option="normal", lib_run_type="FPGA", choice="ALL", make_phase="ALL", + UniProton_packing_path=""): + # 当前路径信息 + self.system = "" + self.objcopy_path = "" + self.builder = None + self.compile_mode = "" + self.core = "" + self.plam_type = "" + self.kconf_dir = "" + self.build_tmp_dir = "" + self.log_dir = "" + self.lib_type = "" + self.hcc_path = "" + self.log_file = "" + self.config_file_path = "" + self.build_time_tag = "" + self.build_dir = globle.build_dir + self.home_path = globle.home_path + self.kbuild_path = globle.kbuild_path + # 当前选项信息 + self.cpu_type = cpu_type + self.compile_option = make_option + self.lib_run_type = lib_run_type + self.make_choice = choice.lower() + self.make_phase = make_phase + self.UniProton_packing_path = UniProton_packing_path if make_phase == "CREATE_CMAKE_FILE" else '%s/output'%self.home_path + self.UniProton_binary_dir = os.getenv('RPROTON_BINARY_DIR') + self.UniProton_install_file_option = os.getenv('RPROTON_INSTALL_FILE_OPTION') + self.UniProton_make_jx = 'VERBOSE=1' if self.UniProton_install_file_option == 'SUPER_BUILD' else 'VERBOSE=1 -j$(nproc)' + # 当前编译平台信息 + self.getOsPlatform() + + #调用cmake生成Makefile文件,需要 + def CMake(self): + if self.UniProton_binary_dir: + self.build_tmp_dir = '%s/output/tmp/%s' % (self.UniProton_binary_dir, self.kconf_dir) + else: + self.build_tmp_dir = '%s/output/tmp/%s' % (self.build_dir, self.kconf_dir) + os.environ['BUILD_TMP_DIR'] = self.build_tmp_dir + + if not os.path.exists(self.build_tmp_dir): + os.makedirs(self.build_tmp_dir) + if not os.path.exists(self.log_dir): + os.makedirs(self.log_dir) + + log_msg('info', 'BUILD_TIME_TAG %s' % self.build_time_tag) + self.builder = BuilderNolog(os.path.join(self.log_dir, self.log_file)) + if self.make_phase in ['CREATE_CMAKE_FILE', 'ALL']: + real_path = os.path.realpath(self.build_tmp_dir) + if os.path.exists(real_path): + shutil.rmtree(real_path) + os.makedirs(self.build_tmp_dir) + #拼接cmake命令 + if self.compile_option == 'fortify': + cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \ + '-DCMAKE_C_COMPILER_LAUNCHER="sourceanalyzer;-b;%sproject" ' \ + '-DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % ( + self.cmake_env_path, self.home_path, self.home_path, self.cpu_type, + self.UniProton_packing_path, self.log_dir, self.log_file) + elif self.compile_option == 'hllt': + cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \ + '-DCMAKE_C_COMPILER_LAUNCHER="lltwrapper" -DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % ( + self.cmake_env_path, self.home_path, self.home_path, self.UniProton_packing_path, self.log_dir, self.log_file) + else: + cmd = '%s/cmake %s -DCMAKE_TOOLCHAIN_FILE=%s/cmake/tool_chain/uniproton_tool_chain.cmake ' \ + '-DCMAKE_INSTALL_PREFIX=%s &> %s/%s' % ( + self.cmake_env_path, self.home_path, self.home_path, self.UniProton_packing_path, self.log_dir, self.log_file) + #执行cmake命令 + if self.builder.run(cmd, cwd=self.build_tmp_dir, env=None): + log_msg('error', 'generate makefile failed!') + return False + + log_msg('info', 'generate makefile succeed.') + return True + + def UniProton_clean(self): + for foldername,subfoldernames,filenames in os.walk(self.build_dir): + for subfoldername in subfoldernames: + if subfoldername in ['logs','output','__pycache__']: + folder_path = os.path.join(foldername,subfoldername) + shutil.rmtree(os.path.relpath(folder_path)) + for filename in filenames: + if filename == 'prt_buildef.h': + file_dir = os.path.join(foldername,filename) + os.remove(os.path.relpath(file_dir)) + if os.path.exists('%s/cmake/common/build_auxiliary_script/__pycache__'%self.home_path): + shutil.rmtree('%s/cmake/common/build_auxiliary_script/__pycache__'%self.home_path) + if os.path.exists('%s/output'%self.home_path): + shutil.rmtree('%s/output'%self.home_path) + if os.path.exists('%s/tools/SRE/x86-win32/sp_makepatch/makepatch'%self.home_path): + os.remove('%s/tools/SRE/x86-win32/sp_makepatch/makepatch'%self.home_path) + if os.path.exists('%s/build/prepare/__pycache__'%self.home_path): + shutil.rmtree('%s/build/prepare/__pycache__'%self.home_path) + return True + + + def make(self): + if self.make_phase in ['EXECUTING_MAKE', 'ALL']: + self.builder.run('make clean', cwd=self.build_tmp_dir, env=None) + tmp = sys.argv + if self.builder.run( + 'make all %s &>> %s/%s' % ( + self.UniProton_make_jx, self.log_dir, self.log_file), cwd=self.build_tmp_dir, env=None): + log_msg('error', 'make %s %s failed!' % (self.cpu_type, self.plam_type)) + return False + sys.argv = tmp + if self.compile_option in ['normal', 'coverity', 'single']: + if self.builder.run('make install %s &>> %s/%s' % (self.UniProton_make_jx, self.log_dir, self.log_file), cwd=self.build_tmp_dir, env=None): + log_msg('error', 'make install failed!') + return False + if os.path.exists('%s/%s' % (self.log_dir, self.log_file)): + self.builder.log_format() + + log_msg('info', 'make %s %s succeed.' % (self.cpu_type, self.plam_type)) + return True + + def SdkCompaile(self)->bool: + # 判断该环境中是否需要编译 + if self.hcc_path == 'None': + return True + + self.MakeBuildef() + if self.CMake() and self.make(): + log_msg('info', 'make %s %s lib succeed!' % (self.cpu_type, self.make_choice)) + return True + else: + log_msg('info', 'make %s %s lib failed!' % (self.cpu_type, self.make_choice)) + return False + + # 对外函数,调用后根据类初始化时的值进行编译 + def UniProtonCompile(self): + #清除UniProton缓存 + if self.cpu_type == 'clean': + log_msg('info', 'UniProton clean') + return self.UniProton_clean() + # 根据cpu的编译平台配置相应的编译环境。 + if self.make_choice == "all": + for make_choice in globle.cpu_plat[self.cpu_type]: + self.prepare_env(self.cpu_type, make_choice) + if not self.SdkCompaile(): + return False + else: + self.prepare_env(self.cpu_type, self.make_choice) + if not self.SdkCompaile(): + return False + return True + + def MakeBuildef(self): + + if not make_buildef(globle.home_path,self.kconf_dir,"CREATE"): + sys.exit(1) + log_msg('info', 'make_buildef_file.sh %s successfully.' % self.kconf_dir) + +# argv[1]: cpu_plat 表示要编译的平台: +# argv[2]: compile_option 控制编译选项,调用不同的cmake参数,目前只有normal coverity hllt fortify single(是否编译安全c,组件化独立构建需求) +# argv[3]: lib_run_type lib库要跑的平台 faga sim等 +# argv[4]: make_choice +# argv[5]: make_phase 全量构建选项 +# argv[6]: UniProton_packing_path lib库的安装位置 +if __name__ == "__main__": + default_para = ("all", "normal", "FPGA", "ALL", "ALL", "") + if len(argv) == 1: + para = [default_para[i] for i in range(0, len(default_para))] + else: + para = [argv[i+1] if i < len(argv) - 1 else default_para[i] for i in range(0,len(default_para))] + + cur_cpu_type = para[0].lower() + cur_compile_option = para[1].lower() + cur_lib_run_type = para[2] + cur_make_choice = para[3] + cur_make_phase = para[4] + cur_UniProton_packing_path = para[5] + for plat in globle.cpus_[cur_cpu_type]: + UniProton_build = Compile(plat, cur_compile_option, cur_lib_run_type, cur_make_choice, cur_make_phase, cur_UniProton_packing_path) + if not UniProton_build.UniProtonCompile(): + sys.exit(1) + sys.exit(0) + diff --git a/build/uniproton_ci_lib/get_config_info.py b/build/uniproton_ci_lib/get_config_info.py new file mode 100644 index 0000000..2259c4e --- /dev/null +++ b/build/uniproton_ci_lib/get_config_info.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# The build entrance of UniProton. +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. +import xml.dom.minidom +import sys +import logging +import globle +from logs import BuilderNolog, log_msg + + +logging.basicConfig(level=logging.NOTSET) +logging.info(globle.config_dir) +config_tree = xml.dom.minidom.parse(globle.config_dir) +EXCEPTION_LIST = (AssertionError, AttributeError, IOError, + ImportError, IndentationError, + IndexError, KeyError, NameError, + SyntaxError, TypeError, ValueError) + +def getNodeValue(node, index = 0): + return node.childNodes[index].nodeValue + +def getXmlNode(node, name): + return node.getElementsByTagName(name) + +def getNodeAtrrValue(node, attrname): + return node.getAttribute(attrname) + +def getChildNodeValueByNodeName(farthe_node, nodename, index = 0): + return farthe_node.getElementsByTagName(nodename)[0].childNodes[index].nodeValue + +def getChildNodeByNodeAtrr(farthe_node, node_name, atrr_name, strr_vlue): + for node in farthe_node.getElementsByTagName(node_name): + if node.getAttribute(atrr_name).startswith(strr_vlue): + return node + return False + +# 根据cputype获取hcc_path, kconf_dir, plam_type +def get_cpu_info(cpu_type, cpu_plat, os_plat): + nameNode = "project" + cpu_list = config_tree.documentElement.getElementsByTagName(nameNode) + hcc_path, kconf_dir, plam_type, lib_type = "", "", "", "" + try: + for cpu in cpu_list: + if getNodeAtrrValue(cpu, "cpu_type") == cpu_type: + lib_type = getChildNodeValueByNodeName(cpu, "lib_type") + plam_type = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "name") + hcc_path = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "compile_path_{}".format(os_plat)) + kconf_dir = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "kconf_dir") + except EXCEPTION_LIST: + log_msg('error', "get cpu {} config info error:{} {}".format(cpu_type, cpu_plat, os_plat)) + sys.exit(0) + + system, core = "None", "None" + try: + for cpu in cpu_list: + if getNodeAtrrValue(cpu, "cpu_type") == cpu_type: + core = getChildNodeValueByNodeName(getChildNodeByNodeAtrr(cpu, "platform", "plat_name", cpu_plat), "core") + system = getChildNodeValueByNodeName(cpu, "system") + except EXCEPTION_LIST: + system = "None" + return lib_type, plam_type, hcc_path, kconf_dir, system, core + +def get_tool_info(tool_name, node_name): + tool_list = config_tree.documentElement.getElementsByTagName("tool") + try: + for tool in tool_list: + if getNodeAtrrValue(tool, "tool_name") == tool_name: + return getChildNodeValueByNodeName(tool, node_name) + except EXCEPTION_LIST: + log_msg("error", "get tool config info error:{} {}".format(tool_name, node_name)) + sys.exit(0) + return False + + +def get_compile_mode(): + nameNode = "UniProton_compile_mode" + cpu_list = config_tree.documentElement.getElementsByTagName(nameNode) + compile_mode = getNodeValue(cpu_list[0]) + return compile_mode diff --git a/build/uniproton_ci_lib/globle.py b/build/uniproton_ci_lib/globle.py new file mode 100644 index 0000000..800e465 --- /dev/null +++ b/build/uniproton_ci_lib/globle.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# The build entrance of UniProton. +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. +import os + + +build_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +home_path = os.path.dirname(build_dir) +config_dir = os.path.join(home_path,'config.xml') +kbuild_path = '%s/cmake/common/build_auxiliary_script' % home_path + +cpus_ = {'all': ['clean', 'm4'], + 'clean':['clean'], + 'm4': ['m4'] + } + +cpu_plat = {'m4': ['cortex'] + } diff --git a/build/uniproton_ci_lib/logs.py b/build/uniproton_ci_lib/logs.py new file mode 100644 index 0000000..c2e9bfb --- /dev/null +++ b/build/uniproton_ci_lib/logs.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# The build entrance of UniProton. +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. + +import os +import re +import sys +import time +import logging +import globle + + +logging.basicConfig(level=logging.NOTSET) + +class BuilderNolog(): + + def __init__(self,log_file): + self.log_file = log_file + self.loglevel = 'INFO' + + def run(self, cmd, cwd=os.getcwd(), env=None): + exit_code = os.system('cd %s && %s' % (cwd, cmd)) + if exit_code != 0: + with open(self.log_file) as file_handle: + for line in file_handle.readlines(): + logging.info(line) + logging.info("\n--[INFO] more message in logfile [%s] env: [%s]" ,self.log_file, env) + return exit_code + + def log_format(self): + try: + sys.path.append(("%s%s") % (globle.home_path, "/../cmake")) + import logcode_format + formatter = (logcode_format.init_format(os.getcwd().split('/')[-1])) + except ImportError: + formatter = '%(asctime)s -- %(levelname)s [UniProton] -- : %(message)s' + + logger_root = logging.getLogger() + for handler in logger_root.handlers: + logger_root.removeHandler(handler) + + with open(self.log_file, 'r') as rd: + lines = rd.readlines() + os.remove(self.log_file) + + logformat = logging.Formatter(formatter) + fh = logging.FileHandler(self.log_file, mode='a', encoding=sys.getdefaultencoding()) + fh.setLevel(self.loglevel) + fh.setFormatter(logformat) + + logger = logging.getLogger('UniProton') + logger.setLevel(self.loglevel) + for handler in logger.handlers: + logger.removeHandler(handler) + logger.addHandler(fh) + + for line in lines: + logger.info(line.strip()) + return + + +def log_msg(level,msg): + logging.info('[%s] %s %s %s', level.upper(),'#'*20,msg,'#'*20) diff --git a/build/uniproton_config/config_m4/defconfig b/build/uniproton_config/config_m4/defconfig new file mode 100644 index 0000000..7b79a8d --- /dev/null +++ b/build/uniproton_config/config_m4/defconfig @@ -0,0 +1,116 @@ +# +# Automatically generated file; DO NOT EDIT. +# UniProton Configuration +# + +# +# Arch Modules Configuration +# +CONFIG_OS_ARCH_ARMV7_M=y + +# +# ARM7-M Sepecfic Configuration +# +CONFIG_INTERNAL_OS_CORTEX_M4=y +CONFIG_INTERNAL_OS_PLATFORM_M4=y + +# +# M4 Sepecfic Configuration +# + +# +# Generic Configuration +# +CONFIG_OS_HARDWARE_PLATFORM="OS_CORTEX_M4" +CONFIG_OS_CPU_TYPE="OS_STM32F407" +CONFIG_OS_MAX_CORE_NUM=1 +CONFIG_INTERNAL_OS_BYTE_ORDER_LE=y +CONFIG_OS_BYTE_ORDER="OS_LITTLE_ENDIAN" + +# +# Core Modules Configuration +# + +# +# IPC Modules Configuration +# + +# +# Event feature configuration +# +CONFIG_OS_OPTION_EVENT=y +CONFIG_OS_OPTION_QUEUE=y + +# +# Semaphore feature configuration +# + +# +# Kernel Modules Configuration +# + +# +# IRQ Modules Configuration +# +CONFIG_OS_OPTION_HWI_COMBINE=y +CONFIG_OS_OPTION_HWI_PRIORITY=y +CONFIG_OS_OPTION_HWI_ATTRIBUTE=y +CONFIG_OS_OPTION_HWI_MAX_NUM_CONFIG=y + +# +# Exc Modules Configuration +# + +# +# Task module Configuration +# +CONFIG_OS_OPTION_TASK=y + +# +# TASK features configuration +# +CONFIG_OS_OPTION_TASK_DELETE=y +CONFIG_OS_OPTION_TASK_SUSPEND=y +CONFIG_OS_OPTION_TASK_INFO=y +CONFIG_OS_OPTION_TASK_YIELD=y +CONFIG_OS_TSK_PRIORITY_HIGHEST=0 +CONFIG_OS_TSK_PRIORITY_LOWEST=31 +CONFIG_OS_TSK_NUM_OF_PRIORITIES=32 +CONFIG_OS_TSK_CORE_BYTES_IN_PID=2 + +# +# Timer Modules Configuration +# +CONFIG_INTERNAL_OS_SWTMR=y + +# +# MM Modules Configuration +# + +# +# OM Modules Configuration +# +CONFIG_OS_OPTION_CPUP=y + +# +# CPUP features configuration +# +CONFIG_INTERNAL_OS_CPUP_THREAD=y +CONFIG_OS_OPTION_CPUP_WARN=y + +# +# Error Report Module Configuration +# + +# +# Hook feature configuration +# + +# +# security Modules Configuration +# +CONFIG_OS_OPTION_RND=y + +# +# Utility Modules Configuration +# diff --git a/cmake/common/build_auxiliary_script/Kconfig2macro.py b/cmake/common/build_auxiliary_script/Kconfig2macro.py new file mode 100644 index 0000000..0472e90 --- /dev/null +++ b/cmake/common/build_auxiliary_script/Kconfig2macro.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# Transfer kconfig configuration file to buildef/config file. +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. + +import os +import sys +import time +import getopt +import re +import logging +import codecs + + +logging.basicConfig(level=logging.NOTSET) + +HEADER_TYPE_BUILD = 0 +HEADER_TYPE_CONFIG = 1 +HEADER_TYPE_INVALID = 2 + +def cmd_help(): + logging.info("Interpret the configuration file which was generated by Kconfig tool, and") + logging.info("Transfer it to header file which will be used in C code") + logging.info("Command format:") + logging.info(" Kconfig2macro.py [-e][-f configFileName] [-o headerFileName]") + logging.info("The default configFileName is .config") + logging.info("The default headerFileName is config.h") + +def headerType(in_file): + with open(in_file, 'r') as fd_in: + lines = fd_in.readlines() + for line in lines: + + if line.find("CONFIG_OS_HARDWARE_PLATFORM=") >= 0: + return HEADER_TYPE_BUILD + return HEADER_TYPE_CONFIG + + +def write_header(out_file): + with codecs.open(out_file, + 'w', + encoding='gbk', + errors='ignore') as fd_out: + file_path, file_name = os.path.split(out_file) + name = ((str(file_name)).split('.'))[0] + header_macro = '%s_H' % (str.upper(name)) + text = r'''/* + * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved. + * + * UniProton is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + * Create: 2009-12-22 + * Description: the common part buildef.h + */ +''' + + text = '%s#ifndef %s\n' % (text, header_macro) + text = '%s#define %s\n' % (text, header_macro) + text = '%s\n' % (text) + text = '%s#ifdef __cplusplus\n#if __cplusplus\nextern "C" {\n#endif\n#endif\n' % (text) + + fd_out.write(text) + return 0 + + +def get_macro_fix(macro): + prefix = "" + suffix = "\n" + if macro == "OS_HARDWARE_PLATFORM" or macro == "OS_CPU_TYPE" or macro == "OS_BYTE_ORDER": + prefix = '#ifndef %s\n' % (macro) + suffix = "#endif\n\n" + + return prefix, suffix + +def write_macro(fd_out, line, flag): + export_flag = False + match_s = re.search(r'\w+', line) + if match_s is None: + return + + macro = match_s.group() + if not macro.startswith("CONFIG_"): + return + + macro = macro[len("CONFIG_"):] + if macro.startswith("INTERNAL_"): + return + + if macro.startswith("EXPORT_"): + macro = macro[len("EXPORT_"):] + export_flag = flag + + if line.find("is not set") >= 0: + value = "NO" + else: + expression = line.split("=", 1) + if len(expression) < 2: + return + value = expression[1].strip() + if value == 'y': + value = "" + prefix, suffix = get_macro_fix(macro) + text = '%s#define %s %s\n%s' %(prefix ,macro, value.strip('"'), suffix) + if export_flag == True or flag == False: + fd_out.write(text.rstrip() + "\n\n") +def write_config(in_file, out_file, flag): + with codecs.open(out_file, 'a+') as fd_out, open(in_file) as fd_in: + fd_out.write("\n") + lines = fd_in.readlines() + for line in lines: + if line.startswith('##'): + fd_out(line.replace("##", "/*") + "*/") + elif line.startswith("CONFIG_"): + write_macro(fd_out, line, flag) + + return 0 + +def write_def_config(filename, string): + with open(filename, 'r', errors='ignore') as fp: + for line in fp: + if string in line: + return line + + with codecs.open(file, 'a+') as fd_in: + text = '#define %-35s NO \n\n' %(str) + + fd_in.write(text) + + return 0 + +def write_external_macro(out_file): + with codecs.open(out_file, 'a+') as fd_out: + + text = '#define OS_LITTLE_ENDIAN 0x1234\n\n#define OS_BIG_ENDIAN 0x4321\n\n#define OS_CORTEX_M4 0x1\n\n#define OS_STM32F407 0x1\n\n' + + fd_out.write(text) + + return 0 + +def write_c_external_tail(out_file): + with codecs.open(out_file, 'a+') as fd_out: + + + text = '#ifdef __cplusplus\n#if __cplusplus\n}\n#endif\n#endif\n' + + fd_out.write(text) + + return 0 + +def write_tail(out_file): + with codecs.open(out_file, 'a+') as fd_out: + + text = '\n#endif\n' + + fd_out.write(text) + + return 0 + +def kconfig2macro(in_file, out_file, flag): + header_type = headerType(in_file) + if header_type == HEADER_TYPE_INVALID: + return -10 + + ret = write_header(out_file) + if ret != 0: + return ret + + ret = write_config(in_file, out_file, flag) + if ret != 0: + return ret + + ret = write_external_macro(out_file) + if ret != 0: + return ret + + ret = write_c_external_tail(out_file) + if ret != 0: + return ret + + ret = write_tail(out_file) + if ret != 0: + return ret + + return 0 +def do_cmd(argv, flag): + in_file = ".config" + out_file = "config.h" + + try: + opts, args = getopt.getopt(argv,"ehf:o:",["help", "inFile=", "outFile="]) + except getopt.GetoptError: + cmd_help() + return -1 + + if len(args) > 0: + cmd_help() + return -2 + + for opt, arg in opts: + if opt in ('-h', '--help'): + cmd_help() + return 0 + elif opt in ('-e'): + flag = True + elif opt in ('-f', '--inFile'): + in_file = arg + elif opt in ('-o', '--outFile'): + out_file = arg + else: + logging.error("ERROR: Invalid Input %s", opt) + cmd_help() + return -3 + + if os.path.exists(in_file) == False: + logging.info("config input file <%s> doesn't exist", in_file) + return -4 + + return kconfig2macro(in_file, out_file, flag) + + +if __name__ == "__main__": + res = do_cmd(sys.argv[1:], False) + sys.exit(res) diff --git a/cmake/common/build_auxiliary_script/make_buildef.py b/cmake/common/build_auxiliary_script/make_buildef.py new file mode 100644 index 0000000..4b8197b --- /dev/null +++ b/cmake/common/build_auxiliary_script/make_buildef.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# coding=utf-8 +# Transfer kconfig configuration file to buildef/config file. +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. + +import os +import sys +import logging +from Kconfig2macro import do_cmd + + +logging.basicConfig(level=logging.NOTSET) + +def make_buildef(home_path, kconf_dir, choice): + kconfig_dir = "{}/build/uniproton_config/config_{}/defconfig".format(home_path,kconf_dir) + buildef_file = "{}/build/uniproton_config/config_{}/prt_buildef.h".format(home_path,kconf_dir) + if choice == "CREATE": + paras = ["-f", kconfig_dir, "-o", buildef_file] + if do_cmd(paras, False) != 0: + logging.info("build prt_buildef.h failed.") + return False + logging.info("build prt_buildef.h succeed.") + elif choice == "EXPORT": + paras = ["-e", "-f", kconfig_dir, "-o", buildef_file] + if do_cmd(paras, False) != 0: + logging.info("export prt_buildef.h failed.") + return False + logging.info("export prt_buildef.h succeed.") + else: + os.remove(buildef_file) + return True diff --git a/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh b/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh new file mode 100644 index 0000000..eb30515 --- /dev/null +++ b/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh @@ -0,0 +1,62 @@ +#!/bin/bash +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. + +set -e +if [ $# != 3 ] ; then + echo "USAGE: $0 AR_TOOL_PATH CK_LIB_PATH CK_LIB_SUFFIX" + exit 1; +fi + + +AR_TOOL_PATH="$1" +CK_LIB_PATH="$2" +CK_LIB_SUFFIX="$3" +file=lib"${CK_LIB_SUFFIX}" + + +if [ "${CPU_TYPE}" = "m4" ] ; then + ARNAME=arm-none-eabi-ar ; OBJCOPYNAME=arm-none-eabi-objcopy; +else + ARNAME=ar; OBJCOPYNAME=objcopy; +fi + +sleep 2 +pushd "$CK_LIB_PATH" +##为什么不加这一行要报错 +if [ "${CPU_TYPE}" = "m4" ] ; then + [ -n tmp_"${file}" ] && rm -rf tmp_"${file}" +fi +mkdir tmp_"${file}" +mv "$file" tmp_"${file}"/ + +pushd tmp_"${file}" +"$AR_TOOL_PATH"/"${ARNAME}" -x "$file" +# 删除某变量指定的目录下所有文件。 +# 通过对变量${FILE_PATH}进行判断,当${FILE_PATH}为空时,不会错误删除根目录下的文件。 +[ -n "${file}" ] && rm -rf "${file}" +if [ "${CPU_TYPE}" = "m4" ] ; then + find . -name '*.s.o'| awk -F "." '{print $2}'|xargs -I'{}' mv ./{}.s.o ./{}.o + find . -name '*.S.o'| awk -F "." '{print $2}'|xargs -I'{}' mv ./{}.S.o ./{}.o + find . -name '*.c.o'| awk -F "." '{print $2}'|xargs -I'{}' mv ./{}.c.o ./{}.o + + for i in $(ls *.o); + do + if [ -f "${i}" ] ; then + "${AR_TOOL_PATH}"/"${OBJCOPYNAME}" --remove-section=.comment -I elf32-littlearm -O elf32-littlearm "${i}" "${i}".oooo + "${AR_TOOL_PATH}"/"${OBJCOPYNAME}" --strip-unneeded "${i}".oooo + mv "${i}".oooo "${i}" + fi + done +fi + +"$AR_TOOL_PATH"/"${ARNAME}" -r -D "$file" *.o +mv "$file" ../ +popd + +# 删除某变量指定的目录下所有文件。 +# 通过对变量${FILE_PATH}进行判断,当${FILE_PATH}为空时,不会错误删除根目录下的文件。 +[ -n tmp_"${file}" ] && rm -rf tmp_"${file}" +popd + + +exit 0 \ No newline at end of file diff --git a/cmake/functions/uniproton_functions.cmake b/cmake/functions/uniproton_functions.cmake new file mode 100644 index 0000000..e365b54 --- /dev/null +++ b/cmake/functions/uniproton_functions.cmake @@ -0,0 +1,171 @@ +# Date: 2019-11-11 +# Copyright © Huawei Technologies Co., Ltd. 2010-2020. All rights reserved. +########################################################################### + + +############################## 公共函数定义区域 ############################## +## 1. import defconfig +##把.config文件转换为cmake命名空间的变量,比如把CONFIG_OS_ARCH_ARM32VX=y 转化为 cmake变量 +function(import_kconfig config_file)##.config文件转换为cmake命名空间的变量 + #### 读取Config文件 + file(STRINGS ${config_file} config_list REGEX "^CONFIG_" ENCODING "UTF-8")#### 读取Config文件 + + ##处理各个匹配行 + foreach (config ${config_list})##处理各个匹配行 + ##获取变量值 + ##字符串匹配‘=’号 + string(REGEX MATCH "=(.+$)" conf_value ${config})##字符串匹配‘=’号 + ## 获取匹配值 + set(conf_value ${CMAKE_MATCH_1})##获取匹配值 + ##匹配CONFIG_OS_HARDWARE_PLATFORM="OS_ARM7" 这种有""的情形 + if("${conf_value}" MATCHES "^\"(.*)\"$") + ##设置环境变量值 + set(conf_value ${CMAKE_MATCH_1})##设置环境变量值 + ##定义结束 + endif()##定义结束 + ##获取变量名 + ##字符串匹配‘=’号 + string(REGEX MATCH "[^=]+" conf_name ${config})##字符串匹配‘=’号 + ##声明cmake全局变量 + ##设置环境变量值 + set("${conf_name}" "${conf_value}" PARENT_SCOPE)##设置环境变量值 + ##message("${conf_name}=${conf_value}") + ##遍历结束符 + endforeach()##遍历结束符 +##功能结束符 +endfunction()##功能结束符 + + + + + + +function(cc_object target sources cppincs cflags component_name working_directory) + # @target Object: the name of the target + # @sources List[str]: the code source path of list + # @cppincs List[str]: the include directories path of list + # @cppdefines List[str]: the defines of list + # @cflags List[str]: the c compile flags of list + # @component_name str: the component name of the atrget + # @working_directory str: the directory of command execute + list(JOIN ${cppincs} "\t-I" target_incflags) + set(obj_install_dir ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${component_name}) + file(MAKE_DIRECTORY ${obj_install_dir}) + + + + foreach(source_path IN LISTS ${sources}) + get_filename_component(source_name ${source_path} NAME) + # .c替换为.eln + string(REGEX REPLACE \\.c \.o target_name ${source_name}) + string(REPLACE ${working_directory}/ "" new_source_path ${source_path}) + string(REGEX REPLACE .*/ "" current_directory ${working_directory}) + add_custom_command( + OUTPUT ${obj_install_dir}/${target_name} + COMMAND ${cc} ${${cflags}} -I${target_incflags} -o ${obj_install_dir}/${target_name} -c ${new_source_path} + DEPENDS ${source_path} + WORKING_DIRECTORY ${working_directory} + ) + add_custom_target( + ${target_name}_custom + ALL + DEPENDS ${obj_install_dir}/${target_name} + ) + + list(APPEND ${target}_list_dep ${target_name}_custom ) + list(APPEND ${target}_list__ ${obj_install_dir}/${target_name} ) + endforeach() + set(${target}_PATH_LIST ${${target}_list__} PARENT_SCOPE) + set(${target}_NAME_LIST ${${target}_list_dep} PARENT_SCOPE) +endfunction() + + +function(asm_object target sources cflags component_name working_directory) + # @target Object: the name of the target + # @sources List[str]: the code source path of list + # @cppincs List[str]: the include directories path of list + # @cppdefines List[str]: the defines of list + # @cflags List[str]: the c compile flags of list + # @component_name str: the component name of the atrget + # @working_directory str: the directory of command execute + set(obj_install_dir ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/${component_name}) + file(MAKE_DIRECTORY ${obj_install_dir}) + + + + foreach(source_path IN LISTS ${sources}) + get_filename_component(source_name ${source_path} NAME) + string(REGEX REPLACE \\.asm \.eln target_name ${source_name}) + string(REPLACE ${working_directory}/ "" new_source_path ${source_path}) + string(REGEX REPLACE .*/ "" current_directory ${working_directory}) + add_custom_command( + OUTPUT ${obj_install_dir}/${target_name} + COMMAND ${asm} ${${cflags}} -o ${obj_install_dir}/${target_name} -c ${new_source_path} + DEPENDS ${source_path} + WORKING_DIRECTORY ${working_directory} + ) + add_custom_target( + ${target_name}_custom + ALL + DEPENDS ${obj_install_dir}/${target_name} + ) + + list(APPEND ${target}_list_dep ${target_name}_custom ) + list(APPEND ${target}_list__ ${obj_install_dir}/${target_name} ) + endforeach() + set(${target}_PATH_LIST ${${target}_list__} PARENT_SCOPE) + set(${target}_NAME_LIST ${${target}_list_dep} PARENT_SCOPE) +endfunction() + + + + + +function(ar_library target_name target_suffix target_path ar_flag object_name object_path) + # @target Object: the name of the target + # @sources List[str]: the code source path of list + # @cppincs List[str]: the include directories path of list + # @cppdefines List[str]: the defines of list + # @cflags List[str]: the c compile flags of list + # @component_name str: the component name of the atrget + # @working_directory str: the directory of command execute + + add_custom_command( + OUTPUT ${target_path}/${target_name}.${target_suffix} + COMMAND ${ar} ${ar_flag} ${target_path}/${target_name}.${target_suffix} ${object_path} + WORKING_DIRECTORY ${target_path} + ) + add_custom_target( + ${target_name} + ALL + DEPENDS ${target_path}/${target_name}.${target_suffix} + ) + foreach(object_target ${object_name}) + add_dependencies(${target_name} ${object_target}) + endforeach() +endfunction() + + +function(link_library target_name target_path link_flag object_name object_path) + # @target Object: the name of the target + # @sources List[str]: the code source path of list + # @cppincs List[str]: the include directories path of list + # @cppdefines List[str]: the defines of list + # @cflags List[str]: the c compile flags of list + # @component_name str: the component name of the atrget + # @working_directory str: the directory of command execute + + add_custom_command( + OUTPUT ${target_path}/${target_name} + COMMAND ${link} ${${link_flag}} -o ${target_path}/${target_name} ${object_path} + WORKING_DIRECTORY ${target_path} + ) + add_custom_target( + ${target_name} + ALL + DEPENDS ${target_path}/${target_name} + ) + foreach(object_target ${object_name}) + add_dependencies(${target_name} ${object_target}) + endforeach() +endfunction() diff --git a/cmake/tool_chain/m4-cortex-config.cmake.in b/cmake/tool_chain/m4-cortex-config.cmake.in new file mode 100644 index 0000000..ec358a4 --- /dev/null +++ b/cmake/tool_chain/m4-cortex-config.cmake.in @@ -0,0 +1,14 @@ +@PACKAGE_INIT@ +include(${CMAKE_CURRENT_LIST_DIR}/UniProton-m4-cortex-targets.cmake) + + + +set_and_check(INSTALL_M4_CORTEX_BASE_DIR "@PACKAGE_INSTALL_M4_CORTEX_BASE_DIR@") +set_and_check(INSTALL_M4_CORTEX_INCLUDE_DIR "@PACKAGE_INSTALL_M4_CORTEX_INCLUDE_DIR@") +set_and_check(INSTALL_M4_CORTEX_INCLUDE_SEC_DIR "@PACKAGE_INSTALL_M4_CORTEX_INCLUDE_SEC_DIR@") +set_and_check(INSTALL_M4_CORTEX_ARCHIVE_DIR "@PACKAGE_INSTALL_M4_CORTEX_ARCHIVE_DIR@") +set_and_check(INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR "@PACKAGE_INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR@") +set_and_check(INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR "@PACKAGE_INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR@") +set_and_check(INSTALL_M4_CORTEX_CONFIG_DIR "@PACKAGE_INSTALL_M4_CORTEX_CONFIG_DIR@") + +check_required_components(UniProton-m4-cortex) \ No newline at end of file diff --git a/cmake/tool_chain/m4_cortex.cmake b/cmake/tool_chain/m4_cortex.cmake new file mode 100644 index 0000000..2befbf8 --- /dev/null +++ b/cmake/tool_chain/m4_cortex.cmake @@ -0,0 +1,256 @@ +set(BUILD_DIR "$ENV{BUILD_TMP_DIR}" ) #version id +set(OBJCOPY_PATH "$ENV{OBJCOPY_PATH}" ) #OBJCOPY_PATH + + + +##最终的链接目标,会生成对应的.a库 +################################################# +## arch代码 +################################################# +list(APPEND ARCH_SRCS + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ +) + +################################################# +## kernel代码 +################################################# +list(APPEND KERNEL_SRCS + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ +) +list(APPEND IPC_SRCS + $ + $ + $ + $ + $ +) +list(APPEND MEM_SRCS + $ + $ +) +list(APPEND OM_SRCS + $ + $ + $ + $ + $ + $ + $ + $ + $ + $ +) +list(APPEND BASE_LIB_SRCS + $ + $ +) + + + +#编译结果 +string(TOUPPER ${PLAM_TYPE} PLAM_TYPE_UP) +string(TOUPPER ${CPU_TYPE} CPU_TYPE_UP) +#编译通用的.a库 +add_library(CortexMXarch STATIC "${ARCH_SRCS}") +add_library(CortexMXkernel STATIC "${KERNEL_SRCS}" "${BASE_LIB_SRCS}") +add_library(CortexMXmem STATIC "${MEM_SRCS}") +add_library(CortexMXom STATIC "${OM_SRCS}") +add_library(CortexMXipc STATIC "${IPC_SRCS}") + +set_target_properties(CortexMXarch PROPERTIES SUFFIX ".lib") +set_target_properties(CortexMXkernel PROPERTIES SUFFIX ".lib") +set_target_properties(CortexMXmem PROPERTIES SUFFIX ".lib") +set_target_properties(CortexMXom PROPERTIES SUFFIX ".lib") +set_target_properties(CortexMXipc PROPERTIES SUFFIX ".lib") + +add_custom_target(cleanobj) +add_custom_command(TARGET cleanobj POST_BUILD + COMMAND echo "Finish Building!" + ) + +if (${COMPILE_MODE} STREQUAL "debug") + message("=============== COMPILE_MODE is ${COMPILE_MODE} ===============") +else() + add_custom_command( + TARGET CortexMXarch + POST_BUILD + COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXarch.lib" + ) + + add_custom_command( + TARGET CortexMXkernel + POST_BUILD + COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXkernel.lib" + ) + + add_custom_command( + TARGET CortexMXmem + POST_BUILD + COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXmem.lib" + ) + + add_custom_command( + TARGET CortexMXom + POST_BUILD + COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXom.lib" + ) + + add_custom_command( + TARGET CortexMXipc + POST_BUILD + COMMAND sh ${PROJECT_SOURCE_DIR}/cmake/common/build_auxiliary_script/make_lib_rename_file_type.sh ${OBJCOPY_PATH} ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} "CortexMXipc.lib" + ) +endif() +####以下为m4 make install打包脚本##### +set(m4_cortex_export modules) + +# 下面的变量分别定义了安装根目录、头文件安装目录、动态库安装目录、静态库安装目录、OBJECT文件安装目录、可执行程序安装目录、配置文件安装目录。 +# 注意:所有安装路径必须是相对CMAKE_INSTALL_PREFIX的相对路径,不可以使用绝对路径!!! +# 否则安装目录下的配置文件(foo-config.cmake, foo-tragets.cmake等)拷贝到其它目录时无法工作。 +set(INSTALL_M4_CORTEX_BASE_DIR .) +set(INSTALL_M4_CORTEX_INCLUDE_DIR UniProton/include) +set(INSTALL_M4_CORTEX_INCLUDE_SEC_DIR libboundscheck/include) +set(INSTALL_M4_CORTEX_ARCHIVE_DIR UniProton/lib/cortex_m4) +set(INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR libboundscheck/lib/cortex_m4) +set(INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR UniProton/config) +set(INSTALL_M4_CORTEX_CONFIG_DIR cmake/cortex_m4) + + + + +include(CMakePackageConfigHelpers) +configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/tool_chain/m4-cortex-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/UniProton-m4-cortex-config.cmake + INSTALL_DESTINATION ${INSTALL_M4_CORTEX_CONFIG_DIR} + PATH_VARS + INSTALL_M4_CORTEX_BASE_DIR + INSTALL_M4_CORTEX_INCLUDE_DIR + INSTALL_M4_CORTEX_INCLUDE_SEC_DIR + INSTALL_M4_CORTEX_ARCHIVE_DIR + INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR + INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR + INSTALL_M4_CORTEX_CONFIG_DIR + INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} +) +install(EXPORT ${m4_cortex_export} + NAMESPACE UniProton:: + FILE UniProton-m4-cortex-targets.cmake + DESTINATION ${INSTALL_M4_CORTEX_CONFIG_DIR} +) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/UniProton-m4-cortex-config.cmake + DESTINATION ${INSTALL_M4_CORTEX_CONFIG_DIR} +) + +install(TARGETS + CortexMXarch + CortexMXkernel + CortexMXmem + CortexMXom + CortexMXipc + EXPORT ${m4_cortex_export} + ARCHIVE DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_DIR}/ +) +if (${COMPILE_OPTION} STREQUAL "coverity" OR ${COMPILE_OPTION} STREQUAL "fortify" OR ${COMPILE_OPTION} STREQUAL "UniProton") + message("Don't Install Sec Lib In ${COMPILE_OPTION}") +else() + install(TARGETS + CortexMXsec_c + EXPORT ${m4_cortex_export} + ARCHIVE DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_SEC_DIR} + ) + + if (NOT "${RPROTON_INSTALL_FILE_OPTION}" STREQUAL "SUPER_BUILD") + ##{GLOB 所有文件 | GLOB_RECURSE 递归查找文件&文件夹} + file(GLOB glob_sec_files ${PROJECT_SOURCE_DIR}/platform/libboundscheck/include/*.h) + install(FILES + ${glob_sec_files} + DESTINATION ${INSTALL_M4_CORTEX_INCLUDE_SEC_DIR} + ) + endif() +endif() +install(FILES + ${PROJECT_SOURCE_DIR}/build/uniproton_config/config_m4/prt_buildef.h + DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR}/cortex_m4/config_m4 +) +if (NOT "${RPROTON_INSTALL_FILE_OPTION}" STREQUAL "SUPER_BUILD") + ##{GLOB 所有文件 | GLOB_RECURSE 递归查找文件&文件夹} + + install(FILES + ${PROJECT_SOURCE_DIR}/src/config/prt_config.c + ${PROJECT_SOURCE_DIR}/src/config/prt_config_internal.h + ${PROJECT_SOURCE_DIR}/src/config/config/prt_config.h + DESTINATION ${INSTALL_M4_CORTEX_ARCHIVE_CONFIG_DIR} + ) + + ##{GLOB 所有文件 | GLOB_RECURSE 递归查找文件&文件夹} + file(GLOB hw_drv_include_files ${PROJECT_SOURCE_DIR}/src/include/uapi/hw/armv7-m/*) + install(FILES + ${hw_drv_include_files} + DESTINATION ${INSTALL_M4_CORTEX_INCLUDE_DIR}/hw/armv7-m + ) + + + install(FILES + + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_clk.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_cpup.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_err.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_errno.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_event.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_exc.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_hook.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_hwi.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_idle.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_mem.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_module.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_queue.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_sem.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_sys.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_task.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_tick.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_timer.h + ${PROJECT_SOURCE_DIR}/src/include/uapi/prt_typedef.h + DESTINATION ${INSTALL_M4_CORTEX_INCLUDE_DIR}/ + ) +endif() diff --git a/cmake/tool_chain/rtosk_tool_chain_gcc.cmake b/cmake/tool_chain/rtosk_tool_chain_gcc.cmake new file mode 100644 index 0000000..636d61c --- /dev/null +++ b/cmake/tool_chain/rtosk_tool_chain_gcc.cmake @@ -0,0 +1,39 @@ +################交叉编译##################### +#cross-compilation config +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + + +set(CPU_TYPE "$ENV{CPU_TYPE}" ) +set(PLAM_TYPE "$ENV{PLAM_TYPE}" ) +set(LIB_TYPE "$ENV{LIB_TYPE}" ) +set(SYSTEM "$ENV{SYSTEM}" ) +set(CORE "$ENV{CORE}" ) +set(LIB_RUN_TYPE "$ENV{LIB_RUN_TYPE}" ) +set(BUILD_DIR "$ENV{BUILD_TMP_DIR}" ) #version id +set(OBJCOPY_PATH "$ENV{OBJCOPY_PATH}" ) #OBJCOPY_PATH +set(COMPILE_MODE "$ENV{COMPILE_MODE}" ) +set(CC_TYPE "$ENV{CC_TYPE}" ) +set(TOOLCHAIN_DIR "$ENV{HCC_PATH}") #该路径应该是外部传入,指向编译工具路径 + +##compiler specified in /etc/profile +set(CMAKE_C_COMPILER "${TOOLCHAIN_DIR}/arm-none-eabi-gcc" CACHE PATH "arm-gcc C compiler" FORCE) +set(CMAKE_ASM_COMPILER "${TOOLCHAIN_DIR}/arm-none-eabi-gcc" CACHE PATH "arm-gcc ASM compiler" FORCE) + +if(${CPU_TYPE} STREQUAL "m4") + set(CMAKE_ASM_FLAGS "--specs=nosys.specs") + set(CMAKE_ASM_COMPILE_OBJECT " -O2 -pipe ${STRONG_COMPILE_WARING_FLAG} ${COMPILE_WARING_FLAG} -std=gnu11 -fno-common -fomit-frame-pointer -mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -Wa,-mimplicit-it=thumb -fstack-protector-strong -funsigned-char -c -o ") + set(CMAKE_C_FLAGS "--specs=nosys.specs") #原ID形式\"888888\" + set(CMAKE_C_COMPILE_OBJECT " -O2 -pipe ${STRONG_COMPILE_WARING_FLAG} ${COMPILE_WARING_FLAG} -std=gnu11 -fno-common -fomit-frame-pointer -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -fstack-protector-strong -fdata-sections -ffunction-sections -fshort-enums -funsigned-char -DSECUREC_BUFFER_SIZE=32 -c -o ") +endif() + + +set(CMAKE_LINKER "${TOOLCHAIN_DIR}/arm-none-eabi-ld" CACHE STRING "" FORCE) +set(CMAKE_AR "${TOOLCHAIN_DIR}/arm-none-eabi-ar" CACHE STRING "" FORCE) +set(CMAKE_C_LINK_FLAGS "-r ") +set(CMAKE_C_ARCHIVE_CREATE " -r ") diff --git a/cmake/tool_chain/uniproton_tool_chain.cmake b/cmake/tool_chain/uniproton_tool_chain.cmake new file mode 100644 index 0000000..58b287a --- /dev/null +++ b/cmake/tool_chain/uniproton_tool_chain.cmake @@ -0,0 +1,34 @@ +################交叉编译##################### +set(CPU_TYPE "$ENV{CPU_TYPE}" ) +set(PLAM_TYPE "$ENV{PLAM_TYPE}" ) +set(LIB_TYPE "$ENV{LIB_TYPE}" ) +set(SYSTEM "$ENV{SYSTEM}" ) +set(CORE "$ENV{CORE}" ) +set(LIB_RUN_TYPE "$ENV{LIB_RUN_TYPE}" ) +set(BUILD_DIR "$ENV{BUILD_TMP_DIR}" ) #version id +set(OBJCOPY_PATH "$ENV{OBJCOPY_PATH}" ) #OBJCOPY_PATH +set(COMPILE_MODE "$ENV{COMPILE_MODE}" ) +set(HOME_PATH "$ENV{HOME_PATH}" ) +set(COMPILE_OPTION "$ENV{COMPILE_OPTION}" ) +set(RPROTON_INSTALL_FILE_OPTION "$ENV{RPROTON_INSTALL_FILE_OPTION}" )##RPROTON_INSTALL_FILE_OPTION="SUPER_BUILD"; + + +#### 统一告警选项,请审慎增删 +set(STRONG_COMPILE_WARING_FLAG "-Wunused -Wredundant-decls -Wfloat-conversion -Wwrite-strings -Wunused-macros -Wswitch-default -Wshift-overflow=2 -Wnested-externs -Wmissing-include-dirs -Wlogical-op -Wjump-misses-init -Wformat-security -Wvla -Wframe-larger-than=4096 -Wduplicated-cond -Wdisabled-optimization -Wduplicated-branches -Wignored-qualifiers -Wimplicit-fallthrough=3 -Wpointer-arith -Wshift-negative-value -Wsign-compare -Wtype-limits -Wcast-qual -Wundef -Wbad-function-cast -Wold-style-definition -Wpacked -Wstrict-prototypes -Wstack-usage=2048") +set(COMPILE_WARING_FLAG " -Wall -Werror -Wextra -Wformat=2 -Wfloat-equal -Wshadow -Wtrampolines -Wdate-time ")## -Wall -Werror -Wextra -Wformat=2 -Wfloat-equal + +if (${CPU_TYPE} STREQUAL "m4" ) + include(${HOME_PATH}/cmake/tool_chain/rtosk_tool_chain_gcc.cmake) +endif() + + +if (${COMPILE_OPTION} STREQUAL "coverity" OR ${COMPILE_OPTION} STREQUAL "fortify" ) + set(CMAKE_C_COMPILER_WORKS TRUE) + set(CMAKE_CXX_COMPILER_WORKS TRUE) + set(CMAKE_ASM_COMPILER_WORKS TRUE) +endif() + +set(CMAKE_C_ARCHIVE_CREATE " -r -D ") + + + diff --git a/config.xml b/config.xml new file mode 100644 index 0000000..d0197b8 --- /dev/null +++ b/config.xml @@ -0,0 +1,21 @@ + + + 1.0.0 + release + + + /opt/buildtools/cmake-3.20.5/bin + + + + + SRE + + cortex + /opt/buildtools/gcc-arm-none-eabi-10-2020-q4-major/bin + /opt/buildtools/gcc-arm-none-eabi-10-2020-q4-major/bin + m4 + + + + diff --git a/doc/UniProton_build.md b/doc/UniProton_build.md new file mode 100644 index 0000000..5525a08 --- /dev/null +++ b/doc/UniProton_build.md @@ -0,0 +1,124 @@ +# 一、Linux下的编译 +## 1.1 搭建Linux编译环境 +##### 【注】当前所有编译器的安装目录都在/opt/buidltools下,首先需要创建该目录并设置权限:mkdir -p /opt/buildtools && chmod -R 755 /opt/buildtools +## 软件要求 +1. SUSE Linux Enterprise Server +2. python 3.4+ +3. Cmake +4. GNU Arm Embedded Toolchain编译器,用于代码编译。 +## 1.2 安装编译器&构建器 +- #### 安装GNU Arm Embedded Toolchain编译器。 +1. 下载编译器. +- 当前开源版本只涉及32位,官方下载地址为:[GNU Arm Embedded Toolchain编译器](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads),指定版本:10-2020-q4-major。 +2. 解压编译器. +- 可以参考如下命令完成解压: +
+ tar -xvf gcc-arm-none-eabi-10-2020-q4-major-x86_64-linux.tar.bz2 -C /opt/buildtools + +## 1.3 安装Cmake +1. 通过官网进行下载[Cmake](https://cmake.org/download/),下载指定版本3.20.5 +2. 以tar包模式举例说明: +- 通过命令进行解压: +- tar -xvf cmake-3.20.5-Linux-x86_64.tar.gz -C /opt/buildtools + +## 1.4 安装Python +##### 下面以python3.8为例介绍安装方法。 +1. 通过[官网下载python源码包](https://gitee.com/link?target=https%3A%2F%2Fwww.python.org%2Fftp%2Fpython%2F3.8.5%2FPython-3.8.5.tgz)。 + +2. 解压源码包。 + - 参考如下命令完成解压,将压缩包名替换为实际下载的源码包名: +``` + tar -xf Python-3.8.5.tgz +``` +3. 检查依赖。 + - 解压后进入到目录中,执行./configure命令以检查编译与安装python所需的依赖: +``` + cd Python-3.8.5 + ./configure +``` +- 如果没有报错就继续下一步操作,如果存在报错就根据提示安装依赖。 +4. 编译&安装python。 +``` + sudo make + sudo make install +``` +5. 检查python版本并正确链接python命令。 +``` + python --version +``` +- 如果显示的不是刚刚安装的python版本,则需要执行以下命令来正确链接python命令。 + +- a. 获取python目录,例如对于python 3.8.5,执行如下命令。 + +``` + which python3.8 +``` +- b. 链接python命令到刚刚安装的python包。 + + 将以下命令中的 "python3.8-path" 替换为 "which python3.8" 命令执行后的回显路径: + +``` + cd /usr/bin && sudo rm python && sudo ln -s "python3.8-path" python +``` +- c. 再次检查python版本。 + +``` + python --version +``` +## 1.5 安装pip包管理工具。 + +##### 如果pip命令不存在,可以下载pip源码包进行安装。pip依赖setuptools,如果setuptools不存在,也需要安装。 + +1. 源码包方式安装: + +- 安装setuptools。 + +- 点击[setuptools源代码包下载地址](https://gitee.com/link?target=https%3A%2F%2Fpypi.org%2Fproject%2Fsetuptools%2F),可以参考下面的命令进行安装: + +``` + sudo unzip setuptools-50.3.2.zip + cd setuptools + sudo python setup.py install +``` + +2. 安装pip。 + +- 点击[pip源代码包下载地址](https://gitee.com/link?target=https%3A%2F%2Fpypi.org%2Fproject%2Fpip%2F),可以参考下面的命令进行安装: +``` + sudo tar -xf pip-20.2.4.tar.gz + cd pip-20.2.4 + sudo python setup.py install +``` + +## 1.6 Linux下编译流程 +##### 参照上述步骤完成环境搭建后,即可按以下步骤完成编译。 +1. 下载UniProton代码 +- git clone https://gitee.com/openeuler/UniProton.git +2. 下载libboundscheck, 按照[指导](../platform/README.md)操作 +3. 执行编译 +- 进入到UniProton根目录下执行命令即可 +``` + python build.py m4 +``` + + +# 二、提供镜像,用户自行下载 +1. 在虚拟机操作命令: + + `docker pull swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/uniproton:v001` + - 执行完成之后,创建容器并进入(默认挂载当前执行命令的目录为容器内的/home/uniproton目录) + + `docker run -it -v $(pwd):/home/uniproton swr.cn-north-4.myhuaweicloud.com/openeuler-embedded/uniproton:v001` +2. 下载代码 + - 下载UniProton代码 + `git clone https://gitee.com/openeuler/UniProton.git` + - 下载libboundscheck, 按照[指导](../platform/README.md)操作 + +3. 执行编译 + - 进入到UniProton根目录下执行命令即可 +``` + python build.py m4 +``` + +# 三、 编译结果 + 生成的静态库文件存放在output/UniProton/lib/cortex_m4目录下。 diff --git a/doc/contribute_guide.md b/doc/contribute_guide.md new file mode 100644 index 0000000..5f222ee --- /dev/null +++ b/doc/contribute_guide.md @@ -0,0 +1,770 @@ +# UniProton 代码&文档贡献指南 +- [编程规范](#编程规范) + - [总体原则](#总体原则) + - [目录结构](#目录结构) + - [命名](#命名) + - [排版与格式](#排版与格式) + - [注释](#注释) + - [宏](#宏) + - [头文件](#头文件) + - [数据类型](#数据类型) + - [变量](#变量) + - [函数](#函数) + - [可移植性](#可移植性) + - [业界编程规范](#业界编程规范) +- [文档写作规范](#文档写作规范) +- [Commit message规范](#Commitmessage规范) +- [贡献流程](#贡献流程) +- [协议](#协议) +- [加入我们](#加入我们) + +

编程规范

+此编程规范在业界通用的编程规范基础上进行了整理,供开发者参考使用。 + +### 总体原则 +- 清晰,易于维护、易于重构。 +- 简洁,易于理解,并且易于实现。 +- 风格统一,代码整体风格保持统一。 +- 通用性,遵循业界通用的编程规范。 + +### 目录结构 +建议将工程按照功能模块划分子目录(可参考UniProton的功能模块划分),子目录再定义头文件和源文件目录。 + +### 命名 +- 使用驼峰风格进行命名,此风格大小写字母混用,不同单词间通过单词首字母大写来分开,具体规则如下: + | 类型 | 命名风格 | 形式 | + | --------------------------- | -------------------------------- | ------------------------- | + | 函数,自定义的类型 | 大驼峰,或带有模块前缀的大驼峰 | AaaBbb, XXX_AaaBbb | + | 局部变量,函数参数,宏参数,结构体成员,联合体成员 | 小驼峰 | aaaBbb | + | 全局变量 | 带'g_'前缀的小驼峰 | g_aaaBbb | + | 宏,枚举值 | 全大写并下划线分割 | AAA_BBB | + | 内核头文件中防止重复包含的宏变量 | 带'PRT'前缀和'H'后缀,中间为大写模块名,以下划线分割 | PRT_MODULE_H | +- 全局函数、全局变量、宏、类型名、枚举名的命名,应当准确描述并全局唯一。 +- 在能够准确表达含义的前提下,局部变量,或结构体、联合体的成员变量,其命名应尽可能简短。 +- UniProton的对外API使用PRT_\\的方式,如果有动词和宾语,则采用PRT_\\\,比如: + ``` + PRT_TaskCreate + PRT_SemPend + PRT_TickGetCount + PRT_TaskGetStatus + ``` + kernel目录下内部模块间接口使用Os\\的方式,比如: + ``` + OsTaskScan + OsSwTmrCtrlInit + ``` + +### 排版与格式 +- 程序块采用缩进风格编写,使用空格而不是制表符('\t')进行缩进,每级缩进为4个空格。 +- 采用K&R风格作为大括号换行风格,即函数左大括号另起一行放行首,并独占一行,其他左大括号跟随语句放行末, + 右大括号独占一行,除非后面跟着同一语句的剩余部分,如if语句的else/else if或者分号,比如: + ```c + struct MyType { // 左大括号跟随语句放行末,前置1个空格 + ... + }; // 右大括号后面紧跟分号 + ``` + ```c + int Foo(int a) + { // 函数左大括号独占一行,放行首 + if (a > 0) { // 左大括号跟随语句放行末,前置1个空格 + ... + } else { // 右大括号、"else"、以及后续的左大括号均在同一行 + ... + } // 右大括号独占一行 + ... + } + ``` +- 条件、循环语句使用大括号,比如: + ```c + if (objectIsNotExist) { // 单行条件语句也加大括号 + return CreateNewObject(); + } + ``` + ```c + while (condition) {} // 即使循环体是空,也应使用大括号 + ``` + ```c + while (condition) { + continue; // continue表示空逻辑,使用大括号 + } + ``` +- case/default语句相对switch缩进一层,缩进风格如下: + ```c + switch (var) { + case 0: // 缩进一层 + DoSomething1(); // 缩进一层 + break; + case 1: + DoSomething2(); + break; + default: + break; + } + ``` +- 一行只写一条语句。 +- 一条语句不能过长,建议不超过120个字符,如不能缩短语句则需要分行写。 +- 换行时将操作符留在行末,新行进行同类对齐或缩进一层,比如: + ```c + // 假设下面第一行不满足行宽要求 + if (currentValue > MIN && // 换行后,布尔操作符放在行末 + currentValue < MAX) { // 与(&&)操作符的两个操作数同类对齐 + DoSomething(); + ... + } + ``` + ```c + // 假设下面的函数调用不满足行宽要求,需要换行 + ReturnType result = FunctionName(paramName1, + paramName2, + paramName3); // 保持与上方参数对齐 + ``` + ```c + ReturnType result = VeryVeryVeryLongFunctionName( // 写入第1个参数后导致过长,直接换行 + paramName1, paramName2, paramName3); // 换行后,4空格缩进一层 + ``` + ```c + // 每行的参数代表一组相关性较强的数据结构,放在一行便于理解,此时可理解性优先于格式排版要求 + int result = DealWithStructLikeParams(left.x, left.y, // 表示一组相关参数 + right.x, right.y); // 表示另外一组相关参数 + ``` +- 声明定义函数时,函数的返回类型以及其他修饰符,与函数名同行。 +- 指针类型"*"应该靠右跟随变量或者函数名,比如: + ```c + int *p1; // Good:右跟随变量,和左边的类型隔了1个空格 + int* p2; // Bad:左跟随类型 + int*p3; // Bad:两边都没空格 + int * p4; // Bad:两边都有空格 + ``` + 当"*"与变量或函数名之间有其他修饰符,无法跟随时,此时也不要跟随修饰符,比如: + ```c + char * const VERSION = "V100"; // Good:当有const修饰符时,"*"两边都有空格 + int Foo(const char * restrict p); // Good:当有restrict修饰符时,"*"两边都有空格 + ``` +- 根据上下内容的相关程度,合理安排空行,但不要使用连续3个或更多空行。 +- 编译预处理的"#"统一放在行首,无需缩进。嵌套编译预处理语句时,"#"可以进行缩进,比如: + ```c + #if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) // 位于行首,不缩进 + #define ATOMIC_X86_HAS_CMPXCHG16B 1 // 缩进一层,区分层次,便于阅读 + #else + #define ATOMIC_X86_HAS_CMPXCHG16B 0 + #endif + ``` + +### 注释 +- 注释的内容要清楚、明了,含义准确,防止注释二义性。 +- 在代码的功能、意图层次上进行注释,即注释解释代码难以直接表达的意图,而不是仅仅重复描述代码。 +- 函数声明处注释描述函数功能、性能及用法,包括输入和输出参数、函数返回值、可重入的要求等;定义处详细描述函数功能和实现要点,如实现的简要步骤、实现的理由、设计约束等。 +- 全局变量要有较详细的注释,包括对其功能、取值范围以及存取时注意事项等的说明。 +- 避免在注释中使用缩写,除非是业界通用或子系统内标准化的缩写。 +- 文件头部要进行注释,建议注释列出:版权说明、版本号、生成日期、作者姓名、功能说明、与其它文件的关系、修改日志等。 +- 注释风格要统一,建议优先选择/* */的方式,注释符与注释内容之间要有1空格,单行、多行注释风格如下: + ```c + /* 单行注释 */ + ``` + ```c + /* + * 多行注释 + * 第二行 + */ + ``` +- 注释应放在其代码上方或右方。 + + 上方的注释,与代码行之间无空行,保持与代码一样的缩进。 + 右边的注释,与代码之间至少相隔1个空格。如果有多条右置注释,上下对齐会更加美观,比如: + ```c + #define A_CONST 100         // 此处两行注释属于同类 + #define ANOTHER_CONST 200   // 可保持左侧对齐 + ``` + +### 宏 +- 代码片段使用宏隔离时,统一通过#ifdef的方式,例如: + ```c + #ifdef PRTCFG_XXX + ... + #endif + ``` +- 定义宏时,要使用完备的括号,比如: + ```c + #define SUM(a, b) a + b     // 不符合本条要求 + #define SUM(a, b) ((a) + (b)) // 符合本条要求 + ``` + 但是也要避免滥用括号,比如单独的数字或标识符加括号毫无意义: + ```c + #define SOME_CONST 100         // 单独的数字无需括号 + #define ANOTHER_CONST   (-1)    // 负数需要使用括号 + #define THE_CONST   SOME_CONST  // 单独的标识符无需括号 + ``` +- 包含多条语句的函数式宏的实现语句必须放在do-while(0)中,例如: + ```c + #define FOO(x) do { \ + (void)printf("arg is %d\n", (x)); \ + DoSomething((x)); \ + } while (0) + ``` +- 禁止宏调用参数中出现预编译指令。 +- 宏定义不以分号结尾。 + +### 头文件 +- 设计原则 + - 头文件应当职责单一。 + - 一个模块通常包含多个.c文件,建议放在同一个目录下,目录名即为模块名;如果一个模块包含多个子模块,则建议每一个子模块提供一个对外的.h,文件名为子模块名。 + - 建议每一个.c文件应有一个同名.h文件,用于声明需要对外公开的接口。 + - 头文件中适合放置接口的声明,不适合放置实现。 + - 不要在头文件中定义变量。 + - 禁止头文件循环依赖,循环依赖指a.h包含b.h,b.h包含c.h,c.h包含a.h。 + - 头文件应当自包含,即任意一个头文件均可独立编译,但同时也要避免包含用不到的头文件。 + - 头文件必须用#define保护,防止重复包含,比如内核中统一使用以下宏定义保护: + ```c + #ifndef PRT__H // 比如 PRT_TASK_H + #define PRT__H + ... + #endif + ``` + - 禁止通过声明的方式引用外部函数接口、变量,只能通过包含头文件的方式使用其他模块或文件提供的接口。 + - 禁止在 extern "C" 中包含头文件。 + - 按照合理的顺序包含头文件: + 1) 源文件对应的头文件 + 2) C标准库 + 3) 需要包含的OS其他头文件 +- 版权声明 + - 头文件版权声明一致,放在头文件置顶位置。 + - 如果提交的代码是在开源软件基础上修改所编写或衍生的代码,请遵循开源许可协议要求,并且已履行被修改软件的许可证义务。 + +### 数据类型 +基础类型定义统一使用prt_typedef.h中定义的类型,比如定义无符号32位整型变量使用U32。 + +### 变量 +- 一个变量只有一个功能,不要把一个变量用作多种用途。 +- 防止局部变量与全局变量同名。 +- 不用或者少用全局变量。 +- 定义函数的局部变量时,控制变量的占用空间,避免因占用过多栈空间导致程序运行失败。比如需要一个大数组,可以通过动态分配内存的方式来避免栈空间占用过大。 +- 在首次使用前初始化变量。 +- 指向资源句柄或描述符的变量,在资源释放后立即赋予新值,包括指针、文件描述符以及其它指向资源的变量。 +- 禁止将局部变量的地址返回到其作用域以外,下面是一个**错误示例:** + ```c + int *Func(void) + { + int localVar = 0; + ... + return &localVar; // 错误 + } + + void Caller(void) + { + int *p = Func(); + ... + int x = *p; // 程序产生未定义行为 + } + ``` + **正确代码示例:** + ```c + int Func(void) + { + int localVar = 0; + ... + return localVar; + } + + void Caller(void) + { + int x = Func(); + ... + } + ``` +- 如果要使用其他模块的变量,应尽量避免直接对变量进行访问,而是通过统一的函数封装或者宏封装的方式,比如mutex模块中: + ```c + // 私有头文件中引入全局变量,但要避免直接使用 + extern struct TagQueCb *g_allQueue; + // 通过GET_QUEUE_HANDLE的方式对g_allQueue进行访问 + #define GET_QUEUE_HANDLE(queueId) (((struct TagQueCb *)g_allQueue) + (queueId)) + ``` + +### 函数 +- 重复代码应该尽可能提炼成函数。 +- 避免函数过长,新增函数不超过 40-50 行。 +- 内联函数要尽可能短,避免超过 10 行(非空非注释)。 +- 避免函数的代码块嵌套过深。 +- 函数应避免使用全局变量、静态局部变量和I/O操作,不可避免的地方应集中使用。 + +### 可移植性 +不使用与硬件或操作系统关系很大的语句,而使用建议的标准语句,以提高软件的可移植性和可重用性。 + +### 业界编程规范 +C语言编程规范参考资料较多,大家可以自行了解,本文不再过多赘述。 + + +

文档写作规范

+ +UniProton欢迎开发者参与到开源社区的贡献中来,本文主要介绍参与UniProton文档贡献的写作规范,如果贡献者提交文档的修改或提交新的文档,请参照此规范。 + +### 命名规范 + +如需提交新的文档,在UniProton代码仓doc目录下创建新的.md文件,命名需遵循 xxx\_xxx.md 格式,根据文档的内容来声明。 + +比如介绍写作规范的文档,可以命名为 UniProton\_doc\_write\_standard.md。 + +### 内容规范 + +以简洁、直观地表达所述内容为目的,介绍性文档言简意赅介绍原理、架构、设计思路等,操作类文档写明关键步骤,以便能对其他开发者起到帮助。可以优先使用中文,建议中英文都支持,UniProton也将持续更新,保证中英文的同步。 + +1. **标题** + + 建议标题层级不超过三级。 + +2. **正文** + - 操作类文档以移植为例,文档结构可以参考如下: + 1. 目的(简述操作目的,如移植到哪款型号的单板) + 2. 软硬件环境准备 + 3. 移植具体步骤 + 4. 结果验证 + + - 介绍性文档以开发指南某一功能为例,文档结构可以参考如下: + 1. 概述(概念及原理介绍) + 2. 功能(支持的接口列表) + 3. 开发流程(如何使用及相应步骤) + 4. 编程实例(提供具体代码示例) + 5. 注意事项 + 6. 其他 + +3. **图片** + + 图片统一存放到文档同级目录下的images文件夹中(英文文档对应images-en),如 UniProton/doc/getting\_started.md 中使用的图片,统一放置到 UniProton/doc/images 目录下,文档中使用相对路径引用图片。图片建议根据内容命名,只用数字序列不利于后续图片的继承。 + + **说明:** 图 + 如果是自制图片,配色请参考如下,格式不限,png/jpg/gif...均可,如果是截图或者其他地方引用图片,风格不做限制。 + + **说明:** 图 +4. **表格** + + 在md文件中可以按照如下形式插入表格。 + + ``` + | Tables | Type | Note | + | ----------- |:-------------:| -----:| + | first | standard | None | + | second | outstanding | 5 | + | third | inside | with | + ``` + +5. **代码** + + 正文中插入代码段,可以在段落前后加上符号 \`\`\`。 +
+ ```c + + int size = 10; + + \``` +
+ + +

Commit message规范

+ +### 概要说明 + +目前,社区有多种 Commit message 的写法规范。UniProton采用的是Angular规范,这是目前使用最广的写法,比较合理和系统化,并且有配套的工具。 + +### Commit message的作用 + +格式化的Commit message有几个好处: + +- 提供更多的历史信息,方便快速浏览 +- 可以过滤某些commit(比如文档改动),便于快速查找信息 +- 可以直接从commit生成Change log + +### UniProton Commit message的格式 + +每次提交,Commit message 都包括三个部分:Header,Body 和 Footer。 +``` +
+空一行 + +空一行 +