Reason: no main function in source file
pkg-config lib
e.g: pkg-config --cflags --libs dbus-1 glib-2.0 dbus-glib-1
gcc -o send-sms send-sms.c `pkg-config --cflags --libs dbus-1 glib-2.0 dbus-glib-1`
在库中有一个文件libxxx.pc.in,其中会定义它所提供的头文件在哪里,有哪些,其库链接方式是怎么样,库在哪里,当然这都是库安装到系统以后的信息,换句话说,可能对于编译环境是无意义的。
prefix=@PREFIX@ exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: library name Description: description goes here Requires: glib-2.0 gobject-2.0 Version: 0.1 Libs: -L${libdir} -llibrary_name Cflags: -I${includedir}/some_sub_dir
出现这种错误的时候通常是由于具体使用了某种类型,但此类型(到使用的时候)还仅有声明,未有定义。比如说,某个头文件有如下声明:
#ifndef __POINT_H #define__POINT_H typedef struct _Point Point; #endif
如果包含了此头文件的文件,可以使用Point去声明:
1).如声明函数时的形式参数,void print_point(Point p),注意是声明函数时,而不是定义函数
2). 声明指针:Point *p;
但是不能使用Point去定义变量,
1). 如定义变量,Point p;
2). 定义函数时的形参,void print_point(Point p) { ... }
3) .或者为其指针申请内在空间时,Point *point = (Point *) calloc(1, sizeof(Point));
会报出incomplete type的编译错误。因为这个时候需要Notification所占的内存大小和具体的定义形式,但是头文件中并没有给出具体的定义,所以编译器不知道此类型所需要的内存,所以会编译出错。
C++中也是如此,为了效率会Forward declaration,也即在使用某个类前,不具体指定其类,而是声明一个没有定义的类:
class Point;
Point a;
使用Foward declaration时,也只能用其去声明,而不能具体使用此类型。
所以,如果要具体使用某个类型时,其所包含的头文件中必须要有类型的具体定义:
#ifndef __POINT_H #define __POINT_H typedef struct _Point Point; struct _Point { int x; int y; }; #endif #include "point.h" Point *n = (Point *) calloc(1, sizeof(Point)); n->x = 1; n->y = 2; ....
其实,在头文件中仅声明类型的目的是为了信息隐藏,也就是不让调用者知道这个类型具体的定义是什么样子的,那么就需要像Java/C++中那样去定义这个类型,
1) 把类型声明为指针类型:
typedef struct Point *Point;
否则调用者还是有可能去定义。
2) 也即在头文件的对应源文件中封装操作此类型的所有方法,这样外界就没有必要去了解类型是如何定义的了。它想操作时,仅需要调用封装的方法即可。
典型的实例:
头文件point.h:
#ifndef __POINT_H #define __POINT_H typedef struct _Point *Point; Point make_point(); void print_point(Point point); void destroy_point(Point p); #endif
#include <string.h> #include <stdlib.h> #include <stdio.h> #include "point.h" struct _Point { int x; int y; }; Point make_point() { Point point = (Point) calloc(1, sizeof(struct _Point)); point->x = 0; point->y = 0; return point; } void print_point(Point point) { printf("point %d, %d\n", point->x, point->y); } void destroy_point(Point p) { if (p == NULL) { printf("warning, destroying NULL object"); return; } free(p); }