- 浏览: 379997 次
- 性别:
- 来自: 苏州
-
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
Ubuntu的社区有一份关于makefile的文章写的很好,连接如下:http://wiki.ubuntu.org.cn/%E8%B7%9F%E6%88%91%E4%B8%80%E8%B5%B7%E5%86%99Makefile:%E4%BD%BF%E7%94%A8make%E6%9B%B4%E6%96%B0%E5%87%BD%E6%95%B0%E5%BA%93%E6%96%87%E4%BB%B6
gcc的Hello World(转载)(转自:http://hi.baidu.com/dream_eagle/item/8332d2163cf75e6d71d5e8e2)
实例代码:
/*
* hello.c - Canonical "Hello, World!" program
*/
#include <stdio.h>
int main(void)
{
printf("Hello,Linux programming world!\n");
return 0;
}
在命令行上键入以下命令编译和运行这段程序:
$gcc hello.c -o hello
$./hello
Hello, Linux programming world!
第一行命令告诉gcc对源代码hello.c进行编译和链接,并使用-o参数指定创建名为hello的可见程序.第二行命令执行hello这个程序,第三行是程序的执行结果.
其实,gcc首先运行预处理程序cpp来展开hello.c中的宏并在其中插入#include文件所包含的内容:然后把预处理后的源代码编译成为目标代码;最后,链接程序ld创建一个名为hello的二进制文件.
现在我们来通过手工操作重新创建这些步骤,以逐步执行编译过程.第一布是运行预处理器.使用-E选项告诉gcc在预处理后停止编译过程:
$gcc -E hello.c -o hello.cpp
此时查看hello.cpp会发现stdio.h的内容确实都插到文件里去了,而其他应当被预处理的标记也做了类似处理.
下一步是将hello.cpp编译为目标代码.可使用gcc的-c选项来完成:
$gcc -x cpp-output -c hello.cpp -o hello.o
-x选项告诉gcc从指定的步骤开始编译,在本例中也就是编译器处理后的源代码(cpp-output).
gcc是怎么知道如何处理某种特殊类型的文件呢?它是依靠文件的扩展名来决定如何正确处理该文件的.
——————————————————————————————
扩展名 类型
.c C语言源代码
.C,.cc C++语言源代码
.i 预处理后的C源代码
.ii 预处理后的C++源代码
.S,.s 汇编语言源代码
.o 编译后的目标代码
.a,.so 编译后的库代码
———————————————————————————————
最后,链接目标文件,生成二进制代码.
$gcc hello.c -o hello
gcc Makefile 入门 (链接:http://www.cnblogs.com/jasonliu/archive/2011/12/23/2299740.html)
使用make命令编译项目文件入门
目录:
一、make命令的运行过程
二、基本gcc编译命令
三、简单Makefile文件的编写
四、实例
一、make命令的运行过程
在shell的提示符号下,若输入"make",则它会到目前的目录下找寻Makefile这个文件.然后依照Makefile中所记录的步骤一步一步的来执行.在我们写程序的时候,如果事先就把compiler程式所需要的步骤先写在Makefile中的话,想要compiler程序的时候就只要打入make的指令.只要程序无误的话,就可以获得所需要的结果了!
在项目文件中,如果有成百上千个源程序,每次修改其中的一个都需要全部重新编译是不可想象的事情.但通过编辑Makefile文件,利用make命令就可以只针对其中修改的源文件进行编译,而不需要全体编译.这就是make命令在编译项目文件时体现出来的优势.能做到这点,主要是基于Makefile文件的编写,和make命令对Makefile文件的调用.Makefile文件作为make命令的默认参数,使一个基于依赖关系编写的结构文件.
大家经常看到使用make all, make install, make clean等命令,而他们处理的目标都是一个Makefile文件,那么all、install、clean参数是如何调用Makefile文件的运行呢?在这里,如果向上面的命令如果能够正确运行的话,那么在Makefile文件里一定有这样的几行,他们的以all、install、clean开始
all: ×××××××
×××××××××××
install: ××××××
×××××××××××
clean: ×××××××××
×××××××××××
all,install,clean我们可以用其他的变量来代替,他们是编译时的一个参数,在Makefile文件中作为一个标志存在,也就是我们所说的目标.make all命令,就告诉make我们将执行all所指定的目标.为了便于理解Make程序的流程,我们给大家看一个与gcc毫无关系的Makefile文件:
#Makefile begin
all:
@echo you have typed command "make all"
clean:
@echo you have typed command "make clean"
install:
@ehco you have typed command "make $@"
#Makefile end
注意在这里,all:、clean:、install:行要顶格些,而所有的@echo前要加tab键来跳格缩进.下面是运行结果
[root@xxx test]#make all
you have typed command "make all"
[root@xxx test]#make clean
you have typed command "make clean"
[root@xxx test]#make install
you have typed command "make install"
二、基本gcc编译命令
1、源程序的编译
在Linux下面,使用GNU的gcc编译器编译一个C语言的源程序.下面我们简单介绍几个常用的Gcc编译命令和参数,这里不是讲解Gcc的使用,只是介绍简单的基础知识是我们能看懂一般的makefile文件.
我们先看一个使用gcc编译器的实例.假设我们有下面一个非常简单的源程序(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux\n");
}
要编译这个程序,我们只要在命令行下执行: gcc -o hello hello.c
gcc 编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.命令行中 gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件.
gcc的基本格式就是:
gcc [-option] objectname sourcename
其中-option是参数,用来控制gcc的编译方式,常见的参数有如下几个:
-o 表示我们要求输出的可执行文件名:-o binaryname
-c 表示我们只要求编译器进行编译,输出目标代码,而不进行连接: -c objectivename.o
-g 表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息: -g
-O2 表示我们希望编译器在编译的时候对我们的程序进行一定程度的优化.2表示我们优化的级别是2.范
围是1-3.不过习惯上我们都使用2的优化级别.
-Wall是警告选项,表示我们希望gcc在编译的时候,让gcc输出她认为的一些程序中可能会出问题的一些警
告信息,比如指针没有初始化就进行赋值等等一些警告信息.
-l 与之紧紧相连的是表示连接时所要的链接库,比如多线程,如果你使用了pthread_create函数,那么 你就应该在编译语句的最后加上"-lpthread","-l"表示连接,"pthread"表示要连接的库,注意他们 在这里要连在一起写.如:gcc -o test test1.o test2.o -lpthread
-I 表示将系统缺省的头文件路径扩展到当前路径,默认的路径保存在/etc/ld.conf文件中。
gcc的例子:
gcc -c test.c,表示只编译test.c文件,成功时输出目标文件test.o
gcc -o test test.o,将test.o连接成可执行的二进制文件test
gcc -o test test.c,将test.c编译并连接成可执行的二进制文件test
gcc -c test.c -o test.o ,与上一条命令完全相同
gcc test.c -o test,与上一条命令相同
gcc -c test1.c,只编译test1.c,成功时输出目标文件test1.o
gcc -c test2.c,只编译test2.c,成功时输出目标文件test2.o
gcc -o test test1.o test2.o,将test1.o和test2.o连接为可执行的二进制文件test
gcc -c test test1.c test2.c,将test1.o和test2.o编译并连接为可执行的二进制文件test
2、程序库的链接
试着编译下面这个程序
/* temp.c */
#include
int main(int argc,char **argv)
{
double value =15;
printf("Value:%f\n",log(value));
}
这个程序相当简单,但是当我们用 gcc -o temp temp.c 编译时会出现下面所示的错误.
/tmp/cc33Kydu.o: In function `main':
/tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'
collect2: ld returned 1 exit status
出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我们必须和数学库连接,为此我们要加入 -lm 选项. gcc -o temp temp.c -lm这样才能够正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的 -L选项指定路径.比如说我们有一个库在 /home/hoyt/mylib下,这样我们编译的时候还要加上 -L/home/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib、/usr/lib、/usr/local/lib(你可以查看你的/etc/ld.conf文件来看看你的系统指定了那几个缺省的路径) 在这三个路径下面的库,我们可以不指定路径.
还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢?很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程(thread)函数的库文件(libpthread.a). 当然,如果找不到,只有一个笨方法.比如我要找sin这个函数所在的库. 就只好用 nm -o /lib/*.so|grep sin>~/sin 命令,然后看~/sin文件,到那里面去找了. 在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0 W sin 这样我就知道了sin在libm-2.1.2.so库里面,我用 -lm选项就可以了(去掉前面的lib和后面的版本标志,就剩下m了所以是 -lm). 如果你知道怎么找,请赶快告诉我,我回非常感激的.谢谢!
3、程序的调试
我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选择xxgdb.记得要在编译的时候加入-g选项.关于gdb的使用可以看gdb的帮助文件.由于我很少使用这个软件,所以我也不能够详细的说出如何使用. 不过我不喜欢用gdb.跟踪一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用.
4、头文件和系统求助
有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得着函数在那个头文件进行了说明.这个时候我们可以求助系统.比如说我们想知道fread这个函数的确切形式,我们只要执行 man fread 系统就会输出着函数的详细解释的.和这个函数所在的头文件说明了. 如果我们要write这个函数的说明,当我们执行man write时,输出的结果却不是我们所需要的. 因为我们要的是write这个函数的说明,可是出来的却是write这个命令的说明.为了得到write的函数说明我们要用 man 2 write. 2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3表示函数是C的库函数.
三、简单Makefile文件的编写
1、Makefile文件的一般组成
(1)注释:
在Makefile中,任何以"#"起始的文字都是注释,make在解释Makefile的时候会忽略它们.
(2)转接下行标志:
在Makefile中,若一行不足以容纳该命令的时候.可在此行之后加一个反斜线(\)表示下一行为本行的延续
,两行应视为一行处理
(3)宏(macro)
宏的格式为: =
例如:
CFLAGS = -O -systype bsd43
其实make本身已有许多的default的macro,如果要查看这些macro的话,可以用make -p的命令.
宏主要是作为运行make时的一些环境变量的设置,比如制定编译器等。
CC 表示我们的编译器名称,缺省值为cc.
CFLAGS 表示我们想给编译器的编译选项
LDLIBS 表示我们的在编译的时候编译器的连接库选项.(我们的这个程序中还用不到这个选项)
(4)规则(Rules)
格式如下:
:
....
:
....
注意:需要顶格写,而需要在下一行tab之后写,由于其是一个批处理形式的文件,所以不
可以随便的换行写,被迫换行的时候要用上面的转接下行标志进行连接.
(5)符号标志及缺省规则
$@ 代指目标文件
$< 第一个依赖文件
$^ 所有的依赖文件
$? 为该规则的依赖
- 若在command的前面加一个"-",表示若此command发生错误不予理会,继续执行下去.
$(macro) 应用这个变量,可以自动的将定义的宏加以展开,并替换使用。
.c.o:
gcc -c $< 这个规则表示所有的 .o文件都是依赖与其相应的.c文件的.例如mytool.o依赖于mytool.c
再一次简化后的Makefile
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
.c.o:
gcc -c $< -I.;
使用宏后进一步的简化Makefile可以是
CC=gcc
CFLAGS=-g -Wall -O2 -I.
main:main.o mytool1.o mytool2.o
.c.o:
2、依赖
我们现在提出这样一个问题:我如何用一个make命令将替代所有的make all, make install,make clean命令呢?当然我们可以象刚才那样写一个Makefile文件:
all:
@echo you have typed command "make all"
clean:
@echo you have typed command "make clean"
install:
@ehco you have typed command "make $@"
doall:
@echo you have typed command "make $@l"
@echo you have typed command "make all"
@echo you have typed command "make clean"
@ehco you have typed command "make install"
[root@xxx test]#make doall
you have typed command "make doall"
you have typed command "make all"
you have typed command "make clean"
you have typed command "make install"
在这里,doall:目标有4调语句,他们都是连在一起并都是由tab键开始的.当然,这样能够完成任务,但是太笨了,我们这样来写:
[root@xxx test]#cat Makefile
# #表示Makefile文件中的注释,下面是Makefile文件的具体内容
all:
@echo you have typed command "make all"
clean:
@echo you have typed command "make clean"
install:
@ehco you have typed command "make $@"
doall: all clean install
@echo you have typed command "make $@l"
相信大家已经看清了doall:的运行方式,它先运行all目标,然后运行clean目标,然后是install,最后是自己本身的目标,并且每个$@还是保持着各自的目标名称.效果大致是一样的。在这里,我们称all, clean, install为目标doall所依赖的目标,简称为doall的依赖.也就是你要执行doall,请先执行他们(all, clean, install),最后在执行我的代码.
注意依赖一定是Makefile里面的目标,否则你非要运行;一般写在最前边,而不是像这样写在最后边。
3、Makefile的编写
在Makefile中,一般采用引导的注释行开始;下边一般紧跟macro定义;接下来是标签(如上面的all、clean等);最后就是Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是:
#describe
macro
label: label1,label2
label1:
:
label2:
:
......
我们来看一个例子:
/* main.c */
#include
#include
int main(int argc,char **argv)
{
mytool1_print("hello");
mytool2_print("hello");
}
/* mytool1.h */
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif
/* mytool1.c */
#include
void mytool1_print(char *print_str)
{
printf("This is mytool1 print %s\n",print_str);
}
/* mytool2.h */
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif
/* mytool2.c */
#include
void mytool2_print(char *print_str)
{
printf("This is mytool2 print %s\n",print_str);
}
因为我们在程序中使用了我们自己的2个头文件,而在包含这2个头文件的时候,我们使用的是<> 这样编译器在编译的时候会去系统默认的头文件路径找我们的2个头文件,由于我们的2个头文件不在系统能够的缺省路径下面,所以我们自己扩展系统的缺省路径,为此我们使用了-I.选项,表示将系统缺省的头文件路径扩展到当前路径.这样的话我们也可以产生main程序,而且也不是很麻烦.但是考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新逐一编译?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译? 为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行一下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个Makefile的文件是:
# 这是上面那个程序的Makefile文件
main:main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
gcc -c main.c -I.
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c -I.
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c -I.
有了这个Makefile文件,不管我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件她连理都不想去理的.
四、实例
1、实例一
一个非常简单的Makefile
假设我们有一个程式,共分为下面的部份:
menu.c 主要的程式码部份
menu.h menu.c的include file
utils.c 提供menu.c呼叫的一些function calls
utils.h utils.c的include file
同时本程式亦叫用了ncurses的function calls.
而menu.c和utils.c皆放在/usr/src/menu下.
但menu.h和utils.h却放在/usr/src/menu/include下.
而程式做完之后,执行档名为menu且要放在/usr/bin下面.
# This is the Makefile of menu
CC = gcc
CFLAGS = -DDEBUG -c
LIBS = -lncurses
INCLUDE = -I/usr/src/menu/include
all: clean install
install: menu
chmod 750 menu
cp menu /usr/bin
menu: menu.o
$(CC) -o $@ $? $(LIBS)
menu.o:
$(CC) $(CFLAGS) -o $@ menu.c $(INCLUDE)
utils.o:
$(CC) $(CFLAGS) -o $@ utils.c $(INCLUDE)
clean:
-rm *.o
-rm *~
在上述的Makefile中,要使用某个macro可用$(macro_name)如此的形式.make会自动的加以展开.
$@为该rule的Target,而$?则为该rule的depend.
若在command的前面加一个"-",表示若此command发生错误则不予理会,继续执行下去.
上述的Makefile的关系可以表示如下:
all
/ \
clean install
\
menu
/ \
menu.o utils.o
若只想清除source以外的档案,可以打make clean;若只想做出menu.o可以打make menu.o;若想一次全部做完,可以打make all或是make;要特别注意的是command之前一定要有一个TAB(即TAB键).
2、实例二
有了上面的说明,我们就可以开始写一些简单的Makefile文件了.比如我们有如下结构的文件:
tmp/
+---- include/
| +---- f1.h
| +----f2.h
+----f1.c #include "include/f1.h"
+----f2.c #include"include/f2.h"
+---main.c #include"include/f1.h", #include"include/f2.h"
要将他们联合起来编译为目标为testmf的文件,我们就可以按下面的方式写Makefile:
#Makefile,Create testmf from f1.c f2.c main.c
main: main.o f1.o f2.o
gcc -o testmf main.o f1.o f2.o
f1.o: f1.c
gcc -c -o file1.o file1.c
f2.o: f2.c
gcc -c -o file2.o file2.c
main.o
gcc -c -o main.o main.c
clean:
rm -rf f1.o f2.o main.o testmf
执行这个Makefile文件
[root@xxx test]make
gcc -c -o main.o main.c
gcc -c -o file1.o file1.c
gcc -c -o file2.o file2.c
gcc -o testmf main.o f1.o f2.o
[root@xxx test]ls
f1.c f1.o f2.c f2.o main.c main.o include/ testmf
如果你的程序没有问题的话,就应该可以执行了./testmf
这是一个很简单的例子,但复杂的例子都是构建在简单功能基础上的.后面将继续介绍详细的makefile的编写方法。
参考连接地址:
http://bbs.ee.ntu.edu.tw/boards/Programming/17/12.html
http://www.linuxeden.com/forum/blog/index.php?op=ViewArticle&blogId=102509&articleId=341
http://www.douzhe.com/bbs/viewtopic.php?t=376&highlight=make
gcc的Hello World(转载)(转自:http://hi.baidu.com/dream_eagle/item/8332d2163cf75e6d71d5e8e2)
实例代码:
/*
* hello.c - Canonical "Hello, World!" program
*/
#include <stdio.h>
int main(void)
{
printf("Hello,Linux programming world!\n");
return 0;
}
在命令行上键入以下命令编译和运行这段程序:
$gcc hello.c -o hello
$./hello
Hello, Linux programming world!
第一行命令告诉gcc对源代码hello.c进行编译和链接,并使用-o参数指定创建名为hello的可见程序.第二行命令执行hello这个程序,第三行是程序的执行结果.
其实,gcc首先运行预处理程序cpp来展开hello.c中的宏并在其中插入#include文件所包含的内容:然后把预处理后的源代码编译成为目标代码;最后,链接程序ld创建一个名为hello的二进制文件.
现在我们来通过手工操作重新创建这些步骤,以逐步执行编译过程.第一布是运行预处理器.使用-E选项告诉gcc在预处理后停止编译过程:
$gcc -E hello.c -o hello.cpp
此时查看hello.cpp会发现stdio.h的内容确实都插到文件里去了,而其他应当被预处理的标记也做了类似处理.
下一步是将hello.cpp编译为目标代码.可使用gcc的-c选项来完成:
$gcc -x cpp-output -c hello.cpp -o hello.o
-x选项告诉gcc从指定的步骤开始编译,在本例中也就是编译器处理后的源代码(cpp-output).
gcc是怎么知道如何处理某种特殊类型的文件呢?它是依靠文件的扩展名来决定如何正确处理该文件的.
——————————————————————————————
扩展名 类型
.c C语言源代码
.C,.cc C++语言源代码
.i 预处理后的C源代码
.ii 预处理后的C++源代码
.S,.s 汇编语言源代码
.o 编译后的目标代码
.a,.so 编译后的库代码
———————————————————————————————
最后,链接目标文件,生成二进制代码.
$gcc hello.c -o hello
gcc Makefile 入门 (链接:http://www.cnblogs.com/jasonliu/archive/2011/12/23/2299740.html)
使用make命令编译项目文件入门
目录:
一、make命令的运行过程
二、基本gcc编译命令
三、简单Makefile文件的编写
四、实例
一、make命令的运行过程
在shell的提示符号下,若输入"make",则它会到目前的目录下找寻Makefile这个文件.然后依照Makefile中所记录的步骤一步一步的来执行.在我们写程序的时候,如果事先就把compiler程式所需要的步骤先写在Makefile中的话,想要compiler程序的时候就只要打入make的指令.只要程序无误的话,就可以获得所需要的结果了!
在项目文件中,如果有成百上千个源程序,每次修改其中的一个都需要全部重新编译是不可想象的事情.但通过编辑Makefile文件,利用make命令就可以只针对其中修改的源文件进行编译,而不需要全体编译.这就是make命令在编译项目文件时体现出来的优势.能做到这点,主要是基于Makefile文件的编写,和make命令对Makefile文件的调用.Makefile文件作为make命令的默认参数,使一个基于依赖关系编写的结构文件.
大家经常看到使用make all, make install, make clean等命令,而他们处理的目标都是一个Makefile文件,那么all、install、clean参数是如何调用Makefile文件的运行呢?在这里,如果向上面的命令如果能够正确运行的话,那么在Makefile文件里一定有这样的几行,他们的以all、install、clean开始
all: ×××××××
×××××××××××
install: ××××××
×××××××××××
clean: ×××××××××
×××××××××××
all,install,clean我们可以用其他的变量来代替,他们是编译时的一个参数,在Makefile文件中作为一个标志存在,也就是我们所说的目标.make all命令,就告诉make我们将执行all所指定的目标.为了便于理解Make程序的流程,我们给大家看一个与gcc毫无关系的Makefile文件:
#Makefile begin
all:
@echo you have typed command "make all"
clean:
@echo you have typed command "make clean"
install:
@ehco you have typed command "make $@"
#Makefile end
注意在这里,all:、clean:、install:行要顶格些,而所有的@echo前要加tab键来跳格缩进.下面是运行结果
[root@xxx test]#make all
you have typed command "make all"
[root@xxx test]#make clean
you have typed command "make clean"
[root@xxx test]#make install
you have typed command "make install"
二、基本gcc编译命令
1、源程序的编译
在Linux下面,使用GNU的gcc编译器编译一个C语言的源程序.下面我们简单介绍几个常用的Gcc编译命令和参数,这里不是讲解Gcc的使用,只是介绍简单的基础知识是我们能看懂一般的makefile文件.
我们先看一个使用gcc编译器的实例.假设我们有下面一个非常简单的源程序(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux\n");
}
要编译这个程序,我们只要在命令行下执行: gcc -o hello hello.c
gcc 编译器就会为我们生成一个hello的可执行文件.执行./hello就可以看到程序的输出结果了.命令行中 gcc表示我们是用gcc来编译我们的源程序,-o 选项表示我们要求编译器给我们输出的可执行文件名为hello 而hello.c是我们的源程序文件.
gcc的基本格式就是:
gcc [-option] objectname sourcename
其中-option是参数,用来控制gcc的编译方式,常见的参数有如下几个:
-o 表示我们要求输出的可执行文件名:-o binaryname
-c 表示我们只要求编译器进行编译,输出目标代码,而不进行连接: -c objectivename.o
-g 表示我们要求编译器在编译的时候提供我们以后对程序进行调试的信息: -g
-O2 表示我们希望编译器在编译的时候对我们的程序进行一定程度的优化.2表示我们优化的级别是2.范
围是1-3.不过习惯上我们都使用2的优化级别.
-Wall是警告选项,表示我们希望gcc在编译的时候,让gcc输出她认为的一些程序中可能会出问题的一些警
告信息,比如指针没有初始化就进行赋值等等一些警告信息.
-l 与之紧紧相连的是表示连接时所要的链接库,比如多线程,如果你使用了pthread_create函数,那么 你就应该在编译语句的最后加上"-lpthread","-l"表示连接,"pthread"表示要连接的库,注意他们 在这里要连在一起写.如:gcc -o test test1.o test2.o -lpthread
-I 表示将系统缺省的头文件路径扩展到当前路径,默认的路径保存在/etc/ld.conf文件中。
gcc的例子:
gcc -c test.c,表示只编译test.c文件,成功时输出目标文件test.o
gcc -o test test.o,将test.o连接成可执行的二进制文件test
gcc -o test test.c,将test.c编译并连接成可执行的二进制文件test
gcc -c test.c -o test.o ,与上一条命令完全相同
gcc test.c -o test,与上一条命令相同
gcc -c test1.c,只编译test1.c,成功时输出目标文件test1.o
gcc -c test2.c,只编译test2.c,成功时输出目标文件test2.o
gcc -o test test1.o test2.o,将test1.o和test2.o连接为可执行的二进制文件test
gcc -c test test1.c test2.c,将test1.o和test2.o编译并连接为可执行的二进制文件test
2、程序库的链接
试着编译下面这个程序
/* temp.c */
#include
int main(int argc,char **argv)
{
double value =15;
printf("Value:%f\n",log(value));
}
这个程序相当简单,但是当我们用 gcc -o temp temp.c 编译时会出现下面所示的错误.
/tmp/cc33Kydu.o: In function `main':
/tmp/cc33Kydu.o(.text+0xe): undefined reference to `log'
collect2: ld returned 1 exit status
出现这个错误是因为编译器找不到log的具体实现.虽然我们包括了正确的头文件,但是我们在编译的时候还是要连接确定的库.在Linux下,为了使用数学函数,我们必须和数学库连接,为此我们要加入 -lm 选项. gcc -o temp temp.c -lm这样才能够正确的编译.也许有人要问,前面我们用printf函数的时候怎么没有连接库呢?是这样的,对于一些常用的函数的实现,gcc编译器会自动去连接一些常用库,这样我们就没有必要自己去指定了. 有时候我们在编译程序的时候还要指定库的路径,这个时候我们要用到编译器的 -L选项指定路径.比如说我们有一个库在 /home/hoyt/mylib下,这样我们编译的时候还要加上 -L/home/hoyt/mylib.对于一些标准库来说,我们没有必要指出路径.只要它们在起缺省库的路径下就可以了.系统的缺省库的路径/lib、/usr/lib、/usr/local/lib(你可以查看你的/etc/ld.conf文件来看看你的系统指定了那几个缺省的路径) 在这三个路径下面的库,我们可以不指定路径.
还有一个问题,有时候我们使用了某个函数,但是我们不知道库的名字,这个时候怎么办呢?很抱歉,对于这个问题我也不知道答案,我只有一个傻办法.首先,我到标准库路径下面去找看看有没有和我用的函数相关的库,我就这样找到了线程(thread)函数的库文件(libpthread.a). 当然,如果找不到,只有一个笨方法.比如我要找sin这个函数所在的库. 就只好用 nm -o /lib/*.so|grep sin>~/sin 命令,然后看~/sin文件,到那里面去找了. 在sin文件当中,我会找到这样的一行libm-2.1.2.so:00009fa0 W sin 这样我就知道了sin在libm-2.1.2.so库里面,我用 -lm选项就可以了(去掉前面的lib和后面的版本标志,就剩下m了所以是 -lm). 如果你知道怎么找,请赶快告诉我,我回非常感激的.谢谢!
3、程序的调试
我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了.最常用的调试软件是gdb.如果你想在图形界面下调试程序,那么你现在可以选择xxgdb.记得要在编译的时候加入-g选项.关于gdb的使用可以看gdb的帮助文件.由于我很少使用这个软件,所以我也不能够详细的说出如何使用. 不过我不喜欢用gdb.跟踪一个程序是很烦的事情,我一般用在程序当中输出中间变量的值来调试程序的.当然你可以选择自己的办法,没有必要去学别人的.现在有了许多IDE环境,里面已经自己带了调试器了.你可以选择几个试一试找出自己喜欢的一个用.
4、头文件和系统求助
有时候我们只知道一个函数的大概形式,不记得确切的表达式,或者是不记得着函数在那个头文件进行了说明.这个时候我们可以求助系统.比如说我们想知道fread这个函数的确切形式,我们只要执行 man fread 系统就会输出着函数的详细解释的.和这个函数所在的头文件说明了. 如果我们要write这个函数的说明,当我们执行man write时,输出的结果却不是我们所需要的. 因为我们要的是write这个函数的说明,可是出来的却是write这个命令的说明.为了得到write的函数说明我们要用 man 2 write. 2表示我们用的write这个函数是系统调用函数,还有一个我们常用的是3表示函数是C的库函数.
三、简单Makefile文件的编写
1、Makefile文件的一般组成
(1)注释:
在Makefile中,任何以"#"起始的文字都是注释,make在解释Makefile的时候会忽略它们.
(2)转接下行标志:
在Makefile中,若一行不足以容纳该命令的时候.可在此行之后加一个反斜线(\)表示下一行为本行的延续
,两行应视为一行处理
(3)宏(macro)
宏的格式为: =
例如:
CFLAGS = -O -systype bsd43
其实make本身已有许多的default的macro,如果要查看这些macro的话,可以用make -p的命令.
宏主要是作为运行make时的一些环境变量的设置,比如制定编译器等。
CC 表示我们的编译器名称,缺省值为cc.
CFLAGS 表示我们想给编译器的编译选项
LDLIBS 表示我们的在编译的时候编译器的连接库选项.(我们的这个程序中还用不到这个选项)
(4)规则(Rules)
格式如下:
:
....
:
....
注意:需要顶格写,而需要在下一行tab之后写,由于其是一个批处理形式的文件,所以不
可以随便的换行写,被迫换行的时候要用上面的转接下行标志进行连接.
(5)符号标志及缺省规则
$@ 代指目标文件
$< 第一个依赖文件
$^ 所有的依赖文件
$? 为该规则的依赖
- 若在command的前面加一个"-",表示若此command发生错误不予理会,继续执行下去.
$(macro) 应用这个变量,可以自动的将定义的宏加以展开,并替换使用。
.c.o:
gcc -c $< 这个规则表示所有的 .o文件都是依赖与其相应的.c文件的.例如mytool.o依赖于mytool.c
再一次简化后的Makefile
main:main.o mytool1.o mytool2.o
gcc -o $@ $^
.c.o:
gcc -c $< -I.;
使用宏后进一步的简化Makefile可以是
CC=gcc
CFLAGS=-g -Wall -O2 -I.
main:main.o mytool1.o mytool2.o
.c.o:
2、依赖
我们现在提出这样一个问题:我如何用一个make命令将替代所有的make all, make install,make clean命令呢?当然我们可以象刚才那样写一个Makefile文件:
all:
@echo you have typed command "make all"
clean:
@echo you have typed command "make clean"
install:
@ehco you have typed command "make $@"
doall:
@echo you have typed command "make $@l"
@echo you have typed command "make all"
@echo you have typed command "make clean"
@ehco you have typed command "make install"
[root@xxx test]#make doall
you have typed command "make doall"
you have typed command "make all"
you have typed command "make clean"
you have typed command "make install"
在这里,doall:目标有4调语句,他们都是连在一起并都是由tab键开始的.当然,这样能够完成任务,但是太笨了,我们这样来写:
[root@xxx test]#cat Makefile
# #表示Makefile文件中的注释,下面是Makefile文件的具体内容
all:
@echo you have typed command "make all"
clean:
@echo you have typed command "make clean"
install:
@ehco you have typed command "make $@"
doall: all clean install
@echo you have typed command "make $@l"
相信大家已经看清了doall:的运行方式,它先运行all目标,然后运行clean目标,然后是install,最后是自己本身的目标,并且每个$@还是保持着各自的目标名称.效果大致是一样的。在这里,我们称all, clean, install为目标doall所依赖的目标,简称为doall的依赖.也就是你要执行doall,请先执行他们(all, clean, install),最后在执行我的代码.
注意依赖一定是Makefile里面的目标,否则你非要运行;一般写在最前边,而不是像这样写在最后边。
3、Makefile的编写
在Makefile中,一般采用引导的注释行开始;下边一般紧跟macro定义;接下来是标签(如上面的all、clean等);最后就是Makefile中最重要的是描述文件的依赖关系的说明.一般的格式是:
#describe
macro
label: label1,label2
label1:
:
label2:
:
......
我们来看一个例子:
/* main.c */
#include
#include
int main(int argc,char **argv)
{
mytool1_print("hello");
mytool2_print("hello");
}
/* mytool1.h */
#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif
/* mytool1.c */
#include
void mytool1_print(char *print_str)
{
printf("This is mytool1 print %s\n",print_str);
}
/* mytool2.h */
#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif
/* mytool2.c */
#include
void mytool2_print(char *print_str)
{
printf("This is mytool2 print %s\n",print_str);
}
因为我们在程序中使用了我们自己的2个头文件,而在包含这2个头文件的时候,我们使用的是<> 这样编译器在编译的时候会去系统默认的头文件路径找我们的2个头文件,由于我们的2个头文件不在系统能够的缺省路径下面,所以我们自己扩展系统的缺省路径,为此我们使用了-I.选项,表示将系统缺省的头文件路径扩展到当前路径.这样的话我们也可以产生main程序,而且也不是很麻烦.但是考虑一下如果有一天我们修改了其中的一个文件(比如说mytool1.c)那么我们难道还要重新逐一编译?也许你会说,这个很容易解决啊,我写一个SHELL脚本,让她帮我去完成不就可以了.但是当我们把事情想的更复杂一点,如果我们的程序有几百个源程序的时候,难道也要编译器重新一个一个的去编译? 为此,聪明的程序员们想出了一个很好的工具来做这件事情,这就是make.我们只要执行一下make,就可以把上面的问题解决掉.在我们执行make之前,我们要先编写一个非常重要的文件.--Makefile.对于上面的那个程序来说,可能的一个Makefile的文件是:
# 这是上面那个程序的Makefile文件
main:main.o mytool1.o mytool2.o
gcc -o main main.o mytool1.o mytool2.o
main.o:main.c mytool1.h mytool2.h
gcc -c main.c -I.
mytool1.o:mytool1.c mytool1.h
gcc -c mytool1.c -I.
mytool2.o:mytool2.c mytool2.h
gcc -c mytool2.c -I.
有了这个Makefile文件,不管我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译和我们修改的文件有关的文件,其它的文件她连理都不想去理的.
四、实例
1、实例一
一个非常简单的Makefile
假设我们有一个程式,共分为下面的部份:
menu.c 主要的程式码部份
menu.h menu.c的include file
utils.c 提供menu.c呼叫的一些function calls
utils.h utils.c的include file
同时本程式亦叫用了ncurses的function calls.
而menu.c和utils.c皆放在/usr/src/menu下.
但menu.h和utils.h却放在/usr/src/menu/include下.
而程式做完之后,执行档名为menu且要放在/usr/bin下面.
# This is the Makefile of menu
CC = gcc
CFLAGS = -DDEBUG -c
LIBS = -lncurses
INCLUDE = -I/usr/src/menu/include
all: clean install
install: menu
chmod 750 menu
cp menu /usr/bin
menu: menu.o
$(CC) -o $@ $? $(LIBS)
menu.o:
$(CC) $(CFLAGS) -o $@ menu.c $(INCLUDE)
utils.o:
$(CC) $(CFLAGS) -o $@ utils.c $(INCLUDE)
clean:
-rm *.o
-rm *~
在上述的Makefile中,要使用某个macro可用$(macro_name)如此的形式.make会自动的加以展开.
$@为该rule的Target,而$?则为该rule的depend.
若在command的前面加一个"-",表示若此command发生错误则不予理会,继续执行下去.
上述的Makefile的关系可以表示如下:
all
/ \
clean install
\
menu
/ \
menu.o utils.o
若只想清除source以外的档案,可以打make clean;若只想做出menu.o可以打make menu.o;若想一次全部做完,可以打make all或是make;要特别注意的是command之前一定要有一个TAB(即TAB键).
2、实例二
有了上面的说明,我们就可以开始写一些简单的Makefile文件了.比如我们有如下结构的文件:
tmp/
+---- include/
| +---- f1.h
| +----f2.h
+----f1.c #include "include/f1.h"
+----f2.c #include"include/f2.h"
+---main.c #include"include/f1.h", #include"include/f2.h"
要将他们联合起来编译为目标为testmf的文件,我们就可以按下面的方式写Makefile:
#Makefile,Create testmf from f1.c f2.c main.c
main: main.o f1.o f2.o
gcc -o testmf main.o f1.o f2.o
f1.o: f1.c
gcc -c -o file1.o file1.c
f2.o: f2.c
gcc -c -o file2.o file2.c
main.o
gcc -c -o main.o main.c
clean:
rm -rf f1.o f2.o main.o testmf
执行这个Makefile文件
[root@xxx test]make
gcc -c -o main.o main.c
gcc -c -o file1.o file1.c
gcc -c -o file2.o file2.c
gcc -o testmf main.o f1.o f2.o
[root@xxx test]ls
f1.c f1.o f2.c f2.o main.c main.o include/ testmf
如果你的程序没有问题的话,就应该可以执行了./testmf
这是一个很简单的例子,但复杂的例子都是构建在简单功能基础上的.后面将继续介绍详细的makefile的编写方法。
参考连接地址:
http://bbs.ee.ntu.edu.tw/boards/Programming/17/12.html
http://www.linuxeden.com/forum/blog/index.php?op=ViewArticle&blogId=102509&articleId=341
http://www.douzhe.com/bbs/viewtopic.php?t=376&highlight=make
- Make_File_Test.zip (8.3 KB)
- 下载次数: 0
发表评论
-
FreeRTOS
2022-03-05 16:31 268Ref https://blog.csdn.net/weix ... -
串口通讯相关
2018-11-02 13:44 437https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1377https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 501https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 602// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 623https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 6178583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 622参考link http://www.cnblogs.com/l ... -
2017 Google hosts
2017-06-08 08:30 14参考link https://laod.cn/hosts/20 ... -
BeagleBone Black安装mono开发环境
2017-05-17 08:49 692Installing Mono and C# on the B ... -
在linux 下怎么进入 /dev/sda1
2017-05-12 13:18 2238https://zhidao.baidu.com/questi ... -
[Ubuntu] 安装开发环境
2017-05-03 10:03 419安装gcc/g++ http://www.cnblogs.co ... -
C++实现ping功能
2017-04-18 11:21 2216基础知识 ping的过程是向目的IP发送一个type=8的I ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 9351 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1628OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1905ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 907转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1958转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 1122C++编写标准Win32DLL如下 头文件 /***** ...
相关推荐
内容概要:本文详细介绍了基于TMS320F系列芯片的C2000串口读写方案及其编程器——FlashPro2000的功能特点和支持的接口模式。文中不仅涵盖了硬件连接的具体步骤,还提供了代码实例来展示Flash擦除操作,并对比了JTAG和SCI-BOOT两种模式的优缺点。此外,针对不同型号的C2000系列芯片,给出了详细的适配指导以及避免烧录过程中可能出现的问题的方法。 适合人群:从事DSP开发的技术人员,尤其是对TI公司C2000系列芯片有一定了解并希望深入了解其编程和烧录细节的人群。 使用场景及目标:适用于实验室环境下的程序调试阶段,以及生产线上的批量烧录任务。主要目的是帮助开发者选择合适的编程工具和技术手段,提高工作效率,减少因误操作导致设备损坏的风险。 其他说明:文中提供的代码片段和命令行指令可以直接用于实际项目中,同时附带了一些实用技巧,如防止芯片变砖的小贴士和自动化重试脚本,有助于解决常见的烧录难题。
汉字字库存储芯片扩展实验 # 汉字字库存储芯片扩展实验 ## 实验目的 1. 了解汉字字库的存储原理和结构 2. 掌握存储芯片扩展技术 3. 学习如何通过硬件扩展实现大容量汉字字库存储 ## 实验原理 ### 汉字字库存储基础 - 汉字通常采用点阵方式存储(如16×16、24×24、32×32点阵) - 每个汉字需要占用32字节(16×16)到128字节(32×32)不等的存储空间 - 国标GB2312-80包含6763个汉字,需要较大存储容量 ### 存储芯片扩展方法 1. **位扩展**:增加数据总线宽度 2. **字扩展**:增加存储单元数量 3. **混合扩展**:同时进行位扩展和字扩展 ## 实验设备 - 单片机开发板(如STC89C52) - 存储芯片(如27C256、29C040等) - 逻辑门电路芯片(如74HC138、74HC373等) - 示波器、万用表等测试设备 - 连接线若干 ## 实验步骤 ### 1. 单芯片汉字存储实验 1. 连接27C256 EPROM芯片到单片机系统 2. 将16×16点阵汉字字库写入芯片 3. 编写程序读取并显示汉字 ### 2. 存储芯片字扩展实验 1. 使用地址译码器(如74HC138)扩展多片27C256 2. 将完整GB2312字库分布到各芯片中 3. 编写程序实现跨芯片汉字读取 ### 3. 存储芯片位扩展实验 1. 连接两片27C256实现16位数据总线扩展 2. 优化字库存储结构,提高读取速度 3. 测试并比较扩展前后的性能差异 ## 实验代码示例(单片机部分) ```c #include <reg52.h> #include <intrins.h> // 定义存储芯片控制引脚 sbit CE = P2^7; // 片选 sbit OE = P2^6; // 输出使能 sbit
测控装备干扰源快速侦测系统设计研究.pdf
嵌入式八股文面试题库资料知识宝典-【开发】嵌入式开源项目&库&资料.zip
嵌入式八股文面试题库资料知识宝典-百度2022年嵌入式面试题.zip
少儿编程scratch项目源代码文件案例素材-空间站.zip
基于关联规则的商业银行个性化产品推荐.pdf
嵌入式八股文面试题库资料知识宝典-Linux基础使用.zip
内容概要:本文详细介绍了利用MATLAB进行轴棱锥生成贝塞尔高斯光束及环形光束光强图像的仿真研究。首先阐述了实验的背景与目标,强调了MATLAB在光学和计算科学领域的广泛应用。接着,具体描述了实验的方法与步骤,包括材料准备、仿真过程中的参数设定和光束生成代码编写。最后,对实验结果进行了深入分析,展示了贝塞尔高斯光束和环形光束的光强分布特点,验证了其光学性能的预期表现。文章还对未来的研究方向和技术改进提出了展望。 适合人群:从事光学、物理学及相关领域研究的专业人士,特别是对光束生成和光学性能分析感兴趣的科研工作者。 使用场景及目标:适用于需要进行光束生成和性能分析的实验室环境,旨在帮助研究人员更好地理解和优化光束特性和传播行为。 其他说明:本文不仅提供了详细的实验方法和步骤,还附有丰富的实验结果和数据分析,为后续研究提供了宝贵的参考资料。
内容概要:本文探讨了三电平NPC型有源电力滤波器(APF)的模型预测控制(MPC)中存在的开关频率过高问题及其解决方案。传统MPC方法会导致极高的开关频率,增加了系统的能耗和热量。通过引入滞环控制模块,可以在不大幅牺牲性能的情况下有效降低开关频率。具体来说,滞环控制通过在价值函数计算后增加一个判断条件,对状态切换进行惩罚,从而减少不必要的开关动作。实验结果显示,开关频率从4392Hz降至3242Hz,降幅达26.2%,虽然电流总谐波畸变率(THD)略有上升,但仍符合国家标准。此外,文中还提出了动态调整滞环宽度的方法,以进一步优化不同负载条件下的表现。 适合人群:从事电力电子、电力系统控制领域的研究人员和技术人员,特别是关注APF和MPC技术的人群。 使用场景及目标:适用于需要优化APF系统开关频率的研究和工程项目,旨在提高系统效率并降低成本。目标是在不影响系统性能的前提下,显著降低开关频率,减少能量损失和热管理难度。 其他说明:文章不仅提供了理论分析,还包括具体的实现代码片段,有助于读者理解和实践。同时,强调了在实际应用中需要注意的问题,如中点电位漂移等。
内容概要:本文介绍了三维POD DMD程序在处理原网格数据方面的独特优势和技术细节。首先阐述了该程序能读取结构化和非结构化网格数据及其拓扑关系,在生成模态数据过程中保持原始网格形态而不需要进行网格插值操作。接着展示了简化版本的Python代码片段,揭示了读取网格数据和生成模态数据的核心逻辑。最后提到提供的辅助学习资料如代码、视频教程、Word教程和实例数据,帮助用户深入理解并掌握该程序的应用。 适合人群:从事计算流体力学领域的研究人员和技术爱好者,尤其是那些希望提高数据处理效率的人群。 使用场景及目标:适用于需要处理复杂网格数据的研究项目,旨在简化数据处理流程,提升工作效率,同时保持数据的原始特性。 其他说明:文中不仅提供了理论性的讲解,还有具体的代码示例和丰富的学习资源,使读者可以边学边练,快速上手。
融合双向路由注意力的多尺度X光违禁品检测.pdf
嵌入式八股文面试题库资料知识宝典-Linux_Shell基础使用.zip
嵌入式八股文面试题库资料知识宝典-联发科2021武汉嵌入式软件开发.zip
基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf
嵌入式八股文面试题库资料知识宝典-ARM常见面试题目.zip
基于LWR问题的无证书全同态加密方案.pdf
嵌入式八股文面试题库资料知识宝典-符坤面试经验.zip
内容概要:本文详细探讨了三电平逆变器在带不平衡负载条件下的仿真研究。主要内容包括仿真环境的搭建、不同拓扑结构的选择(如T型、I型NPC和ANPC)、延时相消法(DSC)和双二阶广义积分器(DSOGI)的正负序分离控制策略、SVPWM或SPWM调制技术的应用、双闭环PI控制以及直流均压控制。文中通过具体的参数设置(交流电压220V,直流侧电压750V)进行了详细的仿真实验,并展示了各个控制策略的效果。最终,通过仿真实验验证了所提出方法的有效性,确保了交流侧三相电压波形的对称性和电流波形的自适应调节。 适合人群:从事电力电子、电机驱动、新能源发电等领域研究的技术人员和研究人员。 使用场景及目标:适用于需要理解和掌握三电平逆变器在复杂负载条件下控制策略的研究人员和技术人员。目标是提高对三电平逆变器及其控制策略的理解,优化实际应用中的性能。 其他说明:本文不仅提供了理论分析,还包含了具体的仿真步骤和代码实现,有助于读者更好地理解和应用相关技术。
内容概要:本文介绍了如何使用Matlab/Simulink软件构建一个14自由度的四轮驱动-四轮转向(4WID-4WIS)整车动力学模型。该模型涵盖了整车纵向、横向、横摆、车身俯仰、侧倾、垂向跳动及四轮旋转和垂向自由度等多个方面,旨在全面反映车辆在不同工况下的动态行为。文中详细描述了各子系统的建模方法,包括转向系统、整车系统、悬架系统、魔术轮胎pac2002、车轮系统和PI驾驶员模块。同时,提供了Simulink源码文件、建模说明文档及相关参考资料,便于用户理解和应用。 适用人群:主要面向汽车工程师、研究人员以及对汽车动力学和Simulink建模感兴趣的学习者。 使用场景及目标:①帮助用户深入了解车辆在各种工况下的动态行为;②为车辆控制策略的制定提供理论支持和技术手段;③作为学习和研究整车动力学建模的有效工具。 其他说明:该模型采用模块化建模方法,提高了模型的清晰度和可维护性,同时也提升了建模效率。