MENU

使用Dev-C++构建新BravoFinder

January 26, 2018 • 程序

前言

BravoFinder第一次发布已经过去了接近两年时间,这段时间里获得了不少人的支持,也发现了一些问题。为了解决许多历史遗留问题,前一段时间我将整个项目完全推翻重写了一次,编码工作已经完成了,文档工作正在慢慢补上。

我一直致力于写平台无关的代码,并且在这个项目里面确实也不会用上专有的API。考虑到大部分模拟飞行玩家都是Windows用户,Windows平台是必须支持的。但我长时间在*nix下做开发,使用的工具链与微软系还是有一定距离,比如CMake在Windows上正常运作可能就有些困难了。在Windows上构建不会太难,但是一个示范介绍是绝对必要的。

准备工作

这次展示的内容依旧使用自由软件工具链,但不运行于类似于Cygwin的模拟环境下,而是完全使用Windows原生API。选择的IDE是轻量级C/C++开发工具Dev-C++,这个软件有一段历史了,官方更是早已停更,版本号停留在4.9.9.2。这里采用的是Orwell升级版,可以在SourceForge上下载。它附带了MinGW下的GCC及相关工具,GCC版本为4.9.2,稍显老旧,但支持BravoFinder中用到的C++11特性是足够了。

当然,在开始之前我们还需要将代码仓库给克隆下来。

构建动态链接库

创建工程并添加文件

BravoFinder第二版的主体是一个库,代码位于Library目录中。我们在Dev-C++的菜单中点击File->New->Project,并新建一个DLL工程,把工程文件保存到合适的位置。
新建DLL工程
这时,左侧的工程目录树中自动创建了dllmain.cppdll.h,而这是我们不需要的,直接将它们删去。接着,在目录树的根部(即项目名称处)点击右键,新建两个目录:DataSetDataStructure。把代码仓库中对应目录下的文件添加(Add To Project)到这两个目录中。
添加项目文件

编译及生成设置

仍然在目录树的根部点击右键,选择Project Options。首先根据你需要的平台(32位或64位)选择合适的基本编译器设置,然后将语言标准设为ISO C++11。链接器参数中记得加上-lm,在计算坐标之间的距离时用到了不少数学函数。以下是一种建议的配置。
一种建议的配置
对了,在Project Options中,检查一下Output选项卡中的输出文件名,建议改为bfinder.dll,与CMake保持一致。

生成

这时可以直接按下F9或F12来生成了,你也可以在菜单的Execute选项卡中看到。如果配置没有出差错,就可以在你设置的目录(默认在创建工程时选择的目录)下看到生成出来的库文件了。

构建演示用命令行前端

创建工程

这次在创建工程时注意选择类型为Console Application。仍然是删除默认文件,并添加仓库中的文件。演示用命令行前端只有一个源文件bf.cpp,位于CliExample目录。

设置及解释

头文件疑虑

在*nix平台上,CMake会在安装时将所需的头文件按照给定目录拷贝到包含目录(即/path/to/install/prefix/include/bfinder)中,所以在bf.cpp中直接使用了bfinder/bfinder.h。在Windows上不做一些修改,这样子是行不通的。下面给出两种可行的做法。

  • 不修改源文件的做法:直接将Library目录复制一份(其实仅需要其中的部分头文件),并将目录命名为bfinder。这样做的话,需要添加的包含目录路径就是这个新的bfinder的路径。
  • 需要修改源文件的做法:将bf.cpp中的bfinder/bfinder.h改为bfinder.h。这样做的话,需要添加的包含目录路径是Library的路径。

选择上面一种做法之后,将相应的包含目录添加好。下图展示的是第一种做法的情况。
添加包含目录

其他需要注意的事项

相应地,把含有bfinder.dll文件的目录的路径要添加到Library Directories中。其他设置参考动态库示范进行,主要是要设置C++11标准。另外,链接器参数这次不是加-lm而是-lbfinder了,因为我们调用的是BravoFinder库里的东西。

生成及使用

生成若没有问题,我们就得到了一个可执行文件。如果你没有改动源码,那么在使用前我们需要创建一个名为navdata.txt的文件,和可执行文件放在同一个目录中。文件中应且只应有某个导航数据Cycle的根目录路径(即含有NAVDATASIDSTARS的目录)。以下是运行结果示范截图。
运行结果示范截图

构建Scaffold框架

代码仓库中的WebAPI是一个简单的演示,旨在告诉大家BravoFinder库的用途多样。为了方便快速地写出这样一个示例程序,我用了自己在2017年中实现的一个简单的用于Web开发的C++框架Scaffold。在Windows上构建它确实不算太简单,为了不至于让整个过程变得过于繁琐,我们在构建它的过程中会阉割掉部分难以配置的、没有用到的功能。

创建Scaffold项目时也应当作为一个库,建议的输出文件为scaffold.dll

最小化的依赖

Scaffold一定需要的依赖有Mongoose和RapidJSON,其中Mongoose已经自带了。请前往GitHub的Tencent/rapidjson获取RapidJSON,并且将它的include目录添加到项目的包含目录中

添加文件

建立DependencyFoundationHeaderUtility目录并将相应的文件添加进去。注意Plugin目录中的插件不需要使用,因此不用添加。

另外,Mongoose是C语言写成的,因此需要做如下调整,Dependency/mongoose/mongoose.c不应当作为C++编译。
不作为C++编译

设置

语言标准为C++11。头文件方面,需要将HeaderDependency的路径添加到包含目录中。另外为了编译Mongoose需要做如下调整。
编译器和链接器参数
其中在我的Windows 8.1系统上,需要定义_WIN32MG_ENABLE_IPV6MG_ENABLE_IPV6应为0。而Mongoose在Windows上使用了winsock2,因此将它加入链接器参数。

生成

设置没有出错的话我们得到了scaffold.dll

构建演示用 Web API

之前为了顺利构建 Web API,费了一些功夫构建Scaffold框架,总共已经构建了3个项目,相信大家也比较熟悉了。Web API 这里主要注意以下几点。

各种目录

包含目录

  • Scaffold库的头文件目录(Header
  • BravoFinder库的头文件目录(根)
  • RapidJSON的头文件目录(include

库目录

  • Scaffold库所在目录
  • BravoFinder库所在目录

编译器和链接器参数

编译器语言标准为C++11。链接器应加上-lbfinder-lscaffold

使用

按照上述说明应该可以得到一个可执行文件。拷贝代码仓库中的config.json到可执行文件所在目录,并编辑它。config.json的根是一个数组,里面的每一个元素都应该含有cycle(导航数据标识)和path(路径),若需要同时使用多组数据请自行添加。配置完成之后开始运行,初始化成功后会打印出Initialization complete!字样,这时 Web API 就可以通过 http 访问了,比如:

http://127.0.0.1:3001/route/AIRAC1801?dep=ZGGG&arr=ZSFZ

如果给定的出发和到达机场无误,则得到航路信息,如:

{"status":200,"route":"ZGGG SID SAREX W6 NLG W509 GLN R200 BEBEM A470 XLN STAR ZSFZ","legs":[{"from":"ZGGG","to":"SAREX","route":"SID"},{"from":"SAREX","to":"NLG","route":"W6"},{"from":"NLG","to":"KEVAR","route":"W509"},{"from":"KEVAR","to":"GLN","route":"W509"},{"from":"GLN","to":"VIPAP","route":"R200"},{"from":"VIPAP","to":"OVGOT","route":"R200"},{"from":"OVGOT","to":"SUMDO","route":"R200"},{"from":"SUMDO","to":"BEBEM","route":"R200"},{"from":"BEBEM","to":"SWA","route":"A470"},{"from":"SWA","to":"IKATA","route":"A470"},{"from":"IKATA","to":"TEBON","route":"A470"},{"from":"TEBON","to":"XLN","route":"A470"},{"from":"XLN","to":"ZSFZ","route":"STAR"}],"waypoints":[{"wpt":"ZGGG","lat":23.393333435058595,"lon":113.30833435058594},{"wpt":"SAREX","lat":22.88166618347168,"lon":113.48332977294922},{"wpt":"NLG","lat":22.531667709350587,"lon":113.5616683959961},{"wpt":"KEVAR","lat":22.625,"lon":113.80999755859375},{"wpt":"GLN","lat":22.708332061767579,"lon":114.03333282470703},{"wpt":"VIPAP","lat":22.761667251586915,"lon":114.53166961669922},{"wpt":"OVGOT","lat":22.78333282470703,"lon":114.75},{"wpt":"SUMDO","lat":22.899999618530275,"lon":115.88166809082031},{"wpt":"BEBEM","lat":22.950000762939454,"lon":116.36000061035156},{"wpt":"SWA","lat":23.440000534057618,"lon":116.76667022705078},{"wpt":"IKATA","lat":23.764999389648439,"lon":117.13666534423828},{"wpt":"TEBON","lat":24.13833236694336,"lon":117.50166320800781},{"wpt":"XLN","lat":24.565000534057618,"lon":118.01499938964844},{"wpt":"ZSFZ","lat":25.933332443237306,"lon":119.66500091552735}]}

后记

其实很多人应该已经看出了Dev-C++在这里的作用是一个GUI的Makefile生成器。但考虑到真正需要这篇指导的人可能并不熟悉GNU系工具链,还是很详细地写了。

生成的二进制文件可以在项目的Release页下载。

Tags: c/cpp
Archives Tip
QR Code for this page
Tipping QR Code
Leave a Comment

已有 4 条评论
  1. CMake还是可以用的,我用MSVC配置好,configure & generate之后会生成VS的解决方案,再调用msbuild去编译解决方案就好了。不过不管用哪个,手写Makefile或者CMakeList.txt感觉还是比较烦的。

  2. Delbert Delbert

    太优秀了@(小乖)

  3. AlanJin AlanJin

    非常优秀@(真棒)

  4. tham tham

    优秀@(滑稽)