首页 > 解决方案 > 架构 x86_64 的未定义符号:可能是什么原因

问题描述

使用 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);
}

标签: csqlitecmake

解决方案


sqlite3.h仅仅包含头文件是不够的。你需要要么

  • 链接到sqlite3 --lsqlite3在您的编译器/链接器命令中使用,或
  • sqlite3.c在您编译的源文件中包含“合并的”SQLite 源文件。

关于第二个选项,请参阅https://sqlite.org/amalgamation.html


推荐阅读