
简介本资源提供在Windows平台使用Visual Studio 2017编译64位libssh2库的完整成果面向需要在C/C项目中集成SSH2协议、实现远程文件传输与shell访问的开发者。libssh2作为开源SSH2协议库其64位版本可确保与64位应用程序的兼容性适合具备一定CMake与MSVC编译基础的中高级开发者使用。压缩包共115个文件以109个h头文件为主另含3个lib静态库、2个dll动态库及1个cpp示例文件整体约2.14MB头文件覆盖libssh2与OpenSSL相关接口声明库文件可直接用于链接。资源已获1513人学习下载。通过该包读者可省去从源码获取、依赖配置到CMake生成与编译的繁琐流程直接获得可用的64位libssh2.lib及配套头文件并参考示例快速完成包含路径与链接器配置将SSH2能力集成到自有工程中。1. 为什么在 VS2017 里编译 64 位 libssh2 总有人卡在第一步如果你正在用 VS2017 做 Windows 上的 C/C 开发某天需要让程序通过 SSH 执行远程命令、传输文件或者对接一套自动化运维工具那么 libssh2 大概率会进入你的视野。它是一套轻量的 SSH2 协议客户端库不依赖 OpenSSL 之外的重型框架编译出来就是一个静态库或动态库塞进工程就能用。但问题在于网上能搜到的教程大多停留在 32 位、老版本 VS 或者直接用 vcpkg 一键安装真正要在 VS2017 里手动编译出 64 位版本并且让它在自己的工程里稳定链接中间会踩一串坑zlib 和 OpenSSL 的位数不匹配、CMake 生成器选错、运行库配置冲突、链接时找不到符号。这篇笔记就按我实际走通的路径把从环境准备到最终验证的完整流程拆开讲清楚适合需要自己掌控依赖版本、不想被包管理器绑死的中高级 C 开发者。2. 编译前的依赖准备zlib 与 OpenSSL 的 64 位版本怎么选libssh2 本身不实现加密和压缩它依赖两个外部库OpenSSL 提供加密算法和密钥交换zlib 提供传输压缩。这两个库必须和 libssh2 保持相同的目标架构也就是都要是 64 位。很多人在这一步翻车是因为从网上随手下载了一个 32 位的 OpenSSL 预编译包结果 CMake 配置阶段不报错链接阶段才出现一堆LNK2019未解析的外部符号排查起来非常费时间。2.1 用 vcpkg 统一管理依赖位数我一般会先用 vcpkg 把依赖装好这样位数和运行库类型都能统一控制。假设 vcpkg 已经克隆到D:\vcpkg并且已经执行过bootstrap-vcpkg.bat接下来只需要指定 triplet 为x64-windowsD:\vcpkg\vcpkg install zlib:x64-windows D:\vcpkg\vcpkg install openssl:x64-windows这两条命令执行完后vcpkg 会在D:\vcpkg\installed\x64-windows下生成include、lib、bin三个目录。include里是头文件lib里是导入库bin里是运行时需要的 DLL。注意openssl在 vcpkg 里默认安装的是动态库版本如果你希望静态链接需要改成openssl:x64-windows-static但那样会连带影响 libssh2 的链接方式后面会细说。提示vcpkg 安装 openssl 耗时较长网络不稳定时容易中断建议先确认代理配置或者换用离线包但不要混用不同来源的库文件。2.2 手动编译依赖时的关键参数如果你不想用 vcpkg而是自己从源码编译 OpenSSL 和 zlib那么必须确保在 VS2017 的 64 位本机工具命令提示符下操作。以 OpenSSL 为例配置命令要明确指定VC-WIN64Aperl Configure VC-WIN64A --prefixD:\deps\openssl --openssldirD:\deps\openssl\ssl nmake nmake installVC-WIN64A表示 64 位 Release 版本--prefix指定安装路径。zlib 的编译更简单用 CMake 生成 VS2017 解决方案后在配置管理器里把平台切到x64再编译即可。无论用哪种方式最终你要得到的是三个东西头文件目录、.lib导入库目录、.dll运行时目录。把这三个路径记下来下一步配置 libssh2 时要用。3. 用 CMake 生成 VS2017 工程并编译 64 位 libssh2依赖就绪后接下来是 libssh2 本体的编译。libssh2 官方推荐用 CMake 构建但 CMake 的图形界面和命令行在指定生成器、架构、依赖路径时有一些细节需要注意尤其是 VS2017 对应的生成器名称和-A x64参数。3.1 获取源码与目录结构确认从 libssh2 的官方发布渠道下载源码包解压到一个没有中文和空格的路径比如D:\src\libssh2-1.11.0。进入目录后你会看到CMakeLists.txt、src、include、example等文件夹。确认include下存在libssh2.h这是后续工程里要包含的头文件。不要直接在源码根目录里执行构建最好新建一个build子目录保持源码目录干净方便出问题时重新来。3.2 CMake 命令行配置的完整参数打开 VS2017 的“x64 本机工具命令提示符”cd 到build目录执行下面这条命令。注意生成器名称必须和 VS2017 匹配Visual Studio 15 2017 Win64是带 Win64 后缀的旧写法新版本 CMake 推荐用-A x64指定架构cmake -G Visual Studio 15 2017 -A x64 ^ -DCMAKE_INSTALL_PREFIXD:\deps\libssh2 ^ -DOPENSSL_ROOT_DIRD:\vcpkg\installed\x64-windows ^ -DOPENSSL_INCLUDE_DIRD:\vcpkg\installed\x64-windows\include ^ -DOPENSSL_CRYPTO_LIBRARYD:\vcpkg\installed\x64-windows\lib\libcrypto.lib ^ -DOPENSSL_SSL_LIBRARYD:\vcpkg\installed\x64-windows\lib\libssl.lib ^ -DZLIB_ROOTD:\vcpkg\installed\x64-windows ^ -DZLIB_INCLUDE_DIRD:\vcpkg\installed\x64-windows\include ^ -DZLIB_LIBRARYD:\vcpkg\installed\x64-windows\lib\zlib.lib ^ -DBUILD_SHARED_LIBSOFF ^ -DCMAKE_BUILD_TYPERelease ^ ..这里有几个参数需要解释。CMAKE_INSTALL_PREFIX决定nmake install或 VS 的 INSTALL 工程把编译产物复制到哪里。OPENSSL_ROOT_DIR是 CMake 查找 OpenSSL 的根目录但为了保险我通常把OPENSSL_INCLUDE_DIR、OPENSSL_CRYPTO_LIBRARY、OPENSSL_SSL_LIBRARY三个变量也显式指定避免 CMake 找到系统里其他版本的 OpenSSL。ZLIB_ROOT同理。BUILD_SHARED_LIBSOFF表示编译静态库如果你需要 DLL改成ON但那样链接时还要处理__declspec(dllexport)相关的问题。注意如果 CMake 报错说找不到 OpenSSL先检查路径里有没有反斜杠转义问题命令行里用\或者/都可以但不要混用。另外确认libcrypto.lib和libssl.lib确实存在于指定目录。3.3 编译与安装配置成功后build目录下会生成libssh2.sln。用 VS2017 打开这个解决方案在顶部工具栏把解决方案配置切到Release解决方案平台切到x64。然后右键ALL_BUILD工程选择“生成”。编译完成后再右键INSTALL工程选择“仅生成 INSTALL”。这样头文件、.lib和.dll如果编译动态库就会复制到D:\deps\libssh2下。如果你更喜欢命令行也可以在同一个命令提示符里执行cmake --build . --config Release --target INSTALL这条命令会自动完成编译和安装两步。编译过程中如果出现LNK1181找不到libcrypto.lib说明前面的 OpenSSL 库路径没指对回到 CMake 配置步骤检查。4. 避坑与排查编译链接阶段最常见的 5 个问题即使按照上面的步骤走不同机器环境还是会遇到各种报错。下面这 5 个是我在多个项目里反复见到的按“现象 → 原因 → 解决”整理出来方便你快速定位。4.1 链接时报 LNK2019 无法解析的外部符号_SSLeay_version现象编译 libssh2 或者自己的工程时链接器报一堆 OpenSSL 相关符号找不到比如_SSLeay_version、_OPENSSL_init_ssl。原因链接器找到的libcrypto.lib是 32 位版本或者虽然路径对但库文件本身不包含这些符号。VS2017 在 x64 平台下不会自动区分 32 位和 64 位库只要路径里有.lib就尝试链接。解决用dumpbin /headers libcrypto.lib | findstr machine检查库文件的机器类型x64 应该显示8664。如果是14C就是 32 位需要重新获取 64 位版本。同时确认工程属性里“链接器 → 输入 → 附加依赖项”只包含 64 位库。4.2 CMake 配置阶段报 Could NOT find OpenSSL现象执行cmake命令后输出里出现Could NOT find OpenSSL, try to set the path to OpenSSL root folder然后配置失败。原因CMake 的FindOpenSSL模块在 Windows 上默认会去几个固定路径找如果 OpenSSL 装在非标准位置它找不到。即使设置了OPENSSL_ROOT_DIR如果目录结构不符合预期比如缺少include/openssl/ssl.h也会失败。解决除了OPENSSL_ROOT_DIR把OPENSSL_INCLUDE_DIR、OPENSSL_CRYPTO_LIBRARY、OPENSSL_SSL_LIBRARY全部显式传入。另外确认OPENSSL_ROOT_DIR指向的目录下确实有include和lib两个子目录。4.3 运行时报缺少 zlib1.dll 或 libcrypto-1_1-x64.dll现象编译出来的程序在开发机上能跑换一台机器就弹窗说找不到zlib1.dll或libcrypto-1_1-x64.dll。原因如果 libssh2 和 OpenSSL 都是动态链接那么运行时需要这些 DLL 在PATH或者可执行文件同目录下。开发机上因为 vcpkg 或者安装目录已经加入PATH所以不报错。解决把D:\vcpkg\installed\x64-windows\bin下的zlib1.dll、libcrypto-1_1-x64.dll、libssl-1_1-x64.dll复制到你的.exe所在目录。或者改成静态链接vcpkg 安装zlib:x64-windows-static和openssl:x64-windows-static然后 libssh2 也用BUILD_SHARED_LIBSOFF重新编译。4.4 编译 libssh2 时提示找不到libssh2_config.h现象在 VS 里生成ALL_BUILD时某个源文件报Cannot open include file: libssh2_config.h。原因libssh2_config.h是 CMake 根据配置生成的通常生成在build/src目录下。如果 VS 工程的附加包含目录没有把这个路径加进去就会找不到。解决检查build/src下是否有libssh2_config.h。如果没有说明 CMake 配置阶段没成功重新执行配置。如果有在 VS 工程属性里把$(SolutionDir)src加到“C/C → 常规 → 附加包含目录”。4.5 32 位工程误用 64 位 libssh2 导致 LNK1112现象链接器报模块计算机类型“x64”与目标计算机类型“x86”冲突。原因你的主工程平台是 Win32但链接的 libssh2.lib 是 x64 版本。VS2017 的配置管理器里解决方案平台和项目平台可能不一致。解决在 VS 顶部把解决方案平台切到x64然后检查每个项目的属性页里“链接器 → 高级 → 目标计算机”是否也是MachineX64。如果主工程必须用 Win32那就需要重新编译 32 位的 libssh2不能混用。5. 在自己的 VS2017 工程里链接 libssh2 并验证 SSH 连接编译出 64 位 libssh2 只是第一步真正要用起来还得把它集成到自己的工程里并且写一段最小验证代码确认能连上 SSH 服务。这一章给出工程配置的具体步骤和一段可运行的测试代码。5.1 工程属性里的包含目录与库目录设置假设你的工程叫SshDemo平台是 x64。右键工程 → 属性做以下配置C/C → 常规 → 附加包含目录添加D:\deps\libssh2\include和D:\vcpkg\installed\x64-windows\include。链接器 → 常规 → 附加库目录添加D:\deps\libssh2\lib和D:\vcpkg\installed\x64-windows\lib。链接器 → 输入 → 附加依赖项添加libssh2.lib、libcrypto.lib、libssl.lib、zlib.lib。如果是静态链接还要加上ws2_32.lib、crypt32.lib、user32.lib因为 OpenSSL 静态库依赖这些系统库。提示Debug 配置和 Release 配置要分别设置不要只改一个。另外如果 vcpkg 安装的是动态库libssh2.lib其实是导入库运行时仍然需要对应的 DLL。5.2 最小验证代码连接本地 SSH 并执行 whoami下面这段代码用 libssh2 连接本机 SSH 服务执行whoami命令并打印结果。你需要先在本机开启 OpenSSH 服务或者把host换成你实际能访问的 Linux 服务器 IP。#include stdio.h #include string.h #include libssh2.h #include winsock2.h #pragma comment(lib, ws2_32.lib) int main() { WSADATA wsadata; WSAStartup(MAKEWORD(2, 2), wsadata); LIBSSH2_SESSION *session libssh2_session_init(); if (!session) { printf(session init failed\n); return 1; } // 创建 TCP socket 并连接 22 端口 SOCKET sock socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in sin; sin.sin_family AF_INET; sin.sin_port htons(22); sin.sin_addr.s_addr inet_addr(127.0.0.1); if (connect(sock, (struct sockaddr*)sin, sizeof(sin)) ! 0) { printf(connect failed\n); return 1; } // 把 socket 交给 libssh2 会话 libssh2_session_set_blocking(session, 1); if (libssh2_session_handshake(session, sock)) { printf(handshake failed\n); return 1; } // 用用户名和密码认证实际项目建议用密钥 if (libssh2_userauth_password(session, your_user, your_password)) { printf(auth failed\n); return 1; } // 打开通道执行命令 LIBSSH2_CHANNEL *channel libssh2_channel_open_session(session); if (!channel) { printf(channel open failed\n); return 1; } libssh2_channel_exec(channel, whoami); char buf[1024]; int n; while ((n libssh2_channel_read(channel, buf, sizeof(buf) - 1)) 0) { buf[n] 0; printf(%s, buf); } libssh2_channel_close(channel); libssh2_channel_free(channel); libssh2_session_disconnect(session, bye); libssh2_session_free(session); closesocket(sock); WSACleanup(); return 0; }这段代码的逻辑很直接初始化 Winsock创建 libssh2 会话建立 TCP 连接握手密码认证打开通道执行命令读取输出最后释放资源。关键参数说明libssh2_session_set_blocking(session, 1)设置阻塞模式适合这种简单的同步测试libssh2_userauth_password的第二个和第三个参数分别是用户名和密码生产环境应该换成libssh2_userauth_publickey_fromfile用密钥认证。编译时如果报inet_addr已弃用可以在项目属性里把“SDL 检查”关掉或者改用inet_pton。5.3 验证成功与失败时的观察点如果一切正常程序会输出当前登录的用户名比如desktop-abc\user或者root。如果卡在handshake failed先用 PuTTY 或者ssh命令确认目标主机的 22 端口可达并且 SSH 服务版本不是太老。如果auth failed检查用户名密码或者目标服务器是否禁用了密码认证。如果编译时链接报错回到第 4 章对照排查。这一步跑通之后你就可以把 libssh2 集成到更大的项目里比如做批量命令下发、SFTP 上传下载。6. 进阶技巧用 CMake 的 find_package 让 libssh2 可复用手动在 VS 属性页里填路径的方式换一台机器或者换一个工程就要重来一遍团队协作时尤其痛苦。更优雅的做法是让 libssh2 的安装目录里带一个libssh2-config.cmake或者Findlibssh2.cmake这样其他工程可以直接用find_package(libssh2 REQUIRED)自动找到头文件和库。libssh2 官方 CMake 工程在INSTALL阶段其实已经生成了一个libssh2-config.cmake只是很多人没注意。6.1 确认安装目录下的 CMake 配置文件执行完INSTALL后去D:\deps\libssh2下看看有没有lib\cmake\libssh2\libssh2-config.cmake和libssh2-config-version.cmake。如果有说明安装是完整的。然后在你的工程CMakeLists.txt里这样写cmake_minimum_required(VERSION 3.10) project(SshDemo C) set(CMAKE_PREFIX_PATH D:/deps/libssh2;D:/vcpkg/installed/x64-windows) find_package(libssh2 REQUIRED) find_package(OpenSSL REQUIRED) find_package(ZLIB REQUIRED) add_executable(SshDemo main.c) target_link_libraries(SshDemo PRIVATE libssh2::libssh2 OpenSSL::Crypto OpenSSL::SSL ZLIB::ZLIB)CMAKE_PREFIX_PATH告诉 CMake 去哪些根目录找配置文件。libssh2::libssh2是配置文件里定义的导入目标它会自动带上头文件路径和链接库。OpenSSL::Crypto和OpenSSL::SSL是 CMake 内置的 FindOpenSSL 模块提供的目标ZLIB::ZLIB同理。这样写的好处是跨平台Linux 下只要装了libssh2-dev也能用同一份CMakeLists.txt。6.2 用批处理脚本固化编译流程为了避免每次换机器都重新敲一遍 CMake 命令我习惯写一个build_libssh2.bat放在源码目录旁边内容如下echo off set VCPKG_ROOTD:\vcpkg set LIBSSH2_SRCD:\src\libssh2-1.11.0 set INSTALL_DIRD:\deps\libssh2 if not exist build mkdir build cd build cmake -G Visual Studio 15 2017 -A x64 ^ -DCMAKE_INSTALL_PREFIX%INSTALL_DIR% ^ -DOPENSSL_ROOT_DIR%VCPKG_ROOT%\installed\x64-windows ^ -DZLIB_ROOT%VCPKG_ROOT%\installed\x64-windows ^ -DBUILD_SHARED_LIBSOFF ^ -DCMAKE_BUILD_TYPERelease ^ %LIBSSH2_SRC% cmake --build . --config Release --target INSTALL把这个脚本和源码放在一起新机器上只要改三个路径变量双击运行就能完成编译和安装。注意脚本要在 VS2017 的 x64 本机工具命令提示符里执行否则cmake可能找不到编译器。如果报cl.exe不是内部或外部命令说明当前命令行环境不对从开始菜单里重新打开正确的提示符。6.3 版本升级时的注意事项libssh2 从 1.9 到 1.11 在 API 上有一些细微变化比如libssh2_session_handshake的返回值处理、libssh2_userauth_publickey_frommemory的引入。升级版本时不要直接覆盖旧的头文件和库先在一个独立目录里编译新版本然后用dumpbin /exports对比新旧.lib的导出符号确认你的代码里用到的函数没有缺失。另外 OpenSSL 3.x 和 1.1.1 在 API 上有较大差异libssh2 1.11 已经支持 OpenSSL 3.x但如果你还在用 1.1.1升级 OpenSSL 时要同步确认 libssh2 的兼容性。我一般会在build目录里保留一份CMakeCache.txt出问题时能快速看出当时用的依赖路径和版本。这套流程我在三台不同配置的 Windows 机器上走过最慢的一步永远是 OpenSSL 的编译如果不想等直接用 vcpkg 装依赖是最省事的。编译 64 位 libssh2 本身并不复杂复杂的是让所有依赖的位数、运行库类型、链接方式保持一致。把第 4 章的排查清单存下来下次遇到报错先对照一遍能省下不少翻论坛的时间。希望帮到你。本文还有配套的精品资源点击获取