简单静态库与动态库的创建以及Makefile基本使用

1.linux中的动态库和静态库的区别:
静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库。 

动态库在程序编译时并不会被连接到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在。 
 
2.源程序包含:log.c  main.c(主程序)  log.h
将在下边贴出。

3-1.静态库的创建以及使用:

gcc  -c  log.c                 |生成 log.o 文件
ar  cr  libstatic.a  log.o     |创建静态库libstatic.a 并将 .o 问价链接到 .a 文件中
gcc  main.c  -L.  libstatic.a  log.h  -o  out    |-L:链接库  .:表示当前目录 后跟要链接的库和头文件, 生成可执行程序out
3-2.使用Makefile创建静态库
Makefile内容:
src=$(wildcard *.c)
obj=$(patsubst %.c, %.o, $(src))

test:libstatic.a edit
%.o:%.c
@ gcc -c $< -o $@
libstatic.a:$(obj)
@ar cr $@ $^
edit:$(obj)
@ gcc $^ -o $@
clean:
@ rm -rf *.o
.PHONY:clean
del:
@ rm -rf edit
.PHONY:del

4-1.动态库的创建以及使用:
        gcc -c -fPIC log.c    |生成位置无关的.o文件   -fPIC
gcc -shared -o libdynamic.so log.o   | 生成.so文件
        gcc main.c -L. libdynamic.so log.h -o out | 生成可执行程序out


  注意:结果出乎意料,编译的时候没问题,由于指定了-L.选项,编译器可以在当前目录下找

到libdynamic.so,而运行时却说找不到libdynamic.so
1.在运行out时通过环境变量LD_LIBRARY_PATH把当前目录添加到共享库的搜索
路径:LD_LIBRARY_PATH=. ./out
2.这是最常用的方法。把libdynamic.so所在目录的绝对路径(比如/home/akaedu/somedir)添加到/etc/ld.so.conf中(该文件中每个路径占一行),然后运行ldconfig
3.第三种方法就是把libdynamic.so拷到/usr/lib或/lib目录,这样可以确保动态链接器能找到这个共享
库。
4.在编译可执行文件out的时候就把libdynamic.so的路径写死在可执行文件中
4-2.使用Makefile创建动态库
Makefile内容:
src=$(wildcard *.c)
obj=$(patsubst %.c, %.o, $(src))


test:libdynamic.so edit
%.o:%.c
@ gcc -c -fPIC $< -o $@
libdynamic.so:$(obj)
@ gcc -shared -o $@ $^
edit:$(obj)
@ gcc $^ -o $@
clean:
@ rm -rf *.o
.PHONY:clean
del:
@ rm -rf edit
.PHONY:del

5.源代码

      1).  log.c

#include "log.h"
#include
#include
#define SIZE 1024L
#define LSIZE 0L

//#define ERR(...)  write_log(fd, __VA_ARGS__)
//#define DEB(...)  write_log(fd, __VA_ARGS__)

static int fd;
static struct stat sta;
static char buffer[15] = {0};
static char err[30] = "  ERR|发生错误\012";
static char deb[30] = "  DEB|调试正常";


/*#define write_log(...) do{\
    localtime_log();\
    int wr;\
    if((wr = write(fd, buffer, strlen(buffer))) < 0)\
            perror("write");\
    write(fd, err, strlen(err));\
    }while(0)
*/

long int stat_log(void)
{
    int st;
    if((st=fstat(fd, &sta)) == -1)
            perror("stat");

    return sta.st_size;
}

void localtime_log(void)
{
    time_t t;
    struct tm *tim;
    tim = localtime(&t);
    strcpy(buffer, "");
    sprintf(buffer, "扫描时间:%04d-%02d-%02d %02d:%02d:%02d", tim->tm_year+1947,
            tim->tm_mon+3, tim->tm_mday+4, tim->tm_hour, tim->tm_min, tim->tm_sec);

    return;
}

void ftruncate_log(void)
{
    int ftc;
    if((ftc = ftruncate(fd, 0L)) == -1)
        perror("ftruncate");
        char buf[40] = "日志\012\012日志内容\012------------------\012";
            write(fd, buf, sizeof(buf));
       
            localtime_log();
            int wr;
            if((wr = write(fd, buffer, strlen(buffer))) < 0)
                perror("write");
            write(fd, "\012", 1);


    return;
}

void errwr_log(void)
{
    localtime_log();
    int wr;
    if((wr = write(fd, buffer, strlen(buffer))) < 0)
        perror("write");
    write(fd, err, strlen(err));


    return;
}

void debwr_log(void)
{
    localtime_log();
    int wr;
    if((wr = write(fd, buffer, strlen(buffer))) < 0)
        perror("write");
    write(fd, deb, strlen(deb));

    return;
}

void open_log(const char* path)
{
     fd = open(path, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    if(fd < 0){
        perror("open");
       fd = open("log.t",  O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    }
    while(1){
    
        long int size = stat_log();
        if(size > SIZE){
            ftruncate_log(); 
        }

        else if (size == LSIZE){
             char buf[40] = "日志\012\012日志内容\012------------------\012";
             write(fd, buf, sizeof(buf));        
             localtime_log();
             int wr;
             if((wr = write(fd, buffer, strlen(buffer))) < 0)
                perror("write");
             write(fd, "\012", 1);

        }

        else{
            write(fd, "\012", 1);
            //ERR(err, strlen(err));
            //DEB(deb, strlen(deb));
            errwr_log();
            debwr_log();
        }

    }

    close(fd);
 
    return;
}

   2).  log.h

#ifndef  _LOG_H
#define
   _LOG_H
#include
 
#include
 
#include
 
#include
 
#include
 
#include
 
#include
 
void
 open_log ( const char *path ) ;
#endif

   3).  main.c

#include "log.h"

int main(void)
{
   open_log("log.t");

   return 0;
}

6.其中log.c涉及linux下的常用文件操作文件,内容是简单模拟日志。


你可能感兴趣的:(Linux_C编程)