C语言用GNU源码编译建构系统工具(GNU BUILD SYSTEM)编译创建动态库
- 首先看一下这篇博文:C语言数据结构之顺序结构(Sequence)
- 此次目的是将sequence.c改造一下,创建为一个动态链接库同时打包一个可发布的源码包,包括源码、头文件、测试文件!
创建工作目录
- 工作目录libmg(mg即muggles,一定要有一个自己的名称空间namespace)
工作目录结构如下所示:
libmg
\- Makefile.am
\- src
\- Makefile.am
\- sequence.c
\- libmg.h
\- mg
\- Makefile.am
\- types.h
\- sequence.h
\- tests
\- Makefile.am
\- test_seq.c
每个子目录下都编辑一个Makefile.am文件!!!
- 主目录libmg/Makefile.am内容如下:
SUBDIRS = src tests
- 源码目录libmg/src/Makefile.am内容如下:
SUBDIRS = mg
lib_LTLIBRARIES = libmg.la
libmg_la_SOURCES = libmg.h \
mg/types.h \
sequence.c mg/sequence.h
libmg_la_LDFLAGS = -release 1.0
include_HEADERS = libmg.h
nobase_include_HEADERS = \
mg/types.h \
mg/sequence.h
- 源码目录下子目录mg的libmg/src/mg/Makefile.am内容如下:
EXTRA_DIST = types.h sequence.h
- 测试目录tests/Makefile.am内容如下:
AM_CFLAGS = -I ../src -I .
AM_LDFLAGS = -L../src -lmg
check_PROGRAMS = test_seq
test_seq_SOURCES = test_seq.c
TESTS = $(check_PROGRAMS)
将源码sequence.c改造一下
- 主头文件libmg/src/libmg.h代码如下:
/* filename : libmg.h */
#ifndef __LIBMG_HEAD
#define __LIBMG_HEAD
#include "mg/types.h"
#include "mg/sequence.h"
#endif/*__LIBMG_HEAD*/
- 主源码文件libmg/src/sequence.c代码如下:
/* filename: sequence.c */
#include <stdio.h>
#include <stdlib.h>
#include "mg/sequence.h"
/* create a new sequence */
Sequence *
mg_sequence_new (int pagesize)
{
Sequence *seq = (Sequence*) malloc (sizeof(Sequence));
seq->pagesize = pagesize;
seq->pages = 1;
seq->size = 0;
seq->elts = (void**) malloc (seq->pages * seq->pagesize * sizeof(void*));
for (int i = 0; i < seq->pagesize; i++)
seq->elts[i] = NULL;
return seq;
}
/* free every elements */
void
mg_sequence_free_elements (Sequence *seq)
{
for (int i = 0; i < seq->size; i++)
free (seq->elts[i]);
}
/* free the sequence */
void
mg_sequence_free (Sequence *seq)
{
free (seq->elts);
free (seq);
}
/* sequence is empty return 1 else return 0 */
int
mg_sequence_is_empty (Sequence *seq)
{
if (seq->size == 0) return 1;
return 0;
}
/* sequence is full return 1 else return 0 */
/*int
mg_sequence_is_full (Sequence *seq)
{
if (seq->size == seq->maxsize) return 1;
return 0;
}
*/
/* get sequence size */
int
mg_sequence_size (Sequence *seq)
{
return seq->size;
}
/* append a val into sequence */
void
mg_sequence_append (Sequence *seq, void *val)
{
seq->elts[seq->size] = val;
seq->size = seq->size + 1;
if (seq->size == seq->pages * seq->pagesize)
{
seq->pages = seq->pages + 1;
seq->elts = realloc (seq->elts, seq->pages * seq->pagesize * sizeof(void*));
}
}
/* insert a val at idx into sequence */
void
mg_sequence_insert (Sequence *seq, int idx, void *val)
{
for (int i = seq->size - 1; i >= idx; i--)
seq->elts[i+1] = seq->elts[i];
seq->elts[idx] = val;
seq->size = seq->size + 1;
}
/* set a val at idx of sequence */
void
mg_sequence_set (Sequence *seq, int idx, void *val)
{
seq->elts[idx] = val;
}
/* remove a val at idx of sequence */
void
mg_sequence_remove (Sequence *seq, int idx)
{
for (int i = idx; i <= seq->size; i++)
seq->elts[i] = seq->elts[i+1];
seq->size = seq->size - 1;
}
/* get a val at idx of sequence */
void *
mg_sequence_get (Sequence *seq, int idx)
{
return seq->elts[idx];
}
/* reverse the sequence */
void
mg_sequence_reverse (Sequence *seq)
{
for (int i = 0, j = seq->size - 1; i < seq->size / 2; i++, j--)
{
void *tmp = seq->elts[i];
seq->elts[i] = seq->elts[j];
seq->elts[j] = tmp;
}
}
/* call mgfunc on each element */
void
mg_sequence_foreach (Sequence *seq, MgFunc mgfunc)
{
for (int i = 0; i < seq->size; i++)
mgfunc (seq