资讯动态

VS2017编译libssh2:解决CMake找不到OpenSSL与x64链接失败

发布时间:2026/10/20 15:12:47 来源:尧图企业网站定制
简介本资源是面向Windows平台C/C开发者的libssh2库64位编译成果包专为VS2017环境定制解决在64位Windows应用中集成SSH2协议支持的核心依赖问题适用于远程安全通信、SFTP文件传输及嵌入式SSH客户端开发等实际场景。压缩包共115个文件含109个头文件.h——涵盖libssh2核心接口与OpenSSL兼容层如ssl.h、evp.h、tls1.h、ec.h等3个静态库文件.lib用于链接2个运行时DLLlibcrypto-1_1-x64.dll、libssl-1_1-x64.dll保障加密功能另有1个示例源码main.cpp便于快速验证调用流程整体体积仅2.14MB轻量易集成。已有1517人学习下载资源结构即开即用无需重复编译可直接将头文件目录纳入包含路径、链接libssh2.lib并部署对应DLL显著降低跨平台网络库接入门槛。1. VS2017 编译 libssh2一个看似简单却让无数人卡在 CMake 报错、OpenSSL 链接失败、x64 平台切换失灵的“经典翻车现场”你是不是也遇到过项目里突然要加 SFTP 文件传输技术方案定了 libssh2文档写得清清楚楚“支持 Windows”结果一打开 VS2017 就懵了——CMake GUI 点 Configure 直接红屏报Could NOT find OpenSSL哪怕你明明装了 OpenSSL 1.1.1w或者好不容易过了 OpenSSL 这关生成的工程却是 Win32x86平台一编译就提示LNK2019: unresolved external symbol __imp__BIO_new更玄学的是改完平台再 ConfigureCMake 又清空缓存重来前功尽弃。这不是小众需求而是某跨平台系统在某高校实验室做内网设备管理模块时的真实起点也是某公司做远程运维 SDK 时绕不开的底层依赖。它不难但版本链极敏感VS2017 对应的 MSVC 工具集是 v141libssh2 1.10.x 起已默认要求 OpenSSL 1.1.1而官方预编译包又只提供 x86 或静态链接版——你要的是一个能被你的 x64 Release 工程直接#include libssh2.h并#pragma comment(lib, libssh2.lib)的干净动态库。本文全程基于 VS2017 Communityv15.9.39、CMake 3.22.1、OpenSSL 1.1.1w、libssh2 1.10.0所有路径、参数、错误日志均来自真实构建过程不跳步、不省略、不假设你“已经装好”。2. 环境准备三个必须亲手验证的组件及其精确版本锚点2.1 安装 VS2017 并确认 v141 工具集可用VS2017 的关键不是“装了”而是“装对了组件”。很多开发者用默认选项安装后发现没有x64 Native Tools Command Prompt for VS 2017或 CMake 找不到cl.exe根源在于缺失C 通用 Windows 平台工具和Windows 10 SDK10.0.17763.0 或更高。提示不要用 VS Installer 的“修改”功能临时勾选——它可能不刷新环境变量。建议卸载后重装勾选以下三项Desktop development with C必选含 v141 工具集CMake tools for Visual Studio非必须但能避免命令行手动指定生成器Windows 10 SDK (10.0.17763.0)libssh2 的winsock2.h兼容性依赖此版本验证方式打开「x64 Native Tools Command Prompt for VS 2017」执行cl应输出类似Microsoft (R) C/C Optimizing Compiler Version 19.16.27045 for x64。若报cl 不是内部或外部命令说明环境变量未加载需重启命令提示符或手动运行C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat x642.2 下载并编译 OpenSSL 1.1.1wx64 动态库版libssh2 1.10 强依赖 OpenSSL 1.1.1且必须与你的目标平台x64和运行时/MD 或 /MT严格匹配。官方预编译包多为 x86 或静态库.lib直接链接会导致 LNK2001/LNK2019。我们必须自己编译 OpenSSL x64 动态版。步骤清单下载 OpenSSL 1.1.1w 源码 https://www.openssl.org/source/openssl-1.1.1w.tar.gz 解压到D:\deps\openssl-1.1.1w打开「x64 Native Tools Command Prompt for VS 2017」进入源码目录cd /d D:\deps\openssl-1.1.1w配置为 x64 动态库关键no-staticVC-WIN64Aperl Configure VC-WIN64A no-shared no-static --prefixD:\deps\openssl-x64 --openssldirD:\deps\openssl-x64VC-WIN64A强制 x64 构建不是VC-WIN32no-shared先禁用共享库即 DLL因为 libssh2 默认链接 OpenSSL 静态库但我们后续会启用它所以这步只是确保配置无误--prefix指定安装根目录避免污染系统路径生成 Makefile 并编译nmake nmake install编译成功后D:\deps\openssl-x64下应有include\openssl\和lib\目录其中lib\libcrypto.lib和lib\libssl.lib是我们需要的导入库.lib对应bin\libcrypto-1_1-x64.dll运行时需部署。2.3 获取 libssh2 源码并确认分支兼容性libssh2 官方 GitHub 主干main 分支在 2023 年后已移除对 VS2017 的 CI 支持但1.10.0 tag2021年12月发布是最后一个明确标注支持 VS2017 的稳定版。切勿使用 master 或 1.11.x ——它们默认启用 C11 特性VS2017 的 MSVC v141 编译器不完全支持_Generic等语法会直接报错error C2061: syntax error: identifier _Generic。下载地址https://github.com/libssh2/libssh2/archive/refs/tags/libssh2-1.10.0.tar.gz解压至D:\deps\libssh2-1.10.0验证关键文件打开D:\deps\libssh2-1.10.0\CMakeLists.txt搜索cmake_minimum_required应为VERSION 3.10VS2017 自带 CMake 3.10 兼容搜索project(应为project(libssh2 C)无CXX——这是纯 C 库避免 C 运行时冲突。3. CMake 配置四步精准控制平台、运行时与 OpenSSL 路径3.1 创建独立构建目录并启动 CMake GUI永远不要在源码目录下cmake .libssh2 的 CMake 脚本会生成大量中间文件混入源码树后极易导致缓存污染。创建干净构建目录mkdir D:\build\libssh2-x64 cd /d D:\build\libssh2-x64然后启动 CMake GUI非命令行Where is the source code:D:/deps/libssh2-1.10.0Where to build the binaries:D:/build/libssh2-x64点击Configure→ 弹出窗口选择Visual Studio 15 2017 Win64注意末尾的Win64不是Visual Studio 15 2017为什么必须用 GUI因为 VS2017 的 CMake 工具链对CMAKE_GENERATOR_PLATFORM的识别不稳定命令行cmake -G Visual Studio 15 2017 Win64有时会降级为 Win32。GUI 强制锁定平台。3.2 关键变量设置覆盖默认值直击三大痛点首次 Configure 后CMake 会报红Could NOT find OpenSSL此时不要慌——这是预期行为。在 GUI 变量列表中找到并修改以下项勾选Advanced才可见变量名值说明CMAKE_BUILD_TYPEReleaselibssh2 默认Empty不设则生成 Debug/Release 混合工程BUILD_SHARED_LIBSON生成libssh2.dlllibssh2.lib导入库而非静态libssh2_static.lib多数项目需要 DLL 方式ENABLE_ZLIBOFFlibssh2 的 zlib 压缩是可选的VS2017 下 zlib 依赖易出错初装建议关闭OPENSSL_INCLUDE_DIRD:/deps/openssl-x64/include必须精确到include目录否则找不到openssl/ssl.hOPENSSL_SSL_LIBRARYD:/deps/openssl-x64/lib/libssl.lib指向 OpenSSL 的 SSL 导入库OPENSSL_CRYPTO_LIBRARYD:/deps/openssl-x64/lib/libcrypto.lib指向 OpenSSL 的 Crypto 导入库注意OPENSSL_SSL_LIBRARY和OPENSSL_CRYPTO_LIBRARY必须是.lib文件路径不是目录CMake 会自动推导对应的.dll名称libssl-1_1-x64.dll但不会帮你拷贝 DLL。3.3 二次 Configure 与 Generate确认无红标后生成 VS 工程修改完上述变量点击Configure。这次应无红色报错底部日志显示-- Found OpenSSL: D:/deps/openssl-x64/lib/libssl.lib (found version 1.1.1w) -- Configuring done -- Generating done -- Build files have been written to: D:/build/libssh2-x64点击GenerateCMake 会在D:\build\libssh2-x64下生成libssh2.sln。验证生成结果打开该目录检查是否存在libssh2.slnVisual Studio 解决方案CMakeCache.txt确认BUILD_SHARED_LIBS:BOOLONCMakeFiles/下有libssh2.dir/证明目标已注册4. 编译与安装从 sln 编译到部署 DLL 的完整闭环4.1 在 Visual Studio 中编译解决方案双击D:\build\libssh2-x64\libssh2.sln用 VS2017 打开。此时解决方案资源管理器中应有多个项目重点关注libssh2主动态库项目生成libssh2.dll和libssh2.libexample示例程序用于后续验证tests测试套件可跳过编译前必做三件事顶部工具栏将Solution Configuration设为ReleaseSolution Platform设为x64不是Active Solution Platform下拉框里的默认值右键libssh2项目 →Properties→Configuration Properties→General→ 确认Configuration Type为Dynamic Library (.dll)右键libssh2→Build或按CtrlShiftB编译过程约 1–2 分钟。成功后输出窗口显示 Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped 。4.2 提取编译产物DLL、LIB、头文件的物理位置编译完成后产物分散在多个子目录。按用途整理类型路径说明动态库DLLD:\build\libssh2-x64\Release\libssh2.dll运行时必须随 exe 部署导入库LIBD:\build\libssh2-x64\Release\libssh2.lib链接时使用对应 DLL 的符号表头文件D:\deps\libssh2-1.10.0\include\libssh2.h等需复制到你的项目include/目录下OpenSSL DLLD:\deps\openssl-x64\bin\libssl-1_1-x64.dllD:\deps\openssl-x64\bin\libcrypto-1_1-x64.dlllibssh2 运行时依赖必须同目录提示不要直接引用D:\deps\libssh2-1.10.0\include作为项目包含目录——源码目录可能被清理。标准做法是新建D:\myproject\3rdparty\libssh2\include将libssh2-1.10.0\include\libssh2.h及其子目录libssh2\全部复制过去。4.3 安装到自定义前缀可选但推荐libssh2 的 CMake 支持INSTALL目标可一键部署头文件、库、DLL 到统一目录避免路径混乱在 VS2017 中右键解决方案 →Build Solution确保所有项目已编译右键INSTALL项目 →Build若无INSTALL项目说明 CMake 未启用安装规则。回到D:\build\libssh2-x64用文本编辑器打开CMakeCache.txt确认CMAKE_INSTALL_PREFIX:PATHD:/install/libssh2-x64已设置然后重新ConfigureGenerate。成功后D:\install\libssh2-x64下结构为include/ libssh2.h libssh2/ publickey.h sftp.h ... lib/ libssh2.lib bin/ libssh2.dll libssl-1_1-x64.dll libcrypto-1_1-x64.dll此目录可直接作为你项目的第三方依赖根目录。5. 常见问题排查五条血泪经验专治 CMake 红屏、LNK2019、平台错乱5.1 现象CMake Configure 报Could NOT find OpenSSL但路径明明正确原因OPENSSL_INCLUDE_DIR指向了D:/deps/openssl-x64根目录而非D:/deps/openssl-x64/include或lib/下缺少libssl.lib因 OpenSSL 编译时未执行nmake install。解决用文件管理器确认D:/deps/openssl-x64/include/openssl/ssl.h存在运行dir D:\deps\openssl-x64\lib\*.lib确保输出含libssl.lib在 CMake GUI 中删除OPENSSL_*所有变量右键 →Delete重新输入完整路径。5.2 现象VS2017 编译libssh2时大量LNK2019: unresolved external symbol __imp__BIO_new原因libssh2 链接了 OpenSSL 的导入库但 OpenSSL 本身是静态编译no-shared导致符号未导出或libssh2项目属性中Configuration Type错设为Application (.exe)。解决重新编译 OpenSSL必须用no-shared配置见 2.2 节nmake install后lib/下应有libssl.lib在 VS 中右键libssh2→Properties→General→Configuration Type必须为Dynamic Library (.dll)。5.3 现象生成的libssh2.dll无法被dumpbin /dependents识别 OpenSSL 依赖原因libssh2项目链接器设置中Additional Dependencies未包含libssl.lib和libcrypto.lib或 CMake 生成时未传递-lssl -lcrypto。解决右键libssh2→Properties→Linker→Input→Additional Dependencies添加libssl.lib;libcrypto.lib同时在Linker→General→Additional Library Directories添加D:\deps\openssl-x64\lib5.4 现象example项目编译通过但运行时报0xc000007b架构不匹配原因example.exe是 x64但加载了 x86 版 OpenSSL DLL如libssl-1_1.dll而非libssl-1_1-x64.dll或PATH环境变量指向了其他目录下的 x86 DLL。解决用Process MonitorSysinternals 工具过滤example.exe的CreateFile事件看它实际加载了哪个libssl*.dll将D:\deps\openssl-x64\bin\加入PATH最前面或直接把libssl-1_1-x64.dll和libcrypto-1_1-x64.dll复制到example.exe同目录。5.5 现象CMake Generate 后VS2017 中libssh2项目平台显示Win32手动改为x64后编译失败原因CMake Generator 选择错误。Visual Studio 15 2017无 Win64会生成 Win32 工程即使你在 VS 里强行切换平台MSBuild 仍调用 x86 工具链。解决彻底删除D:\build\libssh2-x64目录重新创建空目录CMake GUI 中Configure时必须选择Visual Studio 15 2017 Win64名称含 Win64再次 Configure确认CMAKE_GENERATOR_PLATFORM:INTERNALWin64出现在CMakeCache.txt中。6. 验证与集成用一个最小 SFTP 示例跑通整个链路6.1 编写验证代码50 行完成 SFTP 连接与文件列表在D:\build\libssh2-x64\example\下新建sftp_test.c复用 libssh2 自带示例框架// sftp_test.c #include libssh2.h #include libssh2_sftp.h #include stdio.h #include stdlib.h #include string.h int main(int argc, char *argv[]) { const char *host 127.0.0.1; // 替换为你的 SFTP 服务器 const char *user test; const char *pass password; LIBSSH2_SESSION *session; LIBSSH2_SFTP *sftp; LIBSSH2_SFTP_HANDLE *handle; struct libssh2_sftp_attributes attrs; // 初始化 libssh2 libssh2_init(0); // 创建 socket简化版生产环境需用阻塞/非阻塞 socket int sock socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in sin {0}; sin.sin_family AF_INET; sin.sin_port htons(22); sin.sin_addr.s_addr inet_addr(host); if (connect(sock, (struct sockaddr*)sin, sizeof(sin)) ! 0) { fprintf(stderr, Failed to connect\n); return -1; } // 建立 SSH 会话 session libssh2_session_init(); libssh2_session_handshake(session, sock); libssh2_userauth_password(session, user, pass); // 初始化 SFTP sftp libssh2_sftp_init(session); if (!sftp) { fprintf(stderr, Unable to init SFTP session\n); return -1; } // 打开根目录 handle libssh2_sftp_opendir(sftp, /); if (handle) { fprintf(stdout, SFTP connection OK. Root dir listing:\n); char buf[1024]; while (libssh2_sftp_readdir(handle, buf, sizeof(buf), attrs) 0) { printf( %s\n, buf); } libssh2_sftp_closedir(handle); } else { fprintf(stderr, Failed to open root dir\n); } // 清理 libssh2_sftp_shutdown(sftp); libssh2_session_disconnect(session, Normal shutdown); libssh2_session_free(session); closesocket(sock); libssh2_exit(); return 0; }6.2 在 VS2017 中编译并链接此示例将sftp_test.c加入example项目右键example→Add→Existing Item右键example→Properties→Configuration PropertiesGeneral→Configuration Type:Application (.exe)C/C→General→Additional Include Directories:D:\deps\libssh2-1.10.0\include;D:\deps\openssl-x64\includeLinker→General→Additional Library Directories:D:\build\libssh2-x64\Release;D:\deps\openssl-x64\libLinker→Input→Additional Dependencies:libssh2.lib;libssl.lib;libcrypto.lib;ws2_32.lib编译example项目生成example.exe6.3 运行时部署与调试技巧生成的example.exe依赖四个 DLLlibssh2.dll你的编译产物libssl-1_1-x64.dll,libcrypto-1_1-x64.dllOpenSSLVCRUNTIME140.dll,MSVCP140.dllVS2017 运行时部署方案二选一方案 A开发机将D:\build\libssh2-x64\Release\libssh2.dll和D:\deps\openssl-x64\bin\*.dll全部复制到example.exe同目录方案 B目标机安装 Microsoft Visual C 2015–2019 Redistributable (x64) 并将 OpenSSL DLL 放入C:\Windows\System32不推荐或应用目录。调试技巧用depends.exeDependency Walker打开example.exe确认所有依赖 DLL 的架构均为x64且无红色问号若报libssh2_session_handshake返回NULL用 Wireshark 抓包确认 TCP 22 端口是否可达在代码中插入fprintf(stderr, Error: %d\n, libssh2_session_last_error(session, NULL, 0, 0));获取具体错误码。从那以后我每次给新同事配 libssh2 环境都强制走一遍「VS2017 Win64 生成器 → OpenSSL 1.1.1w no-shared 编译 → CMake GUI 手动填 OPENSSL_* 路径 → example.exe 验证」这个闭环哪怕多花 15 分钟也比后期在客户现场 debug LNK2019 强十倍。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑