- 首先确保VS更新,同时Win10 SDK版本在
10.0.19041
及以上(18363未测试,不知道是否可以,也有可能),并在VS Installer-单个组件
菜单中选择过nuget包管理器
,才能正常通过编译。 - 在
Main.cpp
中的solve
函数中,尽管加了两层捕捉,但是依旧存在错误情况下直接退出是因为SEH异常
相关的处理存在,使得MSVC不会捕捉C系列的错误(如内存访问冲突等)。这个可以通过两种方法解决(首先搜索编译选项的启用C++异常
,调整为/EHa
,之后第一种方法参考微软官方Exception handling model
文档,第二种方法参考注册SEH异常转化为C++异常方法) - 注意:这里我并不想在程序中解决这个错误。原因有两个:
- 首先是对于直接使用程序,即使这里使用方法捕捉到错误,出错点也不一定是被捕捉的地方,因此这里捕捉的意义也不大了
- Europa一般来说会作为其他组件嵌入到其他程序中,其他程序应该在调用过程中做好充足的保护,而不是让Europa做保护(反正保护了最后也会崩溃和退出),所以这部分代码应该在其他程序中写。
下面是本库针对europa的新版本VS编译指南,如想访问原来的README,请点击下方链接。
很多改动涉及引用路径和链接路径修改,这里避免了原来的使用环境变量引入,而是直接用相对目录方式引入,这部分请自行查看vcxproj
文件的历史记录。
- dlfcn在Windows+VS下不是必须的,所以可以不用考虑引入,引入的话,需要使用dlfcn下的visual-studio/12文件夹下的sln打开编译,编译前在dlfcn.c前加入一段话:(备注之下,正文第一行)
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
- 添加log4cpp库,新版本europa要求依赖这个库
- 引入boost库的头文件,这个在项目的nuget程序包中解决了
- 这里请按照
vcxproj
文件所写的lib命名规范,提前将需要的lib文件编译出来,编译为Win32
和x64
两种lib,然后include统一管理。 libantlr3c-3.4\include\antlr3convertutf.h
文件中120行左右,将#define false
和#define true
在cpp里面取消备注,也就是改成:
#ifndef __cplusplus
#define false ANTLR3_FALSE
#define true ANTLR3_TRUE
#endif
- 自定义宏方法
- MSVC对##解析错误问题,主要修改的是Error.hh文件
- 关闭
C4067
warning(莫名其妙就预处理指令有意外标记,不是很懂) - 关闭
C5104
warning(C++20部分的某种兼容问题,太烦了关了) - C++——预处理器——使用标准符合性预处理器,选择为
是 (/Zc:preprocessor)
(为了可以正常解析europa里面神奇的define) Number.hh
的110行左右,取消msvc头文件里面对min
和max
的备注,即添加:
// MSVC define min and max in its header, so we undef them
#if _MSC_VER >= 1800
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#endif
Resources.cc
中,select2nd
结构需要重新定义。Types.hh
中,hash_cosmpare
需要引入<xhash>
头文件,并且这东西被放在了stdext
命名空间下;map
需要加入std
命名空间限定。ResourceThreatManager.cc
中,需要取消对max和min的定义,如下:
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
Pdlfcn.hh
里添加dlfcn.h
中重要的定义,在namespace
之前加入,如下:
/* POSIX says these are implementation-defined.
* To simplify use with Windows API, we treat them the same way.
*/
#define RTLD_LAZY 0
#define RTLD_NOW 0
#define RTLD_GLOBAL (1 << 1)
#define RTLD_LOCAL (1 << 2)
/* These two were added in The Open Group Base Specifications Issue 6.
* Note: All other RTLD_* flags in any dlfcn.h are not standard compliant.
*/
#define RTLD_DEFAULT ((void *)0)
#define RTLD_NEXT ((void *)-1)
Mutex.hh
引用pthread.h
之前,要加入#define HAVE_STRUCT_TIMESPEC
,避免对于时间结构重定义- 如果修改了
NDDL.g
(也就是antlr
文件),请去官网下载antlr3.1.3.jar编译文件,用这个对.g
文件编译,然后将c
扩展名改为cpp
并放到VS要求的位置,就可以正常编译。
需要把以下的头文件和c/cpp
代码文件加入到project
中,对应着现有的文件目录添加到合适目录下的Header Files
和Source Files
下:
- ConstraintEngine
- ConstraintTypeChecking.hh
- ConstraintTypeChecking.cc
- CFunctions.cc
- PlanDatabase
- DbClientListerner.cc
- Resource
- FlowProfileGraph.hh
- FlowProfileGraph.cc
- BoostFlowProfileGraph.hh
- BoostFlowProfileGraph.cc
如果是编译exe的话,在项目——> 项目属性——> 配置属性——> 链接器——> 系统——> 子系统
中,应该设置为控制台 (/SUBSYSTEM:CONSOLE)
,如果是编译dll和lib,则保持原样即可。
在Constrains.cc
文件中,获取vector.size()
并转换为edouble
和eint
部分存在类型问题,要把size
强制转换为unsigned int
,以避免错误,修改如下:
// 1534行
(unsigned int)variables.size() - 1
// 1554行
(unsigned int)variables.size()
编译过程忽略以下两个警告:C4267
、C4302
,这两个警告主要都是指针转换和数值截断警告。