开发辅助工具

shell

调试

1)使用trap命令shell脚本执行时会产生三个所谓的伪信号,可以使用trap命令捕获这三个“伪信号”,并输出相关的调试信息
信号名产生原因
EXIT从一个函数中退出或整个脚本执行完毕
ERROR从一条命令返回非零状态时(代表命令执行不成功)
DEBUG脚本中每一条命令执行之前
trap示例:

#! /bin/bash
ERRTRAP()
{
	echo "[LINE:$1] Error: exited with status $?"
}

test()
{
	return 1;
}

trap 'ERRTRAP $LINENO' ERR
hhh
test
2)使用tee命令
 	在shell脚本中管道以及输入输出重定向使用得非常多,在管道的作用下,一些命令的执行结果直接成为了下一条命令的输入。
 	如果执行中出现了问题,此时我们就可以借助于tee命令了。
	tee命令会从标准输入读取数据,将其内容输出到标准输出设备,同时又可将内容保存成文件
tee使用示例:

#! /bin/bash
ipaddr=`sbin/ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' | tee temp.txt | cut -d : -f3 | awk '{print $1]'`
echo $ipaddr
3)使用“调试钩子”
     在C语言程序中,我们经常使用DEBUG宏来控制是否要输出调试信息,
     在shell脚本中我们同样可以使用这样的机制,如下列代码所示:
     if [ “$DEBUG” = “true” ]; then
           echo “debugging”  #此处可以输出调试信息
     fi
   这样的代码块通常称之为“调试钩子”或“调试块”。
   在调试钩子内部可以输出任何您想输出的调试信息,使用调试钩子的好处是它是可以通过DEBUG变量来控制的,
   在脚本的开发调试阶段,可以先执行export DEBUG=true命令打开调试钩子,使其输出调试信息,
   而在把脚本交付使用时可以先执行export DEBUG=false,也无需再费事把脚本中的调试语句一一删除。
hook使用示例:

#! /bin/bash
TRACE()
{
	if [ "$DEBUG" = "true" ]; then
		$@
	fi
}
a=1
TRACE echo "a=$a"
if [ "$a" -eq 1 ]
then
	b=2
else
	b=1
fi
c=3
TRACE echo "c=$c"
4)shell的执行选项
	 -n	只读取shell脚本,但不实际执行
	 -x	进入跟踪方式,显示所执行的每一条命令
	 -c	"string" 从strings中读取命令
	 
     $LINENO:代表shell脚本的当前行号,类似于C语言中的内置宏__LINE__
     $FUNCNAME:函数的名字,类似于C语言中的内置宏__func__,但宏__func__只能代表当前所在的函数名,
     	而$FUNCNAME的功能更强大,它是一个数组变量,其中包含了整个调用链上所有的函数的名字,
     	故变量${FUNCNAME[0]}代表shell脚本当前正在执行的函数的名字,
     	而变量${FUNCNAME[1]}则代表调用函数${FUNCNAME[0]}的函数的名字,余者可以依此类推。
  	 $PS4:$PS4的值将被显示在“-x”选项输出的每一条命令的前面。
  	 	在Bash Shell中,缺省的$PS4的值是"+"号。
  	 	如先执行export PS4='+{$LINENO:${FUNCNAME[0]}} ', 然后再使用“-x”选项来执行脚本,
  	 	就能在每一条实际执行的命令前面显示其行号以及所属的函数名。

git

常用命令

  • 拉取常用

     git pull 	
     git rebase --abort
    
  • 本地常用

     git add (-u) *
     git checkout --
     git commit (--amend -s)
     git reset --soft HEAD^
     git reset --hard (commit_id)
     git stash
     git stash pop
     git diff
     git clean -df
     git log 
     git reflog
    
  • 提交常用

     git push xx HEAD:refs/for/xxx
    
  • 分支常用

     git checkout branch_name
     git branch
     git branch -D
     git branch -a
     git branch -vv
    

error解决

  • email address xxx is not registered in your account
    可能原因1.git账户配置不对

     	配置git账户
     	git config --global user.name
     	git config  user.name
     	git config --global user.email
     	或通过修改git配置文件
     		/etc/gitconfig:适用于所有用户和所有项目的值
     		~/.gitconfig:只适用于当前登录用户的配置
     		.git/config:该git项目的配置
     	
     	git config  user.email
     	git commit --amend --reset-author
    

    可能原因2.ssh登录账户不对

     	修改.git/config中的对应配置项
    

makefile

常用命令

	重定向:	
		make >filename 2>&1
	
	编译中的.d依赖:
		-M的选项:自动寻找源文件中包含的头文件,并生成一个依赖关系
		-MM:生成文件的依赖关系,和-M 类似,但不包含标准库的头文件
		-MG:要求把缺失的头文件按存在对待,并且假定他们和源程序文件在同一目录下,必须和-M选项一起用
		-MF File:当使用了-M或者-MM选项时,则把依赖关系写入名为File的文件中。
		-MD:等同于-M -MF File,但是默认关闭了-E选项。其输出的文件名是基于-o 选项,
			若给定-o选项,则输出的文件名是-o指定的文件名,并添加.d后缀,
			若没有给定,则输入的文件名作为输出的文件名,并添加.d后缀
.d依赖示例:

#include "stdio.h"
#include "defs.h"
 
int main(int argc, char *argv[])
{
	printf("Hello, %s!\n", NAME);
	return 0;
} 
==========================================
命令:	
	gcc -M main.c
输出: 
	 main.o: main.c defs.h \
	 /usr/include/stdio.h \
	 /usr/include/features.h \                                                      
	 /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \                     
	...
==========================================	
命令:	
	gcc -MM main.c
输出: 
	main.o: main.c   defs.h

函数

call函数:
	1)唯一一个可以创建定制化参数函数的引用函数。
	2)支持将一个变量定义为一个复杂的表达式,用call函数根据不同的参数对它进行展开来获取不同的结果
	语法:
		$(call VARIABLE,PARAM,PARAM,...)
	参数:
		在执行时,将它的参数"PARAM"依次赋给临时变量"$(1)","$(2)"
		call对参数的数目没有限制,也可以没有参数值
		最后再对VARIABLE展开后的表达式进行处理.
	返回值:
		VARIABLE展开后的表达式的值
call函数示例:

define FUNC1
$(info echo 4-$(1) $(2))
endef

$(call FUNC1,hello,wolrd)

all:
    @echo Done

变量

MAKEFILE_LIST:
	$(lastword $(MAKEFILE_LIST)):用于获取当前路径
	--Q: 为什么不用 $(shell pwd)
	--A: 可以返回当前路径,但当makefile中存在make -f newMakefile,使用$(shell pwd)返回的就不是当前路径

伪目标

默认情况下:
	1)make认为目标对应着一个文件
	2)make比较目标文件和依赖文件的新旧关系,决定是否执行命令
	3)make以文件处理作为第一优先级	
伪目标:
	1)通过.PHONY关键字声明一个伪目标
	2)伪目标不对应任何实际的文件
	3)不管伪目标的依赖是否更新,命令总是执行
	4)伪目标的语法:先声明,后使用
	5)伪目标的本质:是make中特殊目标.PHONY的依赖
	6)当一个目标的依赖包含伪目标时,伪目标定义的命令总会被执行
	7)规则调用(使用伪目标来模拟C语言中的函数调用)
伪目标示例1====================================
hello.out : func.o main.o
    gcc -o hello.out func.o main.o 

func.o : func.c
    gcc -o func.o -c func.c

main.o : main.c
    gcc -o main.o -c main.c

.PHONY : clean  rebuild  all

rebuild : clean all 

all : hello.out

clean : 
    rm *.o hello.out
====================================
执行:
make all
输出:
gcc -o func.o -c func.c
gcc -o main.o -c main.c
gcc -o hello.out func.o main.o 
-------------------------------------
执行:
make rebuild 
输出:
rm *.o hello.out
gcc -o func.o -c func.c
gcc -o main.o -c main.c
gcc -o hello.out func.o main.o 
绕开.PHONY关键字定义伪目标:
	如果一个规则没有命令或则依赖,并且它的目标不是一个存在的文件名,在执行此规则时,目标总会被认为是最新的
伪目标示例2:
hello.out : func.o main.o
    gcc -o hello.out func.o main.o 

func.o : func.c
    gcc -o func.o -c func.c

main.o : main.c
    gcc -o main.o -c main.c

clean : FORCE
    rm *.o hello.out
FORCE :

传值

	make VALUE=val		

递归

	make -c xxx/makefile
	-include xxx/makefile	

条件判断

	ifeq( $(a)_$(b), y_y )
	endif
	实现逻辑与: " a=y && b=y "

CMake

常用命令

cmake常用命令

常见变量

CMAKE_AR: 静态库的归档工具的名称
CMAKE_ARGC: 在脚本模式下传给CMake的命令行参数的个数。当运行在-P脚本模式下,CMake设置该变量为命令行参数的个数。
CMAKE_ARGV0: 在脚本模式下传给CMake的命令行的第一个参数。
CMAKE_BINARY_DIR: 构建树的最外层路径,是当前CMake构建树的最外层的全路径。
	对于在源码中构建的情况,它与CMAKE_SOURCE_DIR的值一样。
CMAKE_BUILD_TOOL: 执行构建过程的工具。该变量设置为CMake构建时输出所需的程序。
	对于VS 6,CMAKE_BUILD_TOOL设置为msdev,对于Unix,它被设置为make或 gmake。
	对于VS 7,它被设置为devenv.。对于Nmake构建文件,它的值为nmake。
CMAKE_CACHEFILE_DIR: 该变量设置为包含CMakeCache.txt文件的目录的全路径。通常与CMAKE_BINARY_DIR的值一样。
CMAKE_CACHE_MAJOR_VERSION: 用于创建CMakeCache.txt文件的CMake的主版本号。只有当CMake运行于在由一个不同版本的CMake创建的cache文件时,这个变量的值才会不同。
CMAKE_CACHE_MINOR_VERSION: 用于创建CMakeCache.txt文件的CMake的次版本号。只有当CMake运行于在由一个不同版本的CMake创建的cache文件时,这个变量的值才会不同。
CMAKE_COMMAND: 指向cmake可执行程序的全路径。
CMAKE_CURRENT_BINARY_DIR: 当前正在处理的构建目录。每个由add_subdirectory添加的目录将会在构建树中创建一个构建目录。对于直接在源码目录中编译的情况,当前正在处理的构建目录就是当前源码所在的目录。
CMAKE_CURRENT_LIST_DIR: 当前处理的CMakeLists.txt文件所在的目录。
CMAKE_CURRENT_LIST_FILE: 当前处理的CMakeLists.txt文件的全路径。
CMAKE_CURRENT_LIST_LINE: 当前处理的CMakeLists.txt文件的行号。
CMAKE_CURRENT_SOURCE_DIR: 当前处理的源码路径。
CMAKE_EXECUTABLE_SUFFIX: 该平台上可执行程序的后缀。
CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES: 共享库额外的后缀名。
	这些共享库不是CMAKE_SHARED_LIBRARY_SUFFIX。
	在分析某个目标链接的库时,CMake使用该变量识别外部共享库文件。
CMAKE_HOME_DIRECTORY: 源码树的顶级目录的路径。
CMAKE_IMPORT_LIBRARY_PREFIX: 链接的引入库的前缀。CMAKE_IMPORT_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_IMPORT_LIBRARY_SUFFIX: 链接的引入库的后缀。CMAKE_IMPORT_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_LINK_LIBRARY_SUFFIX: 链接的库的后缀。如Windows下是.lib。
CMAKE_MAJOR_VERSION: CMake的主版本号。
CMAKE_MINOR_VERSION: CMake的次版本号。
CMAKE_PARENT_LIST_FILE: 正在处理的CMakeLists.txt文件的父CMakelists.txt文件所在的路径。
CMAKE_PROJECT_NAME: 当前工程的名字。
CMAKE_ROOT: cmake的安装目录。
CMAKE_SCRIPT_MODE_FILE: 脚本模式下正在处理的脚本文件。
CMAKE_SHARED_LIBRARY_PREFIX: 链接的共享库的前缀。TCMAKE_SHARED_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_SHARED_LIBRARY_SUFFIX:链接的共享库的后缀。CMAKE_SHARED_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_SHARED_MODULE_PREFIX: 链接的可加载模块的前缀。CMAKE_SHARED_MODULE_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_SHARED_MODULE_SUFFIX: 链接的可加载模块的后缀。CMAKE_SHARED_MODULE_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_SIZEOF_VOID_P: void指针的大小。
CMAKE_SOURCE_DIR: 源码树的最顶级目录。当在源码中编译时,与CMAKE_BINARY_DIR的值一致。
CMAKE_STANDARD_LIBRARIES: 链接到每个可执行程序和共享库的标准库。它包含一系列库。
CMAKE_STATIC_LIBRARY_PREFIX:链接的静态库的前缀。CMAKE_STATIC_LIBRARY_PREFIX_<LANG> overrides this for language <LANG>.
CMAKE_STATIC_LIBRARY_SUFFIX: 链接的静态库的后缀。CMAKE_STATIC_LIBRARY_SUFFIX_<LANG> overrides this for language <LANG>.
CMAKE_VERSION: CMake的完全版本号。格式:major.minor.patch[.tweak[-id]]。
PROJECT_BINARY_DIR: 工程的构建目录。
PROJECT_NAME: 工程名。
PROJECT_SOURCE_DIR: 当前工程的顶级目录。
[Project name]_BINARY_DIR: 对应工程的顶级构建目录。
[Project name]_SOURCE_DIR: 对应工程的源码目录。
CMAKE_SYSTEM_NAME: 目标机target所在的操作系统名称,只有当CMAKE_SYSTEM_NAME这个变量被设置了,CMake才认为此时正在交叉编译,它会额外设置一个变量CMAKE_CROSSCOMPILING为TRUE.
CMAKE_CROSSCOMPILING: 当前CMake是否是交叉编译。
CMAKE_C_COMPILER: C语言编译器,这里可以将变量设置成完整路径或者文件名,
	设置成完整路径时CMake会去这个路径下去寻找编译相关的其他工具比如linker,binutils等,
	如果写的文件名带有arm-elf等等前缀,CMake会识别到并且去寻找相关的交叉编译器。
CMAKE_CXX_COMPILER: 同上,此时代表的是C++编译器。
CMAKE_FIND_ROOT_PATH: 代表了一系列的相关文件夹路径的根路径的变更,如设置了/opt/arm/,所有的Find_xxx.cmake都会优先根据这个路径下的/usr/lib,/lib等进行查找,然后才会去用户自己的/usr/lib和/lib进行查找,如果有一些库是不被包含在/opt/arm里面的,也可以显示指定多个值给CMAKE_FIND_ROOT_PATH,比如set(CMAKE_FIND_ROOT_PATH /opt/arm /opt/inst)
CMAKE_FIND_ROOT_PATH_MODE_PROGRAM: 对FIND_PROGRAM()起作用,有三种取值,
	NEVER,ONLY,BOTH,第一个表示不在CMAKE_FIND_ROOT_PATH下进行查找,
	第二个表示只在这个路径下查找,第三个表示先查找这个路径,再查找全局路径
CMAKE_FIND_ROOT_PATH_MODE_LIBRARY: 对FIND_LIBRARY()起作用,表示在链接的时候的库的相关选项,
	因此这里需要设置成ONLY来保证我们的库是在交叉环境中找的.
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE: 对FIND_PATH()和FIND_FILE()起作用,一般来说也是ONLY,
	如果想改变,一般也是在相关的FIND命令中增加option来改变局部设置
BOOST_ROOT: 
	对于需要boost库的用户来说,相关的boost库路径配置也需要设置
QT_QMAKE_EXECUTABLE: 相应的qmake路径(指定到qmake本身)

Modern CMake实践

CMake之install方法的使用
CMake最佳实践

Android.mk

Android编译系统使用

android的 makefile – Android.mk 分析

Android编译系统剖析

Android编译系统分析
理解 Android Build 系统 mm mmm mma croot

Kconfig

Kconfig的角色

	Kconfig 有助于使 Linux 内核高度模块化和可定制。Kconfig 为用户提供了许多配置目标:

KConfig配置目标

  menuconfig是这些目标中最受欢迎的。这些目标由不同的主程序处理,这些程序由内核提供并在内核构建期间构建。一些目标有 GUI(如menuconfig),而大多数没有。与 Kconfig 相关的工具和源代码主要位于内核源代码中的 scripts/kconfig/ 下。

------------------------------------分隔符------------------------------------
	当在内核源码目录下输入make menuconfig时,在出现的菜单界面中选择一项时,它会自动更新.config相应项的值。
	如果没有选择,则会在.config问下插入一行注释。类似于# CONFIG_xxx is not set
	当输入make时,根据makefile文件来编译,makefile文件中的变量值则由.config来进行赋值操作。
	仅仅只在Kconfig中添加选项,只会在菜单界面中显示,即使此时选择y或m,也不会编译文件。
	还需要在makefile文件中按照规定添加相应行才能进行编译:obj-$(CONFIG_xxx) += xxx.o。CONFIG_xxx在.config中被定义
	简单关系图解如下: Kconfig------->.config(.conf)---------->makefile
	Kconfig:定义了配置项
	.config:对配置项进行赋值
	makefile:建立配置项的生成法则
  • 生成.config
    生成.config

  • 解析.config
    解析.config

     syncconfig将 .config 作为输入并输出许多其他文件:
     .conf用于makefile文本处理。makefile中将使用的语句:obj-$(CONFIG_xxx) += xxx.o。
     autoconf.h 用于C语言的源文件。
    
  • kbuild

     组件式构建,递归make,是GNU make管理大型项目的常用方法。
     通过将源文件划分为不同的模块/组件,每个组件都由其自己的makefile管理。
     当开始构建时,顶级makefile以正确的顺序调用每个组件的makefile以构建组件,并将它们收集到最终的执行程序中。
     
     kbuild是递归make的一个很好的例子。
     ------------------------------------------------------
     Makefile: 位于源代码根目录的顶级 makefile
     .config: 内核配置文件
     arch/$(ARCH)/Makefile: 架构的 makefile,用于补充顶级makefile
     scripts/Makefile.*: 描述所有的kbuild makefile的通用规则
     ------------------------------------------------------
     1)顶级makefile会将架构Makefile包含进去,读取 .config 文件
     2)在 scripts/ Makefile.* 中定义的例程的帮助下,在每个组件的makefile上调用make,构建组件
     3)将所有的中间对象链接为 vmlinux
    

Kconfig语法

  • CONFIG宏变量参数

     bool:      表示该CONFIG宏只能选择y(编译内核)或者n(不编译),不能选择m(编译为模块)
     tristate:  表示该CONFIG宏可以设置y/m/n三种模式
     string:    表示该CONFIG宏可以设为一串字符,如#define CONFIG_XXX "config test"
     hex:       表示该CONFIG宏可以设为一个十六进制,如#define CONFIG_XXX 0x1234
     int:       表示该CONFIG宏可以设为一个整数,如#define CONFIG_XXX 1234
    
  • 常用参数

      default y:  	表示默认是勾上的,也可以写为default m或者default n
      help:       	帮助提示信息
      depends on: 	依赖项,如depends on XXX 表示当前宏需要CONFIG_ XXX宏打开的前提下,才能设置它
      select :    	反依赖项,如 selecton XXX表示当前宏如果是y或者m则会自动设置XXX=y或者m
      choice:    	会生成一个单选框,里面通过多选一方式选择config
      prompt:       提示信息,对于choice而言,则会用来当做一个单选框入口点的标签
      range :     	设置用户输入的数据范围,如range 0 100表示数据只能位于0~100
      menuconfig: 	和config XXX类似,不同的是该选项除了能设置y/m/n外,还可以实现菜单效果(能回车进入该项内部)
      menu/endmenu:可以理解成一个目录,menu可以把其中一部分配置项包含到一个menu中,这样有利于配置的分类显示
      config:		构成Kconfig的最基本单元,其中定义了配置项的详细信息
      source:		将另外一个Kconfig文件直接复制到当前位置,类似include。
      comment:		注释
    

Editor

C/C++:
	VSCode / Source Insight / Clion / CodeBlocks
python:
	PyCharm / sublime text / jupyter
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值