ubuntumake命令包 ubuntu-make
ubuntu不能使用make命令吗?
关于一个包括几百个源文件的应用程序,使用make和makefile工具就能够简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且这样多的源文件,假如每次都要键入gcc命令进行编译的话,那对程序员来讲简直算是一场灾难。而make工具则可自动完成编译工作,同时能够只对程序员在上次编译后修改过的部分进行编译。于是,有效的利用make和makefile工具能够大大提高项目开辟的效率。
在Ubuntu上做内核编程,要安装哪个包?如何做?
1、gcc(C编译器)
安装apt-getinstallgcc
2、make(源代码维护工具,它能自动检测出需要重新编译的源文件并依照你设定的编译规则去重新编译程序)
安装apt-getinstallmake
3.kernel-source(内核源码包。你能够apt-cachesearchkernel-source搜索到内核源代码包,并用uname-r命令查看到当前系统内核版本,然后用apt-getinstallkernel-source-xxxx来安装和你内核版本一致的内核源代码包)
假如你不想重新编译内核,内核源代码包kernel-source是彻底能够不下载的。
4.kernel-headers(内核源代码头文件包,无论你是要进行内核模块开辟依然进行驱动程序开辟,那个包基本上必须要安装的。因为作为一个内核模块编写者,通常会调用内核里的一些东西,比如内核头文件,内核数据结构申明等。它里面包含了一些关键的内核头文件)
安装apt-cachesearchkernel-headers
uname-r
apt-getinstakkkernel-headers-xxxx
5.kernel-kbuild(用来编译内核模块的,下载安装那个包后会发现在/usr/src目录下多了一个kernel-kbuild-xxxx开头的目录,下面惟独scripts一个目录,这是用来编译内核模块的一些脚本程序)
安装apt-cachesearchkernel-kbuild
uname-r
apt-getinstallkernel-kbuild-xxxx
6.build-essential(包含一个在建立deb包过程中起关键作用的包的信息列表,假如你不想建立deb包你就不需要安装此表)
安装apt-getinstallbuild-essential
7.kernel-package(假如你想把内核镜像做成一个deb包来用,那么必须用安装那个包了)
安装apt-getinstallkernel-package
8.initrd-tools(假如你想制作启动过程的initrd镜像,则那个包是必不可少的)
安装apt-getinstakkinitrd-tools
假设你编写了一个内核模块程序,源代码如下:
/*hello.c*/
#include
#include
#include
staticinthello_init(void)
{
printk(KERN_ALERT"Hello,linuxkernelmodule
");
return0;
}
ubuntumake命令包ubuntu-make
staticvoidhello_exit(void)
{
printk(KERN_ALERT"Goodbye,I'vecreatedalinuxkernelmodulesucessfully
");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
u3000你需要这此源程序编写一个makefile,内容如下:
#Makefileforhello.cfile
#
KERNEL_DIR:=/usr/src/linux
obj-m:=hello.o
default:
$(MAKE)-C$(KERNEL_DIR)SUBDIRS=$(PWD)modules
clean:
$(RM).*.cmd*.mod.c*.o*.ko-r.tmp
注意:这个地方的KERNEL_DIR是指内核源代码头文件所在目录的上一级目录,通常算是指内核源代码目录。该目录普通包括有arch,drivers,fs,include,init,ipc,kernel,lib,mm,net,scripts,usr,sound,security等目录。
在本示例中,/usr/src/linux是一个链接,指向了/usr/src/kernel-headers-2.6.8-3目录。
编写好makefile后就能够输入make命令生成hello.ko内核模块了,然后你能够用:
insmodehello.ko
命令来加入内核模块,然后用:
rmmodhello
来删除内核模块。
Ubuntu下面Makefile的使用办法
运行可执行文件hello
./hello
移除文件rmhello
编译文件得到可执行文件的并且,保留产生的中间文件
g++-save-tempshello_world.cpp-ohello
单个文件编译过程:
实际的编译过程:预处理,对应临时文件hello_world.ii
g++-Ehello_world.cpp-opreprocessed.ii
catpreprocessed.ii
预处理的工作要紧包含去掉注释,然后将我们include的库tack上,以上过程使我们自己主动调用预处理器的过程
cathello_world.ii
则展示了我们在第5)中编译时保留的中间文件,两者是一样的
实际的编译过程:这是真正的编译过程compilationstep,对应临时文件hello_world.s(assemblycode)
我们自己把.ii文件进行assemblycode得到.s的办法。
g++-Spreprocessed.ii-ocomplied.s
.s文件是高级语言和机器语言之间的中间环节
实际的编译过程:Assembly,将.s对应的assemblycode转换成.o对应的机器语言的过程,也叫machine-readablecode或者objectcode
让编译器将.s文件assembly起来
g++-ccomplied.s-oassembled.o
实际的编译过程:最后一步Linking,产生最终的可执行文件。
"Undefinedreference"errorsareprettymuchalwayslinkingerrors,andyouwillprobablyhavethem.Rememberthis.
我们经过连接一堆.o文件,得到.exe文件的过程,命令:
g++assembled.o-ohello_manual
多个文件编译过程:
举例,假如我们有定义一个class,然后我们的文件中包含dog.hpp,dog.cpp和main.cpp三个文件,然后我们只使用以下两个命令:
g++-cmain.cpp-omain.o
g++main.odog_program
的话就会出错,告诉我们undefinedreferenceofdog::bark()
因为关于不同的.cpp文件,都要生成一个objectfile,也算是.o文件。所以假如我们用以下命令:
g++-cmain.cpp-omain.o
g++-cdog.cpp
g++dog.omain.o-odog_program
的话,就可不能出错。
我们假如修改main.cpp中的内容的话,我们只需要重新用最后一个连接命令。然而,假如我们修改了dogclass本身的内容的话,例如添加一个函数,我们就需要重新产生objectfileofdog.cpp,然后重新连接。
对于Make的介绍
用自己常用的记事本创建一个Makefile,并注意大小写。在program对应的目录下面。
geditMakefile
Makefile里面语句的书写规则是
Target:tgt_dependency1tgt_dependency2……
Command
所以dog.o和main.o对应的语句分别是:
dog.o:dog.hppdog.cpp
g++-cdog.cpp
main.o:main.cpp
g++-cmain.cpp
在Makefile中Tab是很重要的,所以不要不记得在command对应的第二行加Tab
Makefile的编译顺序
假如Makefile中有如下语句
animal_assembly:moosegoosecat
command
moose:antlershoovesfur
command
goose:beakwingswebbed_feetinterest_in_bread
command
cat:whiskersevil_personality
command
我们能够看到animal_assembly的dependency是moosegoosecat。假如文件夹中存在moosegoosecat的话,make命令只需要执行第一句就能够了。假如文件夹中缺少moosegoosecat中的一个或者几个,make命令执行的时候,需要先找到moosegoosecat的生成办法,然后执行对应的命令,最后执行animal_assembly生成的命令。
moose:antlershoovesfur
command
animal_assembly:moosegoosecat
command
goose:beakwingswebbed_feetinterest_in_bread
command
cat:whiskersevil_personality
command
假如Makefille是以上形式的话,我们只运行make的话,Makefile会只执行第一句,因为第一句的dependency都存在了,所以只把moose生成的命令执行完就好了。假如我们要生成animal_assembly,就要运行命令makeanimal_assembly。所以,我们需要把最重要的命令,我们最重要生成的objectfile对应的命令放在第一行。
所以我们的dog_program的完整的Makefile文件应该是:
dog_program:dog.omain.o
g++dog.omain.o-odog_program
dog.o:dog.hppdog.cpp
g++-cdog.cpp
main.o:main.cpp
g++-cmain.cpp
在Makefile的最后写clean语句。
clean:
rmdog_program*.o
然后我们在命令窗口运行makeclean的话,就会删除文件夹中生成的可执行文件,和所有过程中产生的副产品。
关于Makefile中的dependencylist,我们需要将每个objectfile的dependencylist都写好。因为make不负责检查文件中的具体的语句,只负责执行Makefile中的语句。
dog_program:
g++dog.omain.o-odog_program
dog.o:dog.hppdog.cpp
g++-cdog.cpp
main.o:main.cpp
g++-cmain.cpp
假如像上面所示去掉dog_program的dependencylist的话,运行make就会出错,因为main是依赖于dog.cpp的。
假如文件中本身就存在dog.o和main.o的话,运行make可不能出错,因为make算是先checkdog.omain.o是否存在,存在的话就直截了当运行。
所以,我们假如修改了main.cpp或者dog.cpp的话,我们需要重新生成dog.o和main.o。因为make是无论那个咨询题的。
make那个命令的功能算是执行Makefile中我们要求执行的语句,对结果没有任何的预期,也可不能检查命令有没有咨询题。所以,我们必须遵守Makefile书写中的一些规则。
all:fill_file_with_nonsense
echo"Ihavemostlycreatedalotofjunktoday!"
fill_file_with_nonsense:create_file
echo"Hello,thereisnothingimportanthere">silly_file
create_file:
touchsilly_filetouch是Unix中的典型命令,用于生成空的文件
move_file:
mvsilly_filesilly_file_new_name
delete_file:
rm_file
open_file:
geditanother_silly_file
clean:
touchjunk1junk2junk3junk4junk5
really_clean:
rmjunk*
假如想体验的更加清晰,就能够运行那个文件中的内容,然后就明白make彻底可不能管结果是什么,不过没有脑子的执行命令。
解释上面的内容:
Makefile的书写规则。all:放在第一句,把所以我们要生成executable依赖的Targets列出来,如此我们需要的所有的文件都能够生成。我们看到all对应的dependency是file_file_with_nonsense,就去找file_file_with_nonsense的生成语句,发现它的dependency是create_file,然后去找create_file的生成语句,就到touchsilly_file,touch是Unix中的典型命令,用于生成空的文件。create_file的语句执行完之后,回到file_file_with_nonsense,执行echo"Hello,thereisnothingimportanthere">silly_file,就把"Hello,thereisnothingimportanthere"写入silly_file中,file_file_with_nonsense的语句也执行完之后,我们就返回到all,然后在命令行输出"Ihavemostlycreatedalotofjunktoday!"。
因为其他的target,不在all的dependencylist中,也不在all的dependency的dependency当中,所以只能经过maketarget的形式来调用对应的命令。
Marvelousmacros(宏)
一个宏的示例,宏算是Makefile中的variables,用来定义我们需要的操作,一些变量之类的
CXX=clang++
FLAGS=-O
hello:hello_world.cpp
$(CXX)$(FLAGS)$?-o$@
clean:
rmhello
CXX,这是一个预定义的宏,defaultvalue是g++。这个地方把CXX定义成clang++了。
FLAGS,这个地方定义的是-O。FLAGS也不一定非得定义成-o,也能够是somemoosehavelargeantlers,然而如此定义的话,就会导致调用的时候出错。
关于上面的文件,我们在命令行输入make的时候,实际运行的是clang++-Ohello_world.cpp-ohello。
假如我们把CXX=clang++这一行删掉的话,在命令行输入make,实际运行的算是g++-Ohello_world.cpp-ohello。
定义好macro宏,我们使用的时候,就要用$(MACRO)如此的形式,这是makefile语言的一种语法。我们注意到MACRO全部用的大写,尽管不是明确规定的,然而通常事情下用大写。
$?和$@是makefilelanguage里面非常的预定义的宏。$?是指的"namesofthedependencies(newerthanthetarget)",$@是指的"nameofthetarget"。
ComplierandlinerflagsinCS225
CXX=clang++LD=clang++
CXXFLAGS=-std=c++1y-stdlib=libc++-c-g-O0-Wall-Wextra-Werror-pedantic
LDFLAGS=-std=c++1y-stdlib=libc++-lpng-lc++abi
ubuntu执行了cmake后什么原因无法执行make
首先去官网下载安装包,选择“XX.tar.gz”源码安装包
输入如下命令
$tar-zxvfxx.tar.gz
$./bootstrap
$make
$makeinstall
输入以上命令后就差不多能够在ubuntu上安装好cmake
编写简单的cmake
使用cmake首先得有个CMakeList.txt文件,你需要把配置信息写在该文件中,然后经过cmake去处理该文件。
将设有下面一个main.cpp文件
//main.cpp文件
#include
usingnamespacestd;
intmain(){
cout<
return0;
}1234567
这时候我们就能够写个如下的CMakeList.txt文件
#cmake最小需要版本
cmake_minimum_required(VERSION2.8)
#项目名字
project(HELLOWORLD)
#包含原程序,即把给定目录下的源程序复制给变量DIR_SRC
aux_source_directory(DIR_SRC./)
#生成程序
add_executable(helloworld${DIR_SRC})1234567891011
然后执行如下命令
$mkdirbuild
$cdbuild
$cmake..
$make
$./helloworld
如此就编译好程序并运行。
添加静态库或者动态库
而假设我们程序用到了在/usr/lib下的一个静态库libmy.a,那就需要添加如下两个命令
#库所在位置
link_directories(/usr/lib)
#程序编译时候链接库
target_link_libraries(helloworldmy)12345
如何在ubuntu在编辑makefile文件
当我们写的程序文件比较少的时候,敲入gcc
/g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷。linux有一个自带的make命令,它让你的工作省去了很大的力气,然而你要学习怎么编写makefile文件。
makefile是一种特殊的文件格式,他将会帮你自动治理你的项目,很强大。
下面经过实例一步步说解怎么使用makefile。下面的四段代码。
[cpp]view
plaincopyprint?
/////main.cpp
#include"functions.h"
intmain()
{
print_hello();
cout< cout<<"Thefactorialof5is"< return0; } ///hello.cpp #include"functions.h" voidprint_hello() { cout<<"HelloWorld!"; } ///factorial.cpp #include"functions.h" intfactorial(intn) { if(n!=1) {return(n*factorial(n-1));} elsereturn1; } //functions.h void print_hello(); intfactorial(intn); /////main.cpp #include"functions.h" intmain() { print_hello(); cout< cout<<"Thefactorialof5is"< return0; } ///hello.cpp #include"functions.h" voidprint_hello() { cout<<"HelloWorld!"; } ///factorial.cpp #include"functions.h" intfactorial(intn) { if(n!=1) {return(n*factorial(n-1));} elsereturn1; } //functions.h void print_hello(); intfactorial(intn); 请将以上文件放到一个目录下。 请注意:我用的是g++进行编译的,你也能够按照你自己的选择来编译程序 make的作用 假如你运行:make命令, 它将会自动的在你的目录下寻找makefile文件,然后执行它,假如你几个makefile文件,你能够指定某一个特定的makefile文件 使用如下命令: make-fmymakefile 假如你想明白更多的make用法,能够执行manmake命令 执行过程 编译器将会编译你的源文件,然后输出目标文件 链接器执行目标文件然后创建一个可执行文件。 手动编译 最不理想的一种执行方式算是 g++main.cpphello.cppfactorial.cpp-ohello akefile基本规则 makefile的基本规则是有以下构成: target:dependencies [tab]systemcommand 利用以上语法编写如下 all: g++main.cpphello.cppfactorial.cpp-ohello 然后运行你的makefile,如下 make-fMakefile-1 如上代码叙述,所写的目标是all,all是makefile默认的目标,假如没有其他规定,make语法将要执行那个目标文件。 我们还发现,all目标并没有依赖的,所以按照命令让他安全的执行。 最后,make经过我们给的命令进行编译程序 使用依赖 这是因为,假如你修改一个单独的文件在你的项目,你不必重新编译一切,惟独你修改。请看下边的例子 [plain]view plaincopyprint? all:hello hello:main.ofactorial.ohello.o g++main.ofactorial.ohello.o-ohello main.o:main.cpp g++-cmain.cpp factorial.o:factorial.cpp g++-cfactorial.cpp hello.o:hello.cpp g++-chello.cpp clean: rm-rf*ohello all:hello hello:main.ofactorial.ohello.o g++main.ofactorial.ohello.o-ohello main.o:main.cpp g++-cmain.cpp factorial.o:factorial.cpp g++-cfactorial.cpp hello.o:hello.cpp g++-chello.cpp clean: rm-rf*ohello 我们看到目标all 惟独依赖,没有系统命令。为了去执行正确,它必须满足所有的目标所依赖的。目标都回去搜索所有的依赖,然后去执行它。 在例子中,我们看到了clean的目标,clean那个目标算是清晰中间生成的.o文件和那些可执行文件 使用变量和注释 当你写makefil文件的时候,当你想改变一些编译的一些选项的时候,他是特别有用处的。 [plain]view plaincopyprint? #这是注释,CC编译器. CC=g++ #CFLAGS是选项 CFLAGS=-c-Wall #目标文件 OBJECTS=main.ofactorial.ohello.o all:hello hello:$(OBJECTS) $(CC)main.ofactorial.ohello.o-ohello ubuntumake命令包ubuntu-make main.o:main.cpp $(CC)$(CFLAGS)main.cpp factorial.o:factorial.cpp $(CC)$(CFLAGS)factorial.cpp hello.o:hello.cpp $(CC)$(CFLAGS)hello.cpp clean: rm-rf*ohello #这是注释,CC编译器. CC=g++ #CFLAGS是选项 CFLAGS=-c-Wall #目标文件 OBJECTS=main.ofactorial.ohello.o all:hello hello:$(OBJECTS) $(CC)main.ofactorial.ohello.o-ohello main.o:main.cpp $(CC)$(CFLAGS)main.cpp factorial.o:factorial.cpp $(CC)$(CFLAGS)factorial.cpp hello.o:hello.cpp $(CC)$(CFLAGS)hello.cpp clean: rm-rf*ohello 你能够看到,使用这些有时候是特别有用的。你能够使用它们,赋值,当你想改变一些变量值的时候,然后你能够使用$(var), 来应用这些变量 怎么接着下去 经过以上简要的介绍,你就能够简要的去编写一些更加复杂的makefile来运行你的复杂的程序了。上边说的不过冰山一角 ,你能够经过差一些make的文档来写。 [plain]view plaincopyprint? CC=g++ CFLAGS=-c-Wall LDFLAGS= SOURCES=main.cpphello.cppfactorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all:$(SOURCES)$(EXECUTABLE) $(EXECUTABLE):$(OBJECTS) ubuntumake命令包ubuntu-make $(CC)$(LDFLAGS)$(OBJECTS)-o$@ .cpp.o: $(CC)$(CFLAGS){1}lt;-o$@ CC=g++ CFLAGS=-c-Wall LDFLAGS= SOURCES=main.cpphello.cppfactorial.cpp OBJECTS=$(SOURCES:.cpp=.o) EXECUTABLE=hello all:$(SOURCES)$(EXECUTABLE) $(EXECUTABLE):$(OBJECTS) $(CC)$(LDFLAGS)$(OBJECTS)-o$@ .cpp.o: $(CC)$(CFLAGS){1}lt;-o$@ 经过以上简要的介绍,你就能够简要的去编写一些更加复杂的makefile来运行你的复杂的程序了。上边说的不过冰山一角 ,你能够经过差一些make的文档来写。 ubuntu13.10_server版本make命令无法使用 make是不必单独安装的,要在ubuntu上进行程序编译首先要安装一个基础开辟包,也算是: sudoapt-getinstallbuild-essential 这包里包含了基本的开辟环境,也算是gcc,g++,固然也有make。 来源:今日热点