使用cmake编译C代码。尽管包含sqlite3.h
文件,但可能在我的一个目标文件中导致此错误的原因:
Undefined symbols for architecture x86_64:
"_sqlite3_close", referenced from:
_prv_temperature_read in object_temperature.c.o
"_sqlite3_column_double", referenced from:
_prv_temperature_read in object_temperature.c.o
"_sqlite3_errmsg", referenced from:
_prv_temperature_read in object_temperature.c.o
"_sqlite3_finalize", referenced from:
_prv_temperature_read in object_temperature.c.o
"_sqlite3_open", referenced from:
_prv_temperature_read in object_temperature.c.o
"_sqlite3_prepare_v2", referenced from:
_prv_temperature_read in object_temperature.c.o
"_sqlite3_step", referenced from:
_prv_temperature_read in object_temperature.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
编辑:
这是object_temperature.c
主类调用的完整lwm2mclient.c
对象。
#include "liblwm2m.h"
#include "lwm2mclient.h"
//..#include <sqlite3.0.tbd>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sqlite3.h>
//...#include <libsqlite3.dylib>
//Resource Id's
#define RES_SENSOR_VALUE 5700
#define RES_SENSOR_UNITS 5701
typedef struct _prv_instance_
{
struct _prv_instance_ * next;
uint16_t shortID;
double temp;
char unit[10];
} prv_instance_t;
static uint8_t prv_temperature_read(uint16_t instanceId,
int * numDataP,
lwm2m_data_t ** dataArrayP,
lwm2m_object_t * objectP)
{
prv_instance_t * targetP;
int i;
sqlite3 *db;
sqlite3_stmt *res;
int timer = 0;
targetP = (prv_instance_t *)lwm2m_list_find(objectP->instanceList, instanceId);
if (NULL == targetP) return COAP_404_NOT_FOUND;
fprintf(stderr, "----------------- Entering in oprv_temperature ----------------\n");
// connect to the backend
timer = time(NULL);
if (time(NULL) - timer > 60)
{
int rc = sqlite3_open("test.sqlite3", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
} else {
fprintf(stdout, "DB Connection Successful..\n");
}
rc = sqlite3_prepare_v2(db, "SELECT temperature_data FROM environment ORDER BY ID DESC LIMIT 1", -1, &res, 0);
if (rc != SQLITE_OK) {
fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
rc = sqlite3_step(res);
if (rc == SQLITE_ROW) {
double t;
fprintf(stdout, "Yeah, rc == SQLITE_ROW \n");
t = sqlite3_column_double(res, 0);
targetP->temp = t;
}
sqlite3_finalize(res);
sqlite3_close(db);
timer = time(NULL);
}
if(*numDataP == 0)
{
*dataArrayP = lwm2m_data_new(1);
if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR;
*numDataP = 1;
(*dataArrayP)[0].id = RES_SENSOR_VALUE;
(*dataArrayP)[1].id = RES_SENSOR_UNITS;
}
for (i = 0; i < *numDataP; i++)
{
switch((*dataArrayP)[i].id)
{
case RES_SENSOR_VALUE:
lwm2m_data_encode_float(targetP->temp, *dataArrayP +1);
break;
case RES_SENSOR_UNITS:
return COAP_405_METHOD_NOT_ALLOWED;;
default:
return COAP_404_NOT_FOUND;
}
}
return COAP_205_CONTENT;
}
lwm2m_object_t * get_object_temperature()
{
/*
* The get_object_temperature function create the object itself and return a pointer to the structure that represent it.
*/
lwm2m_object_t * temperatureObj;
temperatureObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t));
if (NULL != temperatureObj)
{
memset(temperatureObj, 0, sizeof(lwm2m_object_t));
/*
* Assigns it's unique ID 3303
*/
temperatureObj->objID = LWM2M_TEMPERATURE_OBJECT_ID;
/*
* and its unique instance
*
*/
temperatureObj->instanceList = (lwm2m_list_t *)lwm2m_malloc(sizeof(lwm2m_list_t));
if (NULL != temperatureObj->instanceList)
{
memset(temperatureObj->instanceList, 0, sizeof(lwm2m_list_t));
}
else
{
lwm2m_free(temperatureObj);
return NULL;
}
/*
* And the private function that will access the object.
* Those function will be called when a read/write/execute query is made by the server. In fact the library don't need to
* know the resources of the object, only the server does.
*/
temperatureObj->readFunc = prv_temperature_read;
//deviceObj->discoverFunc = prv_device_discover;
//deviceObj->writeFunc = prv_device_write;
//deviceObj->executeFunc = prv_device_execute;
//temperatureObj->userData = lwm2m_malloc(sizeof(prv_instance_t));
}
return temperatureObj;
}
void free_object_temperature(lwm2m_object_t * objectP)
{
if (NULL != objectP->userData)
{
lwm2m_free(objectP->userData);
objectP->instanceList = NULL;
}
if(NULL != objectP->instanceList)
{
lwm2m_free(objectP->instanceList);
objectP->instanceList = NULL;
}
lwm2m_free(objectP);
}
答案 0 :(得分:2)
仅包含sqlite3.h
头文件是不够的。您需要
sqlite3
库-在编译器/链接器命令中使用-lsqlite3
,或者sqlite3.c
。关于第二个选项,请参见https://sqlite.org/amalgamation.html。