在iOS上使用LLVM编译时,Sqlite FTS不起作用

在iOS上使用LLVM编译时,Sqlite FTS不起作用,ios,sqlite,full-text-search,llvm,Ios,Sqlite,Full Text Search,Llvm,我已经开发了一段时间的企业级iPad应用程序。由于应用程序开发大约在2年前开始,我需要从源代码处编译自己的版本SQLite,因为默认的SQLite库sqlite3.dylib在默认情况下没有启用FTS 好的,从那以后一切都很顺利。我一直使用GCC作为项目编译器 问题是,现在我正试图将我的整个项目转换为使用。为此,我需要使用苹果的编译器 就这样。当我将编译器从GCC 4.2更改为LLVM 3.1或4.0时,没有转换为ARC,也没有更改任何其他内容,我的应用程序构建良好,一切正常运行,除了我的FTS

我已经开发了一段时间的企业级iPad应用程序。由于应用程序开发大约在2年前开始,我需要从源代码处编译自己的版本SQLite,因为默认的SQLite库sqlite3.dylib在默认情况下没有启用FTS

好的,从那以后一切都很顺利。我一直使用GCC作为项目编译器

问题是,现在我正试图将我的整个项目转换为使用。为此,我需要使用苹果的编译器

就这样。当我将编译器从GCC 4.2更改为LLVM 3.1或4.0时,没有转换为ARC,也没有更改任何其他内容,我的应用程序构建良好,一切正常运行,除了我的FTS查询,即使是最简单的查询也无法工作。不过,它们运行并返回SQLITE_OK代码时总是没有结果

我被困在这里了。我已经和WWDC'12的一位苹果工程师谈过了,但我们找不到任何解决方案

我保证它不太可能是一个格式错误的查询或类似的东西,因为该应用程序与GCC配合良好。此外,我还可以在SQLite的终端版本上运行查询,或者使用其他应用程序,比如Base

我还使用了一个旧版本的SQLite,但是我已经更新到了最新的版本3.7.13。一切都一样。我还注意到,现在我不知道从什么时候起,mac附带的sqlite支持FTS!!!我可以删除自己的版本,使用苹果的版本。问题是,我有着完全相同的行为

我一直在寻找解决方案,但找不到。我发现了一些与armv6和编译器优化相关的bug,这些bug可以通过使用-mno thumb标志来修复,但这不是我的情况。我还注意到,当我使用Clang分析自定义sqlite文件时,它指出了许多潜在的错误

我有这种非怀疑的观点,我仍然不相信这是一个LLVM或SQLite错误。我更喜欢在解决bug之前检查所有可能的事情。也许我忘记了配置一些东西,或者需要向编译器添加一些我没有做的标记

谢谢你的帮助。同样,该错误只发生在使用LLVM编译的项目上,即使使用默认sqlite也是如此。如果我在sqlite3的终端版本上运行相同的查询,一切都会正常进行

更新:

这个代码有效。它使用fts创建一个新的数据库和一个新的虚拟表,插入两个项目,然后执行select。稍后我将尝试更复杂的查询,但目前看来,我的应用程序的问题可能是,正如预期的那样,我的代码中有一个bug

NSArray *dirPaths = dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
sqlite3 *database;

// Build the path to the database file
NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent: @"test.db"]];

NSFileManager *filemgr = [NSFileManager defaultManager];
NSError *error = nil;
[filemgr removeItemAtPath:databasePath error:&error];

const char *dbpath = [databasePath UTF8String];

if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
    char *errMsg;
    const char *sql_stmt = "CREATE VIRTUAL TABLE IF NOT EXISTS pages USING fts3(title, body);";

    if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
    {
        NSLog(@"Failed to create table");
    } else {

        sql_stmt = "INSERT INTO pages(docid, title, body) VALUES(53, 'Home Page', 'SQLite is a software...');";
        if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
        {
            NSLog(@"Failed to insert");
        }

        sql_stmt = "INSERT INTO pages(title, body) VALUES('Download', 'All SQLite source code...');";
        if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
        {
            NSLog(@"Failed to insert");
        }
    }

    sqlite3_stmt *statement;
    const char *query_stmt = "select * from pages where body match 'soft*';";

    if (sqlite3_prepare_v2(database, query_stmt, -1, &statement, NULL) == SQLITE_OK)
    {
        if (sqlite3_step(statement) == SQLITE_ROW)
        {
            NSLog(@"%@ - %@", [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)],
                  [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)]);
        } else {
            NSLog(@"no results");
        }
        sqlite3_finalize(statement);
    }

    sqlite3_close(database);

} else {
    NSLog(@"Failed to open/create database");
}

毕竟,我已经找到了bug。这是我的密码。总之,我发现: 如果我有这样的事情,我知道这很奇怪/错误:

int a = 0;
a = a++;
NSLog(@"%d", a);
如果使用gcc编译此代码,则记录的值为1;如果使用llvm编译,则记录的值为0


我不知道为什么,但这是另一个问题:

您是否尝试将sqlite3放在单独的静态库中,并使用llvm gcc而不是clang编译此库?那能用吗?是的,我有。有趣的是,如果我这样做,同样的问题也会发生。如果我用Clang编译静态SQLite库,然后用GCC编译整个项目,它就会工作。我不知道这背后的逻辑在哪里。也许是你的代码中的一些内存损坏是由铿锵编译器触发的,但gcc编译器生成的代码不会触发内存损坏。是的,苹果的工程师就是这么说的。但问题是我只是在尝试一个简单的查询。本周晚些时候,我将分享一个简单的项目,举例说明我的问题。非常感谢您的回复!这看起来像是对旧编译器的错误修复。如果您有a=++a,它将按预期工作。