linux一个c文件要引用另一个c文件中的函数编译的时候,应该怎么编译?

来源:互联网 发布:创建视图的sql语句代码 编辑:程序博客网 时间:2024/05/01 11:26

下面是unix环境高级编程中的第一程序:

文件名叫myls.c代码如下:

#include <sys/types.h>
#include <dirent.h>
#include "ourhdr.h"
int main(int argc, char *argv[])
{
        DIR *dp;
        struct dirent *dirp;
        if(argc!=2)
        err_quit("a single argument (the diretory name) is required");
        if((dp=opendir(argv[1]))==NULL)
        err_sys("cant't open %s", argv[1]);
        while((dirp=readdir(dp))!=NULL)
        printf("%s\n",dirp->d_name);
        closedir(dp);
        exit(0);
}


可以看到,上面的myls.c文件应用了我们自定的头文件ourhdr.h

代码如下:

#ifndef __ourhdr_h
#define __ourhdr_h


#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>


#define   MAXLINE 4096
#define   FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
#define   DIR_MODE (FILE_MODE|S_IXUSR|S_IXGRP|S_IXOTH)


typedef void Sigfunc(int);


#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR((Sigfunc*)-1)
#endif


#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))


char *path_alloc(int*);
int open_max(void);
void clr_fl(int,int);
void set_fl(int,int);
void pr_exit(int);
void pr_mask(const char*);
Sigfunc* signal_intr(int,Sigfunc*);


int tty_cbreak(int);
int tty_raw(int);
int tty_reset(int);
void tty_atexit(void);


#ifdef ECHO
struct termios *tty_termios(void);
#endif


void sleep_us(unsigned int);
ssize_t readn(int,void*,size_t);
ssize_t writen(int,const void * ,size_t);
int daemon_int(void);


int s_pipe(int*);
int recv_fd(int,ssize_t (*func)(int,const void*,size_t));
int send_fd(int,int);
int send_err(int,int,const char*);
int serv_accept(int,uid_t *);
int cli_conn(const char *);
int buf_args(char*, int (*func)(int,char**));


int ptym_open(char*);
int ptys_open(int,char*);
#ifdef TIOCGWINS2
pid_t pty_fork(int*,char*,const struct termios*,
const struct winsize*);
#endif
int lock_reg(int,int,int,off_t,int,off_t);
#define read_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLK,FRDLCK,offset,whence,len)


#define readw_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLKW,FRDLCK,offset,whence,len)
#define write_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLK,FWRLCK,offset,whence,len)
#define writew_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLKW,FWRLCK,offset,whence,len)
#define un_lock(fd,offset,whence,len) \
lock_reg(fd,F_SETLK,F_UNLCK,offset,whence,len)


pid_t lcok_test(int,int,off_t,int,off_t);


#define is_readlock(fd,offset,whence,len) \
lock_test(fd,F_RDLCK,offset,whence,len)


#define is_writelock(fd,offset,whence,len) \
lock_test(fd,F_wrLCK,offset,whence,len)


void err_dump(const char* ,...);
void err_msg(const char *,...);
void err_quit(const char *,...);
void err_ret(const char *,...);
void err_sys(const char *,...);


void log_msg(const char*,...);
void log_open(const char*,int,int);
void log_quit(const char*,...);
void log_ret(const char*,...);
void log_sys(const char*,...);


void TELL_WAIT(void);
void TELL_PARENT(pid_t);
void TELL_CHILD(pid_t);
void WAIT_PARENT(void);
void WAIT_CHILD(void);


#endif


同时,我们还引用了我们另外一个err_util.c中的函数err_quit和err_sys两个函数:

myls.c    ourhdr.h  err_util.c 都位于同一个目录下,我们在centos系统终端下,进入这个目录,

使用gcc -o myls myls.c err_util.c命令就可以编译myls.c文件,同时生成一个myls的可执行文件,该可执行文件就是和ls命令一样的效果。

执行./myls /home 就会列出/home下面的所有目录和文件!


下面是GCC的详细介绍

GCC

Linux下使用最广泛的C/C++编译器是GCC,大多数的Linux发行版本都默认安装,不管是开发人员还是初学者,一般都将GCC作为Linux下首选的编译工具。本教程毫不犹豫地使用GCC来编译C程序。

保存文件后退出,打开终端并 cd 到当前目录,输入下面的命令:
    gcc test.c -o test
可以直接将C代码编译链接为可执行文件。

可以看到在当前目录下多出一个文件 test,这就是可执行文件。不像Windows,Linux不以文件后缀来区分可执行文件,Linux下的可执行文件后缀理论上是可以任意更改的。

当然,也可以分步编译:

1) 预处理
    gcc -E test.c -o test.i
在当前目录下会多出一个预处理结果文件 test.i,打开 test.i 可以看到,在 test.c 的基础上把stdio.h和stdlib.h的内容插进去了。

2) 编译为汇编代码
    gcc -S test.i -o test.s
其中-S参数是在编译完成后退出,-o为指定文件名。

3) 汇编为目标文件
    gcc -c test.s -o test.o
.o就是目标文件。目标文件与可执行文件类似,都是机器能够识别的可执行代码,但是由于还没有链接,结构会稍有不同。

3) 链接并生成可执行文件
    gcc test.o -o test

如果有多个源文件,可以这样来编译:
    gcc -c test1.c -o test1.o
    gcc -c test2.c -o test2.o
    gcc test1.o test2.o -o test

注意:如果不指定文件名,GCC会生成名为a.out的文件,.out文件只是为了区分编译后的文件,Linux下并没有标准的可执行文件后缀名,一般可执行文件都没有后缀名。

编译后生成的test文件就是程序了,运行它:
    ./test
如果没有运行权限,可以使用sudo命令来增加权限(注意要在Linux的分区下):
    sudo cdmod test 777

对于程序的检错,我们可以用-pedantic、-Wall、-Werror选项:
  • -pedantic选项能够帮助程序员发现一些不符合 ANSI/ISO C标准的代码(并不是全部);
  • -Wall可以让gcc显示警告信息;
  • -Werror可以让gcc在编译中遇到错误时停止继续。
0 0
原创粉丝点击