重温C编译链接过程[环境:UNIX-CENTER提供的公共fedora]

在CSDN上看到了UNIX-CENTER提供的UNIX公用平台,于是下载了SSH软件,尝试了一下,感觉很好。
一方面,让我们体会了一下使用多核系统的感觉;更重要的方便了对安装UNIX望而却步的和我一样的人,呵呵,着实不错!

很就没有编写C程序,在UNIX下就更是没有经历。于是开始了Hello world!
1. 安装
在solaris下开发C应用程序,缺省开发环境是Sun Studio。UNIX-CENTER已经在服务器上安装了开发工具。其中C程序的编译工具名称为cc。还有的就是make这个命令,make命令是Solaris安装后就自带了。
2. 环境变量
开始编写代码前,要先配置环境变量(如果没有配置过的话)。需要把编译器和make的路径加入到环境变量PATH中去,一般来说,可以使用export命令来进行这个方面的设置。假设您使用的shell为Bourne shell,Sun Studio 11的安装目录为/opt/SunStudio_11/SUNWspro,make通常安装在/usr/ccs/bin目录下,则可以使用如下命令进行设置:
# PATH=/opt/SunStudio_11/SUNWspro/bin:/usr/ccs/bin:$PATH
# export PATH
3. 例子
a. 只有一个文件的简单程序
// hello.c

#include <stdio.h>
int main()    // must return "int" type, why can't be "void"
{
 printf(”Hello World/n”);
 // return 0;   // need or not
}

编译:
cc -o hello hello.c

make hello  // 相当于 cc hello.c -o hello 仅用于编译一个文件,后面的参数是c源程序的文件名的"."前面的部分

b. 包含多个文件的c应用程序
// hello.h
void hello();

// hello.c
#include "hello.h" // 不能用< >
int main()
{
 hello();
}

// hello_f.c
void hello()
{
 printf("Hello World!/n");
}

编译:
cc -o hello hello_f.c hello.c
或:
cc -c hello.c
cc -c hello_f.c
ld -o hello -lc hello.o hello_f.o

在实际项目中,原文件数量往往很多。如果只是用简单的命令去编译这些文件,不但每次要写一堆命令,而且容易出错,难于保持编译选项的一致。用makefile来做相应的编译组织和管理可以解决以上问题。

4. 使用makefile开发程序
先回顾一下编译链接过程:源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。

makefile带来的好处就是——“自动化编译”,它关系到了整个工程的编译规则。编写好makefile文件后,用make命令执行整个工程的编译工作。
make的执行规则是:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

makefile文件的格式:
target ... : prerequisites ...
 command
...
  ...

    target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
    prerequisites就是,要生成那个target所需要的文件或是目标。
    command也就是make需要执行的命令(注意:命令行开始位置为一个TAB,否则执行时会提示:缺少分隔符)。(任意的Shell命令)

采用3中“包含多个文件的c应用程序”的例子,makefile文件如下:
all:hello

hello:hello.o hello_f.o
 cc -o hello hello.o hello_f.o
hello.o
 cc -c hello.c
hello_f.o
 cc -c hello_f.c
clean:
 rm -f *.o hello

输入命令"make"或者"make all"就可以生成执行文件hello。如果要删除执行文件和所有中间文件,那么输入命令"make clean"就可以了。

在这个makefile中,目标文件(target)包含:执行文件edit和中间目标文件(*.o),依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。

在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。

这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。

 

你可能感兴趣的:(c,unix,object,Solaris,makefile,编译器)