PuTTY的源码下载之后,里面已经带有Visual Studio 2010和Visual Studio 2012的解决方案,但是惊奇的发现,用这个两个解决方案编译出来的putty居然是xp风格的,和官网下载到的不一样。(如果只是要单纯的解决这个xp风格,可以参考MANIFEST)

所以,从零开始建立putty的Viusal Studio2017解决方案。
首先,建立一个空项目(记得勾选为解决方案创建目录)

这个时候,在你的putty源码目录的windows文件夹内会有一个putty文件夹,里面会有一个putty.sln
和一个putty
文件夹,将windows文件夹内的putty文件夹更名为VS2017(仅仅是为了与已有的解决方案统一风格而已,名字随意),这个时候,你可以对着解决方案的putty项目,点击右键,移动到添加,然后点击添加现有现有项,或者可以直接按下Shift + Alt +A
,对着原本就有的PuTTY项目,分别添加源文件、头文件、资源文件:

添加完成之后,putty项目看起来应该是这个样子的

无法打开包括文件: “unix.h”
按下Ctrl+Shift+B
,你就会看到这样的画面:

错误
1 | 严重性 代码 说明 项目 文件 行 禁止显示状态 |
原因很明显,它们找不到头文件在哪儿,右击项目,点击属性,选中C/C++,在附加包含目录内填入..\..\..\./;..\..\..\unix/;..\..\..\charset/;..\..\..\windows/;

这个是用来指定编译器搜索头文件的目录的,这里用的是相对路径(相对于putty解决方案内putty项目的路径,也就是putty源码的根目录,unix目录,charset目录和windows目录),这个附加目录也可以在VC++目录
的包含目录里面填写,如下图

库目录在putty项目的建立过程中不用填写,putty没有用到第三方库,这里不用填写。
无法打开包括文件: “dlfcn.h”
再次生成解决方案,你会遇到第二个问题
1 | 严重性 代码 说明 项目 文件 行 禁止显示状态 |

依旧打开项目属性,点击C/C++
,预处理器,预处理器定义

点击右边的下拉箭头,点击编辑,填入以下内容:
1 | WIN32 |
这个时候,看起来应该是这个样子的(“dlfcn.h”是Linux系统的头文件,猜测加预处理参数是为了让编译器知道不去试图查找这个文件)

case 表达式不是常量
再次生成解决方案,你会遇到第三个问题
1 | 严重性 代码 说明 项目 文件 行 禁止显示状态 |

打开项目属性,选中C/C++
,将调试信息格式更改为“程序数据库”,

使用了可能未初始化的本地指针变量
再次生成解决方案,你会遇到第四个问题
1 | 严重性 代码 说明 项目 文件 行 禁止显示状态 |

打开项目属性,选中C/C++
,将SDL检查改为否

noshare.obj & winshare.obj
再次生成解决方案,好了,你成功的将错误减少到了四个
1 |
|

对于错误1和错误2,我只能说,可能原本设计项目的人比较神奇,这两个错误花了我相当长的时间才排查掉,原因说得很清楚了,在连接winshare.obj
的时候,发现函数_platform_ssh_share
和_platform_ssh_share_cleanup
已经在 noshare.obj
内定义过,noshare.c
文件内的内容如下
1 | /* |
大致上看起来就是重定义了,BUT,为什么原本有的putty项目可以编译?,尝试将noshare.c
从项目中移除之后,再次编译,这两错误不见了,但是,为什么原本的项目可以编译呢,好生奇怪,两天之后,偶然发现,原本项目内的noshare.c
文件前面的图标和其他源文件长得不一样,仿佛发现了什么,点开属性一看,原来如此:
右击noshare.c
点击属性,选中常规,点击“项类型”右边的下拉箭头,改成C/C++标头
,

MANIFEST
再次生成解决方案,好了,这次你只能看到两个问题了
1 | 错误 CVT1100 资源重复。类型: MANIFEST,名称: 1,语言: 0x0409 putty D:\Desktop\putty-en\windows\VS2017\putty\CVTRES 1 |
但是这两个问题都不是源代码的问题(其实用源码内原本就有的解决方案能编译成功,就说明代码没问题了(PS:严格来说也不是没有可能)),对于错误 CVT1100 资源重复。类型: MANIFEST,名称: 1,语言: 0x0409 putty D:\Desktop\putty-en\windows\VS2017\putty\CVTRES 1
,右击项目,点击属性,点击清单工具,选中输入和输出,将嵌入清单改成“否”

再次生成解决方案,错误变成了
1 | 严重性 代码 说明 项目 文件 行 禁止显示状态 |

熟悉的话,很容易就知道这个是因为缺了静态库
右击项目,点击属性,点击链接器,选中输入,点击附加依赖项右边的下拉箭头,点击编辑,

填入imm32.lib,它看起来就是这样子的

再次编译,哈哈哈,终于成功了


其他可能遇到的问题
cannot open include file ‘version.h’
不过你也有可能遇到这个问题
1 | 严重性 代码 说明 项目 文件 行 禁止显示状态 |

如果你在第一步中,填写附加包含目录的时候,填在了VC++目录
里面,则不会遇到此问题,若是填到了C/C++
则会遇到,一个办法是更改到VC++
目录去,另外一个办法是在项目属性的资源选项下面,附加目录里面填上..\..\..\./;

关于依赖库
在putty原本带的解决方案内的附加依赖项是下面这些
1 | advapi32.lib |
在Windows 10 1803上,Visual Studio 2017 的预先包含的静态库里面已经包含了除去imm32.lib
之外的所有今天库,所以我只添加了它。有关Visual Studio的各种报错,查看巨硬(微软)的文档是一个好办法,百度得到的办法虽说更为简洁明了一些,但是因为复现环境不一样,有时候并没有效果。
调整项目属性之后不生效
PS:若是调整项目属性之后不生效,请留意调整的项目和生成解决方案的是否是同一个编译选项

让其他项目用同样的属性
按照上一个描述的问题,对于一个工程,在win32和x86的Release和Debug模式都需要调整属性,就整整四个了,整个PuTTY解决方案其实包括了 pageant plink pscp psftp putty puttygen puttytel testbn
,其它七个再来一次,简直爽歪歪,这个时候项目属性表就有用了,可以参考https://www.cnblogs.com/haomiao/p/5812860.html,若是找不到属性管理器,可以点击视图下的其他窗口的“属性管理器”。
懒人包
GitHub上有已经汉化完成的版本——https://github.com/larryli/PuTTY
下载搭建好的PuTTY的Visual Studio 2017解决方案,可以前往https://github.com/BDZNH/PuTTY