Makefile文件的简单编写

2023-11-05

参考:
MakeFile文件是什么——内容、工作原理、作用、使用
嵌入式操作系统linux篇(书)
Makefile伪目标
GNU make中文手册.pdf

  在嵌入式开发中,一个工程中的源文件是非常多的,如果一个个编译会很麻烦,Makefile的出现解决了这个麻烦事,只要我们把Makefile写好,只需要“make”一下,整个工程完全自动编译,极大的提高了软件开发的效率。
下图显示了makefile在工程中的位置,一个目录都有一个makefile文件。

在这里插入图片描述
  make是 一个命令解析工具,用来解释makefile中的规则,编译源代码,生成结果代码。一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。从事嵌入式系统开发需要掌握好makefile的编写。

一. Makefile 的规则:

  1. 一个规则是由目标条件(又称为先决条件)和命令所组成的。命令与条件之间的表达的就是依赖关系(因为这种关系,我们有时候会将条件与依赖不加于区分),这种依赖关系指明在构建目标之前,必须保证条件先满足(或已经构建好了条件)。
  2. 所谓目标就是我们想要生成的文件,然后要生成该文件所需的资源称为条件,将条件变成目标的“动作”称为命令
    在这里插入图片描述
  3. 当条件是目标时,必须先把目标构建出来。

在这里插入图片描述

  1. 一个makefile中是存在多个规则的,在编写规则时应先把各文件的依赖关系想清楚,需要表达什么样的依赖关系。拿下图举例,我们要生成最终的目标 需要的依赖是 目标1,而目标1还没有被构建出来,这时候会先去构建目标1,执行第二个规则,这时候目标2还没构建,又去执行第三个规则,这种依赖关系与函数的递归调用挺类似的。
    需要注意的是:如果第一个规则中的条件不存在,或者该条件不与其它规则有联系,那么规则中的第一个目标将被视为默认目标,其他目标就不会被执行。
    在这里插入图片描述

二.伪目标(又为假目标)

  1. 一般来说,make 的最终目标是 makefile 中的第一个目标,而其它目标一般是因为要生成这个最终目标而附带出来的。这是 make 的默认行为。当然,你的 makefile 是由许多个目标组成,你可以通过 make+目标,让其完成你所指定的目标。 make 可以指定所有 makefile 中的目标,那么也包括“伪目标”,于是我们可以根据这种性质来让我们的 makefile 根据指定的不同的目标来完成不同的事。
    所谓伪目标就是没有条件,只有目标和命令,然后再目标前面加了.PHONY关键字声明。它不代表一个真正的文件名,是一个“虚假”的目标。有时我们也可以将一个伪目标称为标签
    格式:
    在这里插入图片描述
  2. 伪目标的用途是什么,下面先举个例子:
    比如我们在当前目录下有个hello.c文件,在makefile编写一个规则编译这个.c文件成为可执行文件。
    在这里插入图片描述
    执行make命令,在当前目录找到makefile,然后执行makefile里面的命令。
    在这里插入图片描述
      通过makefile生成了一个可执行文件hello,如果我们这时候想把这个可执行文件删除,只需执行linux命令 rm hello删除该文件。这样是可行的,但当一个工程变大,生成的中间文件很多,还要一个个删除就很浪费时间了。这时候,就需要在加一个规则,在这个规则中添加删除命令。然后在命令行执行meke+标签命令,即可删除可执行文件hello,如
    在这里插入图片描述
      这里的clean是一个目标,在执行make时可以指定 clean这个目标来执行其所在规则定义的命令,也就是执行rm hello这个操作。也就是说,我们使用伪目标这种规则所定义的命令不是去创建目标文件,而是使用make指定具体的目标来执行一些特定的命令。 这里的clean还不是真正的“伪目标”,当在同一个目录下存在一个与该目标名一样的文件,这时候再去执行make clean 时,会提示该“clean”已经是最新了,如下图。
    在这里插入图片描述
      为什么会出现这种情况呢?其实,每次在执行make命令时,make都会去检查依赖关系中相关文件的时间戳,如果条件中的相关文件的时间戳大于目标的时间戳,也就是说依赖比目标新,则说明依赖文件有改变,那么需要运行规则当中的命令去重新构建目标。因为make工具将clean目标当成一个文件,且在当前目录下找到了这个文件,加上这个规则里没有依赖,所以,当要求make构建clean目标时,它就会认为clean是最新的了。
    在这里插入图片描述
  3. 在实际工作中会出现当前目录有的文件名会出现与目标名一样的情况,那么如何处理呢?
      只需要在目标前面加上.PHONU关键字,用来说明clean这个是一个伪目标,如果当前目录下有跟目标一样的文件,还可以去执行make clean命令了。对于伪目标,就是只将它作为一个“命令”使用,而不是一个“文件”,所以每一次make这个伪目标,其所在的规则中的命令都会被执行。如图:
    在这里插入图片描述
  4. GNU常用的伪目标名称
      all:这个伪目标是所有目标的目标,其功能一般是编译所有的目标。
      clean:这个伪目标功能是删除所有被 make 创建的文件。
      install :这个伪目标功能是安装已编译好的程序,其实就是把目标执行文件拷贝到指定的目标中去。
      print:这个伪目标的功能是例出改变过的源文件。
      tar:这个伪目标功能是把源程序打包备份。也就是一个 tar 文件。
      dist:这个伪目标功能是创建一个压缩文件,一般是把 tar 文件压成 Z 文件。或是 gz 文件。
      TAGS:这个伪目标功能是更新所有的目标,以备完整地重编译使用。
      checktest:这两个伪目标一般用来测试 makefile 的流程。

三:扩展

   echo命令:该命令是Bash shell的一个命令,其功能用于打印字符串到终端上。在终端上输入echo “hello world”,它会输出原样输出hello world这个字符串。这个命令用于在编译或者调试过程中输出一些信息。
在这里插入图片描述
   在makefile中,先不加echo命令的情况,如下图,make 执行命令行并把命令行的内容进行输出。我们称之为“回显”,就好像我们输入命令执行一样。这样make后生成了一个可执行文件hello。需要注意的是,由于在makefille中“$”具有特殊含义,因此如果想采用echo输出“$”,则必须用两个连着的“$”。还有,如果想显示“$@”符号,需要在前面加一个脱字符“\"。在这里插入图片描述
   如果前面加一个“@”符号,这时候在执行make命令时,这些命令执行时不会在终端上显示,生成了一个可执行文件hello。如下图在这里插入图片描述
   如果只加了echo,然后在执行如下图,这时候会把makefile文件中命令显示出来:echo gcc hello.c -o hellogcc hello.c -o hello但不会去生成可执行文件hello。echo命令就只是用来显示后面的内容。(注意:echo前面必须只有Tab键的长度,且至少有一个Tab,不能用空格代替,否则编译错误为: *** missing separator. Stop)
在这里插入图片描述
  当通过上面的图片显示可以看到,显示了echo gcc hello.c -o hello的内容和gcc hello.c -o hello的内容,这样出现的内容就会很多余。这时候,在echo前面加个“@”符号,就不会显示echo行的内容,只显示echo后面的内容,而且如果echo后的内容是命令,make也不会去执行这个命令。如下图,这样我们可以使用@echo+要显示的内容,来显示一些调试信息。
在这里插入图片描述
  通过一个例子来说明之前说写的内容:在一个目录里写了三个c文件,main.c1.c2.c,然后使用makefile文件去构建可执行文件main。(#号表示注释,类似c语言的//
在这里插入图片描述
  执行make命令,从下图可以看到,写的编译信息通过终端显示了出来。通过编译信息显示的顺序也可以知道,在make执行第一条规则时,由于条件main.o1.o2.o三个先决条件没有被构建,所以按从左到右的顺序去构建这三个条件,最后构建这三个条件后,执行第一个规则,将这三个条件去链接成可执行文件main
在这里插入图片描述
  使用ls -a命令可以看到,make结束后产生了一些中间文件:main.o、1.c、2.c。通过执行伪目标make clean去清除这些中间文件。

四:Makefile变量

   当工程文件变多,makefie文件会写的很庞大,这时就需要使用变量来使makefile内容变得简洁、具有可维护性。比如可以将上个图中的makefile改成下图:
在这里插入图片描述
makefile中的变量只代表文本数据(字符串)
makefile中的变量名规则:
  ----变量名可以包含字符,数字,下划线
  ----不能包含“:”、“#”,“=”或“ ”
  ----变量名大小写敏感
对变量的引用采用$(变量名)或者${变量名}这两种方式。

变量可分为三种:1.用户自定义变量、2.预定义变量、3.自动变量

  1. 用户自定义变量:上面的OBJ、OBJS就是用户自定义的变量
  2. 预定义变量:上面的CC、RM就是预定义变量,该变量的值可重新被改变,如果不改变的话,保持默认值。上图又可改成:
    在这里插入图片描述
    make输出,从下图可以看到,$(CC)替换成cc,$(RM)替换成rm -f在这里插入图片描述
    makefile常见的预定义变量:
    在这里插入图片描述在这里插入图片描述
      ar:建立、 修改、 提取归档文件。 归档文件是包含多个文件内容的一个大文件, 其结构保证了可以恢复原始文件内容
    GCC的执行过程
      1.调用cpp进行预处理, 对源代码文件中的文件包含(include)、 预编译语句(如宏定义define等)进行分析;
      2.调用ccl进行编译, 生成.s为后缀的目标文件;
      3.调用as进行汇编, 汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件;
      4.调用ld进行链接, 所有的目标文件被安排在可执行程序中的恰当的位置。 同时, 该程序所调用到的库函数也从各自所在的档案库中链接到合适的地方。
  3. 自动变量:所谓自动化变量,就是这种变量会把模式中所定义的一系列的文件自动地挨个取出,直到所有的符合模式的文件都取完了。这种自动化变量直营出现在规则的命令中。上图又可改成:
    在这里插入图片描述

常用的自动变量:

  1. $@:代表规则中的目标文件名。如果目标是一个文档( Linux中,一般称.a文件为文档),那么它代表这个文档的文件名。在多目标的模式规则中,它代表的是哪个触发规则被执行的目标文件名(当目标有多个时)。如下图,第一个规则中$@代表libtest.a文件,第二个规则中$@代表1.o、2.o文件.。在这里插入图片描述

  2. $%:规则的目标文件是一个静态库文件时,代表静态库的一个成员名。例如,规则的目标是“foo.a(bar.o)”,那么,“$%”的值就为“bar.o”,“$@”的值为“foo.a”。如果目标不是函数库文件,其值为空。如下图。在这里插入图片描述

  3. $<:规则的第一个依赖文件名。如果是隐含规则,则它代表通过目标指定的第一个依赖文件。

  4. $?:所有比目标文件更 新的依赖文件列表,空格分割。如果目标是静态库文件名,代表的是库成员( .o文件)的更新情况。

  5. $^:规则的所有依赖文件列表,使用空格分隔(当依赖有多个时)。如果目标是静态库文件名,它所代表的只能是所有库成员( .o文件)名。一个文件可重复的出现在目标的依赖中,变量“$^只记录它的一次引用情况。就是说变量“$^”会去掉重复的依赖文件。如下图,在规则1中目标是静态库,所以$^代表该静态库的成员1.o、2.o
    在这里插入图片描述

  6. $+:类似“$^”,但是它保留了依赖文件中重复出现的文件。主要用在程序链接时,库的交叉引用场合。

四种变量定义(赋值)

GNU make 中,一个变量的定义有四种方式(或者称为风格)。我们把这四种方式定义的变量可以看作变量的四种不同风格。变量的这四种不同的风格的区别在于: 1. 定义方式; 2. 展开时机。

  1. 递归展开式变量(递归赋值)–影响的变量可能会是多个
    这一类型的变量的定义是通过“=”或者使用指示符“define”定义的变量。
    比如下图,整个变量的替换过程时这样的:首先“$(name1)”被替换为
    $(name2)”,接下来“$(name2)”被替换为“$(name3)”,最后“$(name3)”被替换为“小明”。整个替换的过程是在执行“echo $(name1)”命令行时进行的。
    在这里插入图片描述优点是:这种类型变量的定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义,或者是通过 make 的命令行选项传递的变量)。
    但这种递归展开式又有缺点,如下图:使用此风格的变量定义,可能会由于出现变量的递归定义而导致 make 陷入到无限的变量展开过程中,最终使 make 执行失败。 它将会导致 make 进入对变量name1、name2、name3的无限展开过程中去(这种定义就是变量的递归定义)。展开过程将是套嵌的、不能终止的(在发生这种情况时, make 会提示错误信息并结束)。一般在书写 Makefile 时,使用这种追加变量值的方法也很少使用(也不是我们推荐的方式)。
    在这里插入图片描述
  2. 直接展开式变量(简单赋值):对“递归展开式”的优化
    这一类型的变量的定义是通过“:=”定义的变量。
    如下图,变量值中对另外变量的引用或者函数的引用在定义时被展开(对变量进行替换)。所以在变量被定义以后就是一个实际所需要定义的文本串,其中不再包含任何对其它变量的引用。这种定义变量的方式更适合在大的编程项目中使用,
    因为它更像我们一般的编程语言。需要注意的是:此风格变量在定义时就完成了对所引用的变量的展开,因此它不能实现对其后定义变量的引用。
    在这里插入图片描述
    如果在定义name2时前面没有name1的定义,那么name2的值是空的,如下图,由于在变量“name1”的定义出现在“name2”定义之后。因此在“name2”的定义中,“name2”的值为空。这一点也是直接展开式与递归展开式的不同点。在这里插入图片描述
    如果将name2的定义改成递归展开式,那么name2的值是不为空的,如下图:在这里插入图片描述
  3. 条件赋值(?=):意思就是如果变量在前面没有定义,使用赋值符号中的值定义该变量。如果变量在前面已经定义,对该变量的赋值无效。比如下图,由于name1之前已经定义了,所以第二次定义name1无效。
    在这里插入图片描述
    如果前面name1未定义,这将name1赋值为"小明",如下图在这里插入图片描述
  4. 追加赋值(+=):意思就是在原来已经被赋值的变量上在附加内容。如下图:
    在这里插入图片描述

隐式规则

  所谓隐式,就是有些中间的规则不用写出来,make 会在自己的“隐含规则”库中寻找可以用的规则,如果找到,那么就会使用。如果找不到,那么就会报错。在之前所写的规则都是显式的。在下面例子中,make 调用的隐含规则是,把[.o]的目标的依赖文件置成[.c],并使用 默认规则“$(CC) $(CFLAGS) $(CPPFLAGS) -c -o”来生成[.o]的目标,这样就不用再写将.c文件编译成.o的规则了。三个.o文件构建后,因为该规则没有命令,然后就不会去生成可执行文件a.out。
在这里插入图片描述
  这里需要注意的是,使用隐式规则是会使用到一些变量(比如预定义变量),这里的CFLAGS、CPPFALGS是无默认值的,如果不给这些变量赋值,这些值是”空“的。如果给这些赋予一些参数,如下图,这样在执行默认规则时就会显示出来了。
在这里插入图片描述
在规则中添加生成可执行文件a.out的命令,如下图
在这里插入图片描述

模式规则

  模式规则中,至少在规则的目标定义中要包含"%",否则,就是一般的规则。目标中的"%“定义表示对文件名的匹配,”%“表示长度任意的非空字符串。例如:”%.c“表示以”.c“结尾的文件名 , 而"s%.c"则表示以"s"开头、”.c"结尾的文件名 。从下图可以看到,main.o : main.c 、1.o : 1.c、2.o : 2.c 三个规则都相同,可以使用模式规则把这三个规则写成%.o : %.c。
在这里插入图片描述
  这里需要注意的是,前面a.out : $(OBJS)原来是隐式规则,然后这里使用了模式规则,从.c文件生成.o文件的规则不在按照隐式规则的规定去生成,而是按照模式规则的规定。如下图,执行make后按照模式规则里面的命令去执行。在这里插入图片描述

make函数(以下只列举两个函数,更多信息请参考GNU make手册)

  1. 文件名处理函数:
    在这里插入图片描述
    测试:在这里插入图片描述
  2. 文本处理函数:
    在这里插入图片描述
    测试:
    在这里插入图片描述
    两个函数结合:在这里插入图片描述
  3. shell函数:
    在这里插入图片描述
    测试: 使用shell命令打印当前目录的文件属性在这里插入图片描述
    在这里插入图片描述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Makefile文件的简单编写 的相关文章

  • Tomcat Intellij Idea:远程部署

    RackSpace 云服务器 Ubuntu 12 04 Intellij Idea 11 1 2 Windows 8 Tomcat 7 0 26 JDK 6 在 Intellij Idea 上 当我尝试在远程 Tomcat 7 服务器上运行
  • 批量删除文件名中包含 BASH 中特殊字符的子字符串

    我的目录中有一个文件列表 opencv calib3d so2410 so opencv contrib so2410 so opencv core so2410 so opencv features2d so2410 so opencv
  • 找不到包“gdk-pixbuf-2.0”

    我正在尝试在 Amazon Linux 发行版实例上构建 librsvg 我已经通过 yum 安装了大部分依赖项 其中一些在实例上启用的默认 yum 存储库中不可用 因此必须从头开始构建它们 我已经走了很远 但还停留在最后一点 跑步时sud
  • 仅使用containerd(不使用Docker)修剪容器镜像

    如果我刚刚containerd安装在 Linux 系统上 即 Docker 是not安装 如何删除未使用的容器映像以节省磁盘空间 Docker 就是这么方便docker system prune https docs docker com
  • 执行命令而不将其保留在历史记录中[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 在进行软件开发时 经常需要在命令行命令中包含机密信息 典型示例是将项目部署到服务器的凭据设置为环境变量 当我不想将某些命令存储在命令历史记
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 为什么 Linux 没有 DirectX API?

    在考虑现代显卡的 Windows 系统上 DirectX API 的驱动程序端实现时 我想知道为什么此实现在非 Windows 系统 尤其是 Linux 上不可用 由于明显缺乏此功能 我只能假设有一个我无视的充分理由 但在我的原始理解中 我
  • 在 C 中使用单个消息队列是否可以实现双向通信

    我希望服务器向客户端发送一些消息 并让客户端确认它 我被分配了这个任务 我可以在 C linux 中使用单个消息队列来完成它还是我需要创建两个 谢谢 是的 可以使用 sysV 消息队列来做到这一点 从您之前的问题来看 您正在使用该队列 您可
  • 如何为 Linux 桌面条目文件指定带有相对路径的图标?

    对于我的一个 Linux 应用程序 我有应用程序二进制文件 一个 launcher sh 脚本 针对 LD LIBRARY PATH 和一个 desktop 文件 所有这些都位于同一文件夹中 我想使用图标的相对路径而不是绝对路径 我试过了
  • 无需超级用户即可在 Linux 中打开 RAW 套接字

    我必须编写一个在 Linux 上运行的 ping 函数 语言是 C 所以 C 也可以 在网上搜索并查看源代码ping命令 事实证明我应该创建一个原始套接字 icmp sock socket AF INET SOCK RAW IPPROTO
  • CMake 链接 glfw3 lib 错误

    我正在使用 CLion 并且正在使用 glfw3 库编写一个程序 http www glfw org docs latest http www glfw org docs latest 我安装并正确执行了库中的所有操作 我有 a 和 h 文
  • Bash - 在与当前终端分开的另一个终端中启动命令的新实例

    我有一个简单的 bash 脚本 test sh 设置如下 bin bash args if args 0 check capture then watch n 1 ls lag home user capture0 watch n 1 ls
  • 如何使用waf构建共享库?

    我想使用构建一个共享库waf http code google com p waf 因为它看起来比 GNU 自动工具更容易 更简洁 到目前为止 我实际上有几个与我开始编写的 wscript 有关的问题 VERSION 0 0 1 APPNA
  • 配置tomat的server.xml文件并自动生成mod_jk.conf

    我在用apache 2 2 15 and tomcat6 6 0 24 on CentOS 6 4并希望使用 tomcat 服务器的功能 通过添加以下内容自动生成 mod jk conf 文件
  • 使用 gdb 调试 Linux 内核模块

    我想知道 API 在内核模块 中返回什么 从几种形式可以知道 这并不是那么简单 我们需要加载符号表来调试内核模块 所以我所做的就是 1 尝试找到内核模块的 text bss和 data段地址 2 在 gdb 中使用 add symbol f
  • 使用os.execlp时,为什么`python`需要`python`作为argv[0]

    代码是这样的 os execlp python python child py other args this works os execlp python child py other args this doesn t work 我读过
  • cdc_acm:无法设置 dtr/rts - 无法与 USB cdc 设备通信

    我试图使用 pic24fj128gb206 枚举 usb cdc 设备 设备似乎已正确枚举 但是当我将设备连接到 Linux PC 时 我从内核收到以下警告消息 cdc acm 1 8 1 6 7 1 0 failed to set dtr
  • 如何让 Node.js 作为后台进程运行并且永不死掉?

    我通过 putty SSH 连接到 linux 服务器 我尝试将其作为后台进程运行 如下所示 node server js 然而 2 5 小时后 终端变得不活动 进程终止 即使终端断开连接 我是否也可以使进程保持活动状态 Edit 1 事实
  • 复制目录内容

    我想将目录 tmp1 的内容复制到另一个目录 tmp2 tmp1 可能包含文件和其他目录 我想使用C C 复制tmp1的内容 包括模式 如果 tmp1 包含目录树 我想递归复制它们 最简单的解决方案是什么 我找到了一个解决方案来打开目录并读

随机推荐

  • Win7系统提示Windows Defender无法扫描选定的文件解决方法

    Win7 64位系统提示 Windows Defender无法扫描选定的文件 怎么办呢 使用Windows Defender扫描文件 结果弹出如下图窗口 该怎么解决呢 参考下文 一起来解决Win7系统提示 Windows Defender无
  • 好玩的人脸识别小软件

    好玩的人脸识别小软件 前言 使用教程 1 软件代码 2 使用步骤 致谢 前言 在毕业的小空闲里面 利用pyqt写了一个简单实现人脸检测的小软件 非常好玩 推荐给大家玩一下 主要是利用Retinaface和Facenet实现人脸识别的 这两个
  • 将jpg格式的图片转换成eps

    bmeps c fig1 jpg fig1 eps
  • Python爬虫数据提取方式——-selenium爬虫框架中的数据提取方式

    介绍 selenium测试框架在爬虫中的应用 网页中通过js渲染的数据 爬虫的解决办法 1 去静态源码中查找 2 抓包或者网络请求中 查看是否有类似与json的get请求 直接请求这个json的API拿到数据 3 使用phantomjs s
  • element-ui 改变一行的样式row-style

    element ui 改变一行的样式row style 在工作过程中需要改变elementui的row style 在百度上查了很久结果都是一样的 rowStyle row rowIndex if rowIndex 0 return col
  • 华为OD机试 - 事件推送(Python)

    题目描述 同一个数轴X上有两个点的集合A A1 A2 Am 和B B1 B2 Bn Ai和Bj均为正整数 A B已经按照从小到大排好序 A B均不为空 给定一个距离R 正整数 列出同时满足如下条件的所有 Ai Bj 数对 Ai lt Bj
  • LaTeX 排版常用技巧 - 逐渐积累

    1 箭头上的文字 你的文字 underrightarrow text 你的文字 你的文字 underrightarrow text 你的文字 更喜欢另一种方式 CPU stackr
  • 散列表查找成功和不成功时的平均查找长度

    已知散列表长度为13 散列函数为H key key 11 处理冲突的方法为线性探测法 请画出依次插入关键字 10 8 40 27 21 57 46 23 19 56 以后的散列表 并计算查找成功和不成功时的平均查找长度 解 散列表是哈希表的
  • 用Ajax实现不刷新页面修改内容

    趁今天有空 就学习了Ajax 在Ajax in action那本书里提到了SAjax 就去下来看看 果然功能强大 让编写Ajax代码变的很简单 于是就写了个 修改内容不刷新页面 的代码 这个功能在网上以前是到处看到 今天终于自己实现了个 代
  • Spring boot本地运行正常,请求正常,打包后运行正常,但是请求报错:invalid bound statement (not found) 的问题

    Spring boot本地运行请求正常 打包后运行正常 但是请求报错 invalid bound statement not found 的问题 问题场景 项目结构 初步分析 接着踩坑 原因 个人问题 总结 问题场景 这个问题发生在我准备将
  • 数据仓库、数据开发面经

    目录 一 前言 二 关于内推or猎头or招聘软件的选择 三 面试形式 四 面试流程选择
  • 【经典蓝牙】 蓝牙HFP层协议分析

    HFP 概述 HFP概念介绍 HFP Hands Free Profile 是蓝牙免提协议 可以让蓝牙设备对对端蓝牙设备的通话进行控制 例如蓝牙耳机控制手机通话的接听 挂断 拒接 语音拨号等 HFP中蓝牙两端的数据交互是通过定义好的AT指令
  • Symbol SysTick_Handler multiply defined (by port.o and bsp_timer.o).

    Symbol SysTick Handler multiply defined by port o and bsp timer o Symbol PendSV Handler multiply defined by port o and s
  • PADS9.5光绘文件输出教程

    目录 光绘文件输出前准备 先执行灌铜 特别注意混合分割层 开短路检查 注意安全间距的验证选项 光绘文件生成 线层 丝印层 阻焊层 钢网层 钻孔图 数控钻孔 线层 阻焊层 丝印层 钢网层GERBER系统生成 钻孔图和数控钻孔生成 对软件生成光
  • Hadoop001存储模型

    HDFS 存储模型 思想 1 化整为0 2 并行计算 第一步 如果一个文件非常非常大 单台服务器的内存无法处理这样一个大文件 无法一次性加载到内存中 可以对文件切割成若干个小文件 第二步 为了达到提升计算效果的目的 可以把切割的小文件分散发
  • c语言面向过程到面向对象,c++ 面向过程 c语言面向对象:列表

    主要利用结构体和函数指针 实现面向对象编程中的封装 继承和多态 base htypedef struct BaseClass int m Data void xjbclz 2016年06月04日 22 35 1272 我们知道嵌入式是在操作
  • 设置windows宿主机内的Linux虚拟机的端口开放

    比如希望开放的是windows内的Linux虚拟机 IP地址 172 30 2 1611 端口 27017 则在windows主机中 用管理员权限打开控制台 并输入 netsh interface portproxy add v4tov4
  • JavaScript 函数防抖(debounce)的实现

    函数防抖是什么 函数防抖是指对于在事件被触发n秒后再执行的回调 如果在这n秒内又重新被触发 则重新开始计时 是常见的优化 适用于 表单组件输入内容验证 防止多次点击导致表单多次提交 等情况 防止函数过于频繁的不必要的调用 代码实现 思路 用
  • tomcat部署项目,ip+端口直接访问项目的三种方式

    部署web项目 需要ip 端口 项目名 路径访问项目 如localhost 8080 springmvc xxx 现在想去掉项目名springmvc 直接输入 localhost 8080 就能访问 三种配置 方式一 项目打war包放到to
  • Makefile文件的简单编写

    参考 MakeFile文件是什么 内容 工作原理 作用 使用 嵌入式操作系统linux篇 书 Makefile伪目标 GNU make中文手册 pdf 在嵌入式开发中 一个工程中的源文件是非常多的 如果一个个编译会很麻烦 Makefile的