OpenMP vs WinSxS

VS2005

今天把一个工程设置为支持OpenMP, 在代码中使用几个 #pragma omp parallel for 编译后, 程序启动时提示找不到 vcmp.dll.

由于项目中别的工程之前我也用了OpenMP, 并没有出现这个错误, 经过比对发现是忘记 #include <omp.h>

仔细看看 omp.h, 就不难理解为什么需要包含这个头文件了.

为了解决著名的dll hell, 微软在现在的windows系统中引入了WinSxS, 将不同版本的系统共享 dll 分门别类的放在描述性的文件夹下, 文件夹的命名规则是已经严格定义的. 应用程序自身需要包含清单文件 manifest, 来说明自己需要动态链接哪一个版本的什么dll.

omp.h 的作用之一就是生成 vc openmp 的 manifest, 来通知系统 loader 加载 WinSxS 下哪一个 vcmp.dll, 如果没有 manifest, 系统不知如何加载, 自然会提示找不到.

STLPort & VC++2010

升级到VS2010以后,还没有编译过依赖STLPort的工程,今天在家编译一个自己以前的项目,发现STLPort和VC++2010存在一个兼容性问题。

Debug编译:

1>e:stlport-5.2.1stlportstl_cstdlib.h(158): error C2084: function ‘__int64 abs(__int64)’ already has a body
1>          d:program files (x86)microsoft visual studio 10.0vcincludestdlib.h(471) : see previous definition of ‘abs’

Release下不存在这个错误。

解决办法:注释掉_cstdlib.h(158)这一行即可。

另外在STLPort论坛已经看到有这个问题的报告,相信在未来版本中会被修正。

VC++2010 bug

软件复杂了,总会有或多或少的bug,今天就遇到一个,从表现来看是VC++ 2010的bug,因为这个确实很难测试覆盖。

http://social.microsoft.com/Forums/zh-CN/visualcpluszhchs/thread/cae52fba-6af8-4f93-bfae-209d44d4f134/

我这里有一个VC++2005的工程编译正常,之前曾升级到VC++2008也编译正常,今天升级到2010以后,编译失败,信息如下:

1>—— Build started: Project: Cal, Configuration: Debug Win32 ——

1>LINK : fatal error LNK1104: cannot open file ‘E:workCalDebugCal.lib’
1>
1>Build FAILED.

问题是Cal本身是一个dll工程,编译生成的应该是Cal.dll和Cal.lib,不可能link阶段依赖自己的lib。

检查升级后的工程配置没有发现问题。磁盘可用空间足够,也没有只读的Cal.lib或者写入不能的目录。

解决办法:

整个项目在转换到2010前有一些工程不存在(unloaded),因为我并没有在当前这台机器上完整check out。

在转换过程中看起来是VC2010错误的分析了依赖关系,把Cal依赖的别的工程错误的指向了Cal自己,变成了一个循环依赖。

这个问题我暂时用下面的方法解决了:

处理前,linker的命令行参数是: /OUT:".debugCal.dll" /INCREMENTAL /NOLOGO /DLL "opengl32.lib" "glew32.lib" "glu32.lib" "E:workCaldebugCal.lib" /DEF:".Cal.def" /MANIFEST /ManifestFile:".DebugCal.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level=’asInvoker’ uiAccess=’false’" /DEBUG /PDB:".debugCal.pdb" /MAP /MAPINFO:EXPORTS /SUBSYSTEM:WINDOWS /PGD:"E:workCaldebugCal.pgd" /TLBID:1 /DYNAMICBASE:NO /NXCOMPAT /NOASSEMBLY /MACHINE:X86 /ERRORREPORT:QUEUE

处理办法:打开工程属性,选择common properties,找到 link library dependencies,把 true 改成 false。

这样可以看到linker的命令行中的 "E:workCaldebugCal.lib" 被去掉了。

当然我不认为这个是真正的完美解决办法,有待微软修正。