【问题标题】:Substituting Visual C++ frontend to one of the previous version将 Visual C++ 前端替换为以前的版本之一
【发布时间】:2014-03-31 11:03:23
【问题描述】:

我正在尝试从 Visual Studio 2013 中的源代码编译 The Point Cloud Library (PCL)(当然使用 v120 工具集和 MSCL18),因为我需要这个库用于 VS2013 项目。但结果却是一项棘手的任务。

  • 一方面,由于破坏,PCL 源代码没有在 VS2013 中编译 VS2013 中新 C++ 标准模板的变化
  • 另一方面,在 VS2012 中编译时,PCL DLL 有自己的 CRT 甚至最简单的 PCL 相关代码崩溃

例如在VS2013中这段代码sn -p:

pcl::console::print_highlight(stdout, "Begin");

由于 PCL DLL 和我的 EXE 中的 CRT 不同,在“EnterCriticalSection(&(((_FILEX *) pf)->lock));”处抛出异常,这在 this question 中有描述。

作为最后的手段,我试图将 C++ 前端从 MSCL18 更改为 MSCL17,以便接收对象或汇编程序文件并在进一步的构建步骤中使用 CL18 链接器链接它们。我还没找到好办法。

所以我的问题是,如果有人可以分享他们在这种两步编译中的经验,如何替换以前的编译器版本前端,或者这个问题的另一种解决方案是什么?

【问题讨论】:

  • 这不起作用,因为您必须使用与工具链版本匹配的标准库(因此,如果您使用 Visual C++ 2012 编译器,您还需要使用 Visual C++ 2012 库,并且同样适用于 Visual C++ 2013)。您不能链接使用不同版本的库编译的对象(这样做会导致 ODR 违规甚至更糟)。如果您需要混合搭配,则需要使用动态库和它们之间的 C(或 COM)接口。
  • 很好的通知。我审查了 STL 的差异。除了一些新方法和新的 C++ 标准修饰之外,这两个编译器几乎相同。所以数据应该可以通过。
  • 几乎一样不是一样。作为对 Visual C++ 2013 的 Visual C++ 库进行更改的人之一,我可以告诉你,尝试混搭是危险的,几乎肯定会以眼泪收场。您可能遇到的 99.99% 的问题在编译时无法诊断,并且表现为晦涩难懂、有时无法可靠重现的运行时崩溃。这就是为什么默认情况下我们禁止链接不匹配的对象。
  • 我刚刚使所有内容都可以编译,我将尝试我得到的。我所做的更改是 (1) 将“= delete”构造函数更改为私有构造函数,(2) 删除 bool 转换器上的显式关键字,(3) 删除 basic_string 的 initializer_list 构造函数和 (4) 将模板更改为两个其他 basic_string 构造函数。就是这样,它看起来很简单的变化,尤其是没有字符串创建。我要把它点燃,看看会怎样。
  • 詹姆斯,你听起来很扎实。我明白你在说什么。我只是想找到完成工作的方法。除了用 C++ 前端和 STL 子集替换这个想法之外,你会推荐什么?我可能忽略了什么?

标签: visual-c++ visual-studio-2013 point-cloud-library


【解决方案1】:

我尝试了几种方法来编译这个第 3 方库而不更改库源代码。结果证明工作正常的一个是将VS2013 C++前端(工具集v120,MSCL18)替换为前一个(VS2012,工具集v110,MSCL17)用于一些不通过VS2013的文件,然后使用生成的 OBJ 文件在 VS2013 中进一步编译。

James McNellis 的评论做得很好,因为它们帮助我更好地理解并仔细修复了 VS2013 STL 流和字符串对象中的编译错误,并提出了我的 VS2013 STL 子集,它使用 VS2012 原生工具集编译得很好。

实际上,我为不同的配置和平台创建了一个自定义构建工具(C++ 项目 -> 属性):

Debug|Win32
$(ComSpec) /c ""$(ProgramFiles)\Microsoft Visual Studio 11.0\Common7\Tools\vsvars32.bat" x86   && cl.exe /c %(FullPath) /IC:\Src\PCLCompilation\local_stl /IC:/Src/PCLCompilation/boost_1_55_0 /IC:/Src/PCLCompilation/eigen/include /I"C:/Src/PCLCompilation/flann-1.8.4.v120/include" /I"$(SolutionDir)include" /I"C:/Src/PCLCompilation/pcl-master/common/include" /I"C:/Src/PCLCompilation/pcl-master/octree/include" /I"C:/Src/PCLCompilation/pcl-master/io/include" /I"C:/Src/PCLCompilation/pcl-master/filters/include" /nologo /W3 /WX- /MP4 /Od /Ob0 /Oy- /Zi /D_MSC_VER=1800 /D WIN32 /D _WINDOWS /D _WINDLL /D _MBCS /D _DEBUG /D BOOST_DISABLE_ASSERTS /D EIGEN_NO_DEBUG /D BOOST_ALL_NO_LIB /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D NOMINMAX /D BOOST_LIB_DIAGNOSTIC /D EIGEN_USE_NEW_STDVECTOR /D EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET /D FLANN_STATIC /D CMAKE_INTDIR=$(Configuration) /D PCLAPI_EXPORTS /Gm- /EHsc /RTC1 /MDd /GS /arch:SSE2 /fp:precise /Zc:wchar_t /Zc:forScope /GR /openmp /Fo"$(IntDir)\" /Fd"$(TargetDir)$(TargetName).pdb" /Gd /TP /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355 /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355 /analyze- /errorReport:prompt /bigobj"
Debug|x64
$(ComSpec) /c ""$(ProgramFiles)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64           && cl.exe /c %(FullPath) /IC:\Src\PCLCompilation\local_stl /IC:/Src/PCLCompilation/boost_1_55_0 /IC:/Src/PCLCompilation/eigen/include /I"C:/Src/PCLCompilation/flann-1.8.4.v120/include" /I"$(SolutionDir)include" /I"C:/Src/PCLCompilation/pcl-master/common/include" /I"C:/Src/PCLCompilation/pcl-master/octree/include" /I"C:/Src/PCLCompilation/pcl-master/io/include" /I"C:/Src/PCLCompilation/pcl-master/filters/include" /nologo /W3 /WX- /MP4 /Od /Ob0      /Zi /D_MSC_VER=1800 /D WIN32 /D _WINDOWS /D _WINDLL /D _MBCS /D _DEBUG /D BOOST_DISABLE_ASSERTS /D EIGEN_NO_DEBUG /D BOOST_ALL_NO_LIB /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D NOMINMAX /D BOOST_LIB_DIAGNOSTIC /D EIGEN_USE_NEW_STDVECTOR /D EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET /D FLANN_STATIC /D CMAKE_INTDIR=$(Configuration) /D PCLAPI_EXPORTS /Gm- /EHsc /RTC1 /MDd /GS /arch:SSE2 /fp:precise /Zc:wchar_t /Zc:forScope /GR /openmp /Fo"$(IntDir)\" /Fd"$(TargetDir)$(TargetName).pdb" /Gd /TP /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355                                                           /errorReport:prompt /bigobj"

Release|Win32
$(ComSpec) /c ""$(ProgramFiles)\Microsoft Visual Studio 11.0\Common7\Tools\vsvars32.bat" x86   && cl.exe /c %(FullPath) /IC:\Src\PCLCompilation\local_stl /IC:/Src/PCLCompilation/boost_1_55_0 /IC:/Src/PCLCompilation/eigen/include /I"C:/Src/PCLCompilation/flann-1.8.4.v120/include" /I"$(SolutionDir)include" /I"C:/Src/PCLCompilation/pcl-master/common/include" /I"C:/Src/PCLCompilation/pcl-master/octree/include" /I"C:/Src/PCLCompilation/pcl-master/io/include" /I"C:/Src/PCLCompilation/pcl-master/filters/include" /nologo /W3 /WX- /MP4 /O2 /Ob2 /Oy- /GL /D_MSC_VER=1800 /D WIN32 /D _WINDOWS /D NDEBUG /D BOOST_DISABLE_ASSERTS /D EIGEN_NO_DEBUG /D BOOST_ALL_NO_LIB /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D NOMINMAX /D BOOST_LIB_DIAGNOSTIC /D EIGEN_USE_NEW_STDVECTOR /D EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET /D FLANN_STATIC /D CMAKE_INTDIR=$(Configuration) /D PCLAPI_EXPORTS /D _WINDLL /D _MBCS /Gm- /EHsc /MD /GS /arch:AVX /fp:precise /Zc:wchar_t /Zc:forScope /GR /openmp /Fo"$(IntDir)\" /Fd"$(TargetDir)$(TargetName).pdb" /Gd /TP /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355 /analyze- /errorReport:prompt  /bigobj"
Release|x64
$(ComSpec) /c ""$(ProgramFiles)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64           && cl.exe /c %(FullPath) /IC:\Src\PCLCompilation\local_stl /IC:/Src/PCLCompilation/boost_1_55_0 /IC:/Src/PCLCompilation/eigen/include /I"C:/Src/PCLCompilation/flann-1.8.4.v120/include" /I"$(SolutionDir)include" /I"C:/Src/PCLCompilation/pcl-master/common/include" /I"C:/Src/PCLCompilation/pcl-master/octree/include" /I"C:/Src/PCLCompilation/pcl-master/io/include" /I"C:/Src/PCLCompilation/pcl-master/filters/include" /nologo /W3 /WX- /MP4 /O2 /Ob2      /GL /D_MSC_VER=1800 /D WIN32 /D _WINDOWS /D NDEBUG /D BOOST_DISABLE_ASSERTS /D EIGEN_NO_DEBUG /D BOOST_ALL_NO_LIB /D _SCL_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_WARNINGS /D NOMINMAX /D BOOST_LIB_DIAGNOSTIC /D EIGEN_USE_NEW_STDVECTOR /D EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET /D FLANN_STATIC /D CMAKE_INTDIR=$(Configuration) /D PCLAPI_EXPORTS /D _WINDLL /D _MBCS /Gm- /EHsc /MD /GS /arch:AVX /fp:precise /Zc:wchar_t /Zc:forScope /GR /openmp /Fo"$(IntDir)\" /Fd"$(TargetDir)$(TargetName).pdb" /Gd /TP /wd4800 /wd4521 /wd4251 /wd4275 /wd4305 /wd4355 /errorReport:prompt /bigobj"

具有以下输出:

$(IntDir)%(Filename).obj

我将不可编译文件的工具更改为这个自定义构建工具(C++ 文件 -> 属性 -> 常规 -> 项目类型 -> 自定义构建工具),它很好地配合了整个编译过程。字符串对象二进制表示看起来相同,生成的二进制 DLL 没有问题,所有系统都通过了我们所有的 QA 测试。 这个小技巧帮助我们将所有系统迁移到 VS2013,因为我们依赖的库中的一些文件导致延迟。

3 月 30 日更新:几个月来,我们在几个开发和测试盒上没有发现这种方法有任何错误。

【讨论】:

  • 有一天你会后悔的。令人震惊的是,还没有人将此问题添加到项目的错误跟踪器中。强烈建议避免这样的hackorama。
  • 我知道这是一个 hack,所以我有一个 B 计划,在遇到真正问题时回滚到 VS2012。现实情况是,我们在多次运行中以相当重的负载使用这个库,过去两周没有发生任何问题。所以我希望一切都会好起来的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
相关资源
最近更新 更多