windows环境编译xapian库

目录

一、安装环境 

二、编译zlib,生成相关文件

        生成32位的lib

        生成64位的lib

        zdll.lib与zlib.lib的区别:

三、编译生成xapian静态库(Release版),生成相关文件

        准备环境

        生成32位的xapian库

        生成64位的xapian库

四、举个栗子


一、安装环境 

操作系统win11专业版64位操作系统
VS版本VS2017Enterprise,版本15.8.8,
xapian-core版本1.4.21历史版本路径:Index of /xapian
zlib版本1.2.11历史版本路径:Index of /fossils
msys版本msys2-x86_64-20221028.exe

二、编译zlib,生成相关文件

    下载并解压zlib源代码文件。
        生成32位的lib
    1、设置msvc的32位命令行运行环境 找到vs的vcvars32.bat文件,我的VS2017的 vcvars32.bat文件 路径:\VS2017\VC\Auxiliary\Build\,进入此目录, 在此目录的窗口的地址栏中输入"cmd",弹出命令行窗口。 在CMD窗口中输入vcvars32.bat。不要直接双击 vcvars32.bat文件,那样CMD窗口会自动关闭。   因为这几个步骤后面要经常做,写了个脚本如下(命名:vs_x86.bat,可以直接双击):
call "C:\VS2017\VC\Auxiliary\Build\vcvars32.bat"
cmd /k
puase

    2、msvc的32位命令行环境中编译、链接、生成zlib库 继续在上面的CMD窗口中进入zlib源代码目录,输入如下命令,在zlib源代码目录会生成zlib.dll、zlib.lib文件: 

nmake -f win32/Makefile.msc

 注意:zlib1.2.5版本用上面面命令会报错 , zlib1.2.8版本也有一点小错误,需要额外处理。  

        生成64位的lib
        1、 设置msvc的64位命令行运行环境 :方法同32位lib编译方法,只是运行文件为 vcvars64.bat 文件。也可以同上文写一个脚本文件(vs_x64.bat)。
call "C:\VS2017\VC\Auxiliary\Build\vcvars64.bat"
cmd /k
puase

        2、msvc的64位命令行环境中编译、链接、生成zlib库:在cmd输入命令如下:

nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"
          上述命令执行完成后,在源代码目录下会生成一堆的.obj文件,.pdb文件,还有.exe文件,最主要的还有 zdll.lib,zlib.lib,zlib1.dll ,在磁盘其他地方建立一个名为 zlib-1.2.11-lib64 的目录用于存放头文件和库文件(此目录后续有用,我建在c盘根目录 C:\zlib-1.2.11-lib64 ),此目录下再建一个include目录(将1.2.11源代码目录中的 zconf.h、zlib.h 文件拷贝到此目录),建一个lib目录(将 源代码目录中刚生产的zdll.lib,zlib.lib,zlib1.dll文件拷贝到此目录 )。
        下面编写一个脚本文件自动实现编译生成32位zlib库,首先用文本编辑器打开源代码中.\win32\Makefile.msc文件,将文件中 -del *.pdb一行删除。然后运行下面脚本文件。
REM 文件名:vs2017-32zlib.bat,将此文件放到zlib源代码目录的根目录,然后运行此脚本即可生成相应的ZLIB库文件
@REM 这是我的VS2017中vcvars32.bat的全路径
set VS= "C:\VS2017\VC\Auxiliary\Build\vcvars32.bat"
@REM 设置输出路径,将会自动生成此目录,并且会生成bin、lib、include、pdb目录,程序运行完成后,会将生成的.dll、.lib、.pdb、还有程序所需要包含的.h文件都会拷贝到这些目录
set OUT="C:\zlib-1.2.11-lib32"
call %VS%
@REM 下面这两行代码,64位的zlib与32位的不同
nmake /f win32/Makefile.msc clean
nmake /f win32/Makefile.msc
md %OUT%\lib
md %OUT%\bin
md %OUT%\include
md %OUT%\pdb
copy /Y *.lib %OUT%\lib
copy /Y *.h %OUT%\include
copy /Y *.dll %OUT%\bin
copy /Y *.exe %OUT%\bin
copy /Y *.pdb %OUT%\pdb
del *.pdb
pause
        自动生成64位zlib库的脚本略有不同,下面只列出不同的部分  
nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"  clean
nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" 
        zdll.lib与zlib.lib的区别:
在编译 zlib 库时生成的 zdll.lib zlib.lib 文件之间的区别在于它们对于库的链接方式和使用环境的不同:
  • zdll.lib
    • 这是用于链接动态链接库(DLL)的导入库文件,与之相关联的为zlib.dll。当您编译动态链接版本的 zlib 库时,会生成这个文件。
    • 它包含了在运行时加载并使用 zlib.DLL 的相关信息,允许您在编译时将应用程序与 zlib.DLL 进行链接。应用程序运行时,需要将对应的zlib.dll放到与应用程序相同的目录。
    • 如果您的应用程序需要在运行时动态加载 zlib 库,通常需要使用 zdll.lib 文件。
  • zlib.lib    
    •  这是用于链接静态链接库(Static Library)的库文件。当您编译静态链接版本的 zlib 库时,会生成这个文件。
    • 它包含了 zlib 库的所有功能,以便在编译时将这些功能直接嵌入到您的应用程序中。
    • 如果您的应用程序需要在编译时将 zlib 的功能静态链接到应用程序中,通常需要使用 zlib.lib 文件。
总之, zdll.lib 用于链接动态链接版本的 zlib 库,而 zlib.lib 用于链接静态链接版本的 zlib 库。您应该根据您的应用程序的需要选择适当的库文件进行链接。

三、编译生成xapian静态库(Release版),生成相关文件

        准备环境
        1、下载xapian源代码:下载地址见本文第一章节,下载后解压即可。
        2、安装msys2环境:
msys2此网址保持着最近10几个版本,随便装一个即可,安装后,根目录会出现mingw32与mingw64两个空目录msys2-distrib-x86_64安装包下载_开源镜像站-阿里云
MinGW32下载i686-win32-sjlj或者i686-win32-dwarf解压后替换msys2安装目录下的mingw32与mingw64两个空目录https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds
MinGW64下载x86_64-win32-sjlj或者x86_64-win32-sehhttps://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds
运行msys2,在msys2窗口下运行如下命令,安装make,默认情况下是随msys2环境已经安装好了的。   
pacman -S make
        生成32位的xapian库
        1、启动msys2、配置32位编译环境:执行本文第二章节中提到的脚本文件vs_x86.bat,在CMD窗口中输入如下命令:msys2_shell.cmd  -use-full-path 会出现msys2窗口
        2、 生成xapian编译环境、生成Makefile在msys2窗口中进入 xapian源代码目录 。(msys2是什么?自己百度。msys2中要访问本地windows环境下的c盘怎么办?直接用“cd  /c”即可,msys2是仿真linux环境,linux下没有盘符概念,只有目录。因此要进入d盘,输入“cd  /d”即可。)输入如下命令行
./configure LD=link CC="cl -nologo" CXX="$PWD/compile cl -nologo" CXXFLAGS="-EHsc -Z7" AR=lib CPPFLAGS=-IC:/zlib-1.2.11-lib32/include LDFLAGS="-LC:/zlib-1.2.11-lib32/lib" --prefix="d:/xapian-install-1.4.21-X86"
        3、 编译xapian,生成xapian静态库:上述命令跑完后,执行 make 过程中会出现很多warning,不用在意。
         4、打包生成的xapian:make完后,执行 make install  跑完后,会生成d:/xapian-intall-1.4.21目录,里面会有4个子目录(bin、include、lib、share),其中lib子目录下会有libxapian.a库文件。
        生成64位的xapian库
        1、启动msys2,配置64位编译环境 执行本文第二章节中提到的脚本文件 vs_x64.bat 在CMD窗口中输入如下命令:msys2_shell.cmd  -use-full-path 会出现msys2窗口
        2、 生成xapian编译环境、生成Makefile在msys2窗口中进入 xapian源代码目录 。输入如下两条命令,第一条命令的目的是将mingw64\bin 的路径添加到 PATH 变量的前面
​export PATH="/mingw64/bin:$PATH"
./configure LD=link CC="cl -nologo" CXX="$PWD/compile cl -nologo" CXXFLAGS="-EHsc -Z7" AR=lib CPPFLAGS=-IC:/zlib-1.2.11-lib64/include LDFLAGS="-LC:/zlib-1.2.11-lib64/lib" --prefix="d:/xapian-install-1.4.21-X64"
    最后要注意:我们生成的xapian库文件既不是.lib、也不是.dll文件,而是libxapian.a文件,不用诧异,只是文件后缀不同而已,就是一个静态lib文件。

四、举个栗子

  • 创建VS2017 控制台工程,项目设置为Release x86;
  • 在项目属性的 C/C++-->General 修改"Addtional Include Directories",加上xapian的include路径;
  • 在项目属性的 C/C++-->Code Generation修改Release下的Runtime Library为 /MT (我们编译的xapian运行时库用的MT,需要确保一致)
  • 在项目属性中 Linker-->General修改"Additional Library Directories",加上xapian的lib目录和zlib的lib目录;
  • 在项目属性的 Linker-->input中加上Rpcrt4.lib 和 Ws2_32.lib
  • 在项目属性的 C/C++-->General 修改“SDL检查”,由“是/(sdl)”改为“否(/sdl-)”
  • cpp代码中加入如下代码
#pragma warning(disable : 4996)
#pragma comment(lib, "libxapian.a")
#pragma comment(lib, "zdll.lib")
  • 将zlib1.dll拷贝到跟编译生成的exe文件同目录下,否则exe启动会有错误提示:应用程序无法正常启动(0xc000007b)
  • 下面是具体代码示例:
#pragma warning(disable : 4996)
#include <iostream>
#include <string>
#include "xapian.h"
#pragma comment(lib, "libxapian.a")
#pragma comment(lib, "zdll.lib")
using namespace std;

const string index_data_path = "./index_data";
const std::string doc_id1 = "doc1";
const std::string doc_keylist1 = "中国 to build self search engine";
const std::string doc_content1 = "What is the search engine?\nMaybe How you should ask baidu or google.\nBut I want to develop my own app.\nThen you may need the xapian source code.";
const std::string doc_id2 = "doc2";
const std::string doc_keylist2 = "NeXa generation search platform";
const std::string doc_content2 = "Every one know search is use full\nIt can Nexa be done just by a PC or phone.\nPlatform is very important";

const int DOC_ID_FIELD = 101;

void save_data()
{
	std::cout << "--- save_data----" << std::endl;
	Xapian::WritableDatabase db(index_data_path, Xapian::DB_CREATE_OR_OPEN);
	Xapian::TermGenerator indexer;
	Xapian::Document doc1;
	doc1.add_term(doc_id1);
//	doc1.add_value(DOC_ID_FIELD, doc_id1); // 用户自定义信息,也可以用此字段作为其他用途
	doc1.set_data(doc_content1); // payload
	indexer.set_document(doc1);
	indexer.index_text(doc_keylist1); // could use space seperated text line like terms or article
	db.replace_document(doc_id1, doc1);

	Xapian::Document doc2;
	doc2.add_term(doc_id2);
//	doc2.add_value(DOC_ID_FIELD, doc_id2); // custom property
	doc2.set_data(doc_content2);
	indexer.set_document(doc2);
	indexer.index_text(doc_keylist2);
	db.replace_document(doc_id2, doc2);

	db.commit();
}

void search_data1()
{
	std::cout << "--- search_data1----" << std::endl;
	Xapian::Database db(index_data_path);
	Xapian::Enquire enquire(db);
	Xapian::QueryParser qp;	

	Xapian::Query term1("中国");
	Xapian::Query term2("nexa"); //查询语句输入关键字不能用大写,原文中关键字可以大、小写
	Xapian::Query query = Xapian::Query(Xapian::Query::OP_OR, term1, term2);

	std::cout << "query is: " << query.get_description() << std::endl;

	enquire.set_query(query);

	Xapian::MSet matches = enquire.get_mset(0, db.get_doccount()); // find top 10 results
	std::cout << matches.get_matches_estimated() << " results found" << std::endl;
	std::cout << "matches " << matches.size() << std::endl;

	for (Xapian::MSetIterator it = matches.begin(); it != matches.end(); ++it)
	{
		Xapian::Document doc = it.get_document();
		std::string doc_id = doc.get_value(DOC_ID_FIELD);
		// FIXME: not every record will show field value, should do filter later
		std::cout << "rank: " << it.get_rank() + 1 << ", weight: " << it.get_weight() << ", match_ratio: " << it.get_percent() << "%, match_no: " << *it << ", doc_id: " << doc_id << ", doc content: [" << doc.get_data() << "]\n" << std::endl;
	}
}

void search_data2()
{
	std::cout << "--- search_data2----" << std::endl;
	Xapian::Database db(index_data_path);
	Xapian::Enquire enquire(db);
	Xapian::QueryParser qp;

	Xapian::Query term1("search");
	Xapian::Query term2("platform");
	Xapian::Query query = Xapian::Query(Xapian::Query::OP_AND, term1, term2);

	std::cout << "query is: " << query.get_description() << std::endl;

	enquire.set_query(query);

	Xapian::MSet matches = enquire.get_mset(0, 10); // find top 10 results, like split page
	std::cout << matches.get_matches_estimated() << " results found" << std::endl;
	std::cout << "matches " << matches.size() << std::endl;

	for (Xapian::MSetIterator it = matches.begin(); it != matches.end(); ++it)
	{
		Xapian::Document doc = it.get_document();
		std::string doc_id = doc.get_value(DOC_ID_FIELD);
		// FIXME: not every record will show field value, should do filter later
		std::cout << "rank: " << it.get_rank() + 1 << ", weight: " << it.get_weight() << ", match_ratio: " << it.get_percent() << "%, match_no: " << *it << ", doc_id: " << doc_id << ", doc content: [" << doc.get_data() << "]\n" << std::endl;
	}
}

void search_data3()
{
	std::cout << "--- search_data3-------" << std::endl;
	Xapian::Database db(index_data_path);
	Xapian::Enquire enquire(db);

	Xapian::Query term("nexa");
	std::cout << "query is: include \"" << "nexa" << "\"" << std::endl;

	enquire.set_query(term);

	Xapian::MSet matches = enquire.get_mset(0, db.get_doccount()); // find top 10 results
	std::cout << matches.get_matches_estimated() << " results found" << std::endl;
	std::cout << "matches " << matches.size() << std::endl;

	for (Xapian::MSetIterator it = matches.begin(); it != matches.end(); ++it)
	{
		Xapian::Document doc = it.get_document();
		std::string doc_id = doc.get_value(DOC_ID_FIELD);
		std::cout << "rank: " << it.get_rank() + 1 << ", weight: " << it.get_weight() << ", match_ratio: " << it.get_percent() << "%, match_no: " << *it << ", doc_id: " << doc_id << ", doc content: [" << doc.get_data() << "]\n" << std::endl;
	}
}

int main(int argc, char** argv)
{
	std::cout << "hello xapian" << std::endl;
	save_data();
	search_data1();
	search_data2();
	search_data3();
	return 0;
}

文本参考如下文档:

https://www.cnblogs.com/cswuyg/p/10402218.html

  • 27
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python Xapian(简称xapian)是一个用于全文搜索和信息检索的开源工具。它提供了Python语言的接口,使得我们可以方便地在Python环境中使用xapian的功能。 xapian是一种基于倒排索引的搜索引擎。它的主要特点是快速、可扩展,以及支持多种语言。我们可以利用xapian来创建和维护一个倒排索引,然后在这个上进行全文搜索和信息检索。 使用xapian,我们可以将一个文本集合中的文档添加到索引中。这个索引可以包含多个字段,每个字段可以是不同的文本类型(例如标题、正文、作者等)。然后,我们可以使用查询语句在这个索引中进行搜索。xapian支持多种查询类型,例如布尔查询、短语查询、通配符查询等。 除了基本的全文搜索,xapian还提供了一些高级功能。例如,我们可以使用xapian来计算查询和文档之间的相关性得分,从而对搜索结果进行排序。xapian还支持结果分页、结果高亮显示等功能,使得搜索结果更易于阅读和理解。 使用Python Xapian,我们可以在Python程序中轻松地集成全文搜索和信息检索功能。它可以应用于各种场景,例如网站搜索引擎、文档管理系统、邮件分类等。通过合理使用xapian的功能,我们可以帮助用户快速准确地找到他们所需的信息,提高用户体验和效率。 总之,Python Xapian是一个功能强大、易于使用的全文搜索和信息检索工具。它提供了丰富的功能和灵活的接口,可以满足不同应用的需求。无论是初学者还是专业开发人员,都可以利用xapian来构建高效的搜索和检索系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值