一个简单的Linux下编程例子
程序猿平时写的程序文件,比如C,或者Java的文件,叫做源文件。而电脑上能运行的软件,比如windows下的exe文件,叫做可执行文件。源文件不能直接变成可执行文件,要经过一个中间阶段,叫做点o文件(就是后缀名是.o的文件)。点o文件在windows下编程的时候我们是感觉不到的,因为windows下的编程环境,如visualstudio,会自动处理,替我们生成了.o文件,然后再自动生成exe文件,windows下编程只需要点一下按钮就完成了源文件到可执行文件的转变。
Linux下没有visualstudio这么厉害的编程工具,所以得自己操心这些细节。Linux下,程序员要指明从源文件怎么生成.o文件,然后从.o文件怎么生成可执行文件。这些规矩,都要写在一个叫做Makefile的文件里。
举个栗子,下面是一个完整的工程,ls命令看一下,有个叫做Makefile的文件:
在上面的例子中,所有的.o都是生成的中间文件,.cpp是C++的源文件,.h是C++的头文件,.cu是在GPU上执行的文件,gch是临时文件。
现在我们该打开一个文件看看里面的内容,先打开Makefile看看。Linux下,编辑文件的命令叫做vim。输入vimMakefile:
Makefile文件分成两部分,开头是变量定义,意思是说有些特别长的字符串,程序猿懒得每回都重写一遍,所以给他们重起个名字,以后用的时候用名字来代替就行。比如上面的例子中CC就是/usr/local/gcc481/bin/g++的名字。以后要用的时候,需要一个在美元符号后用花括号括起来,比如${CC}。上面那个栗子的前五行都是变量定义。
Makefile的第二部分是编译规则定义,定义的顺序跟真正执行的顺序是反着的,比如最后一步才是把所有的.o文件合并成可执行文件main,但在Makefile里要写在第一条,之后才解释各个.o文件是怎么生成的。每一个生成规则由两行组成。比如这个,表示要生成一个叫Sampl.o的文件:
第一行叫依赖关系,表示生成这个.o文件的时候,需要用到哪些别的文件,这里要用到Sample.cpp和Sample.h。第二行是编译规则,大家还记得变量CC的定义吧,他其实是指用存放在/usr/local/gcc481/bin这个文件夹下面的g++编译器的。所以这句话的意思是:用存放在/usr/local/gcc481/bin的g++编译器,把Sample.cpp和Sample.h两个文件,以–c为参数编译成一个.o文件。(-c是参数,意思是啥后面解释)。clean是一个比较特殊的“虚拟文件”,它的作用是,按照你的规定,清理掉一些中间文件,这就跟平时干完活了打扫卫生一样。
在本文的栗子里,clean“文件”把.o文件,.gch文件,和最终生成的可执行文件main都清理掉(放心,clean需要主动调用才会工作,所以不用担心它自动把可执行文件main删掉了,感觉跟白忙一场似的)。说到这里大家应该能大概明白Makefile的组成了。Makefile的东西其实很多,网上有一篇经典《跟我一起学makefile》,解释的很清楚,感兴趣的话可以搜搜看。
现在我们退出刚才用vim打开的Makefile,退出方法是先按Esc,然后“shift”和“;”键一起按,然后按q,回车。把“shift”和“;”键一起按下之后,窗口的最下面一行会清空,第一个字符变成“:”,表示等待进一步输入的意思。
现在输入make试试看结果。Make命令表示按照Makefile的要求,生成可执行文件。屏幕上会显示好几句话,里面的每句话都表示执行Makefile里的一条指令。如果程序有错误,或者有警告,都会在这里显示。下面就是执行栗子中Makefile的结果:
前五行,每行都是生成一个.o文件
其中前四行,用的是g++编译器,第五行用的是nvcc编译器(nvcc是编译GPU程序的编译器)
在用nvcc编译器编译Relief.cu文件的时候,系统发现了五个warning,这是GPU编程里的一个问题,不会影响程序正常运行,我们以后有空再解释它。最后一行是使用前面产生的.o文件,生成一个可执行文件main。
为了运行可执行文件,输入./main命令。(点-斜杠-main,一个都不能少),这表示运行程序,中间要停顿几秒钟,执行程序。输入完之后回车,然后系统会停顿几秒~
现在输入make clean,表示运行刚才Makfile里面的clean虚拟文件。结果是三类文件已经被删除了。
Linux下编程基本就是这个样子,基本顺序是写好各个文件->写好Makefile>用make命令生成可执行文件->运行。