【问题标题】:Undefined symbol on xcode with custom library for ios (definition of the symbol is there)带有 ios 自定义库的 xcode 上未定义的符号(符号的定义在那里)
【发布时间】:2012-08-30 13:53:00
【问题描述】:

我知道还有其他同名的问题,但没有一个问题与我相同。

我有两个项目。其中一个构建一个库,另一个构建一个使用该库的应用程序。

当我构建库时,一切正常。它创建一个包含库的 .a 文件。当我尝试构建第二个项目时,我收到以下消息:

Undefined symbols for architecture armv7:
  "_SPLite3_rtree_geometry_callback", referenced from:
      _register_spatialite_sql_functions in liblibspatialite.a(spatialite.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

那很糟糕。一开始不知道在说什么,后来研究了一下,发现这个库可能还没有为armv7建库,所以我用lipo命令查看架构:

lipo -info liblibspatialite.a

这会产生以下输出。

Non-fat file: liblibspatialite.a is architecture: armv7

好的,所以架构是正确的。然后呢?也许检查符合库的 .o 文件的符号。为此,我使用了 nm 命令:

nm spatialite.o | grep SPLite3_rt

产生以下输出:

U _SPLite3_rtree_geometry_callback

我查看了 nm 的联机帮助页,发现符号前的 U 表示它未定义。所以似乎就是这样。该符号显示为未定义。我在另一个工作区中有另一个版本的项目。我已经检查过了,它产生了一个工作库。 nm 命令在其他版本上返回以下内容:

0000e5f6 T _SPLite3_rtree_geometry_callback
0018c668 S _SPLite3_rtree_geometry_callback.eh

所以,有了这个库,它就可以正常工作了。我试图找到两个项目的构建选项的差异,但它们对我来说看起来是一样的。 如果我在项目属性的编译器部分中包含库的源文件,我可以使用库的第一个版本进行构建。 (选择目标 -> 构建阶段 -> 编译源),但我认为这不是使用库的重点。

所以,我想知道我该怎么做才能将 _SPLite3_rtree_geometry_callback 包含在库中。

提前致谢。

编辑:

更多信息。在spatialite.c中,有如下代码:

#define sqlite3_rtree_geometry_callback SPLite3_rtree_geometry_callback

SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
  const char *zGeom,
  int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
  void *pContext
);

编辑 2:

方法代码:

/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/

SQLITE_API int sqlite3_rtree_geometry_callback(
  sqlite3 *db,
  const char *zGeom,
  int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *),
  void *pContext
){
  RtreeGeomCallback *pGeomCtx;      /* Context object for new user-function */

  /* Allocate and populate the context object. */
  pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
  if( !pGeomCtx ) return SQLITE_NOMEM;
  pGeomCtx->xGeom = xGeom;
  pGeomCtx->pContext = pContext;

  /* Create the new user-function. Register a destructor function to delete
  ** the context object when it is no longer required.  */
  return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, 
      (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
  );
}

【问题讨论】:

  • spatialite.c 中的代码是一个声明。定义在哪里?
  • @JefferyThomas 代码在文件 sqlite3.c 中。我把它贴在 EDIT 2 下面。
  • 使用 nm 查看库中是否定义了 _sqlite3_rtree_geometry_callback。如果是这样,那么 sqlite3.c 中缺少#define sqlite3_rtree_geometry_callback SPLite3_rtree_geometry_callback
  • 如果我在 liblibspatialite.a 上使用 nm,@JefferyThomas _sqlite3_rtree_geometry_callback 不会出现在列表中;显示的是 U _SPLite3_rtree_geometry_callback;无论如何,我检查了 sqlite3.c 并在那里 #define sqlite3_rtree_geometry_callback SPLite3_rtree_geometry_callback
  • 不是很好。剩下的唯一事情是代码被有条件地排除在外,SQLITE_API 在两个文件中的定义不同。在SQLITE_API int sqlite3_rtree_geometry_callback( 之前查找#if... 可能排除该功能。确保SQLITE_API 对两个文件具有相同的定义。

标签: ios xcode linker


【解决方案1】:

检查spacialite.c 是否已添加到库的目标中。

【讨论】:

  • 是的,它已添加。实际上,该库仅由两个大文件组成。 spatialite.c 和 sqlite3.c
【解决方案2】:

你必须在预处理宏中指定 SQLITE_ENABLE_RTREE

【讨论】:

    【解决方案3】:

    好的。这看起来很奇怪,但看起来我终于修好了。一切都已正确定义,所以我不知道为什么它不起作用。

    我使用 xcode 目标首选项来定义预处理器宏。相反,我将 SQLITE_ENABLE_RTREE 更改为 .pch 文件,然后构建包含缺少的符号。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-07
      • 2020-02-26
      • 2014-01-20
      • 2016-02-24
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2023-04-10
      相关资源
      最近更新 更多