win7下用vs2017编译OpenVpn2.4.6源码并生成客户端 win7下用vs2013编译openvpn2.3.8源码并生成客户端

壹,准备工作

    一,下载Openvpn2.4.6的源码:请前往官网下载:https://www.openvpn.net/截止发稿时,最新的OpenVpn的版本是2.4.6

    二,下载openssl。

        openssl有两个来源,一个是从官网上下载源码,自己编译。不过openssl的编译也挺复杂,且本文重点也不是编译openssl。所以我们可以直接下载OpenSSL的安装包:http://slproweb.com/download/Win64OpenSSL-1_1_0h.exe。

            下载后直接安装,安装后openssl的dll库就出现在安装目录中了(如果安装时选择把文件放到系统目录,则dll就在系统目录中了)。

            注1:openssl 1.1.0开始由原先的libeay32.dll、ssleay32.dll变成了libcrypto-1_1.dll、libssl-1_1.dll,一些加密方式也发生了变化。

            注2:安装后如果没有把openssl的目录添加到环境变量中,可能在编译时就要设置openssl库的路径了。

            

    三,下载lzo,自行前往官网下载:http://www.oberhumer.com/opensource/lzo/,我下载的是2.10版本

    四,下载tap  9驱动,下载地址:https://download.csdn.net/download/sspdfn/10474182

    五,这里简单介绍下

        1、tap驱动是Open实现的核心,它可以在windows上创建一个虚拟网卡,所有的vpn操作都是基于此的。

        2、lzo是一解压缩库,类似于zip。

        3、openssl,加密用的,编译openvpn会用到这个。

    六,安装VS2015/2017

        编译2.4.6,要用到wdk10,这只有在vs2015之后的版本才有。笔者一开始用vs2013,但会有问题,详情在后面会写到。

        理论上,可以单独下载wdk10,然后vs2013引用 wdk10。这个方法没试过。不过好像wdk10从vs2015后就没有开发单独下载的包,都直接集成到VS IDE中了。有试过这个方法的同学,欢迎留言。

    七、vs2013编译openvpn2.3.8

        可以参考我的另一篇文章 

win7下用vs2013编译openvpn2.3.8源码并生成客户端


贰,编译

    一,新建一个工程OpenVpn

        1、新建一个工程,工程名叫OpenVpn,选择控制台应用程序,因为Openvpn的核心Openvpn.exe程序就是一个控制台程序。勾选空项目,点完成。

        2、把openvpn-2.4.6/src/openvpn中的所有*.h,*.c文件拖到OpenVpn目录中,并将这些文件载入到工程中。

        3、把lzo-2.10/src下的所有*.h,*.c,*.ch文件拖到OpenVpn目录中,并将这些文件载入工程中


    二、compat.lib的编译

        1、解压后的目录openvpn-2.4.6中有一个Openvpn.sln文件,用vs2013打开。打开后可以看到有四个项目,分别是Compat,msvc-generate,openvpn,openvpnserv。今天我们主要讲解对openvpn的编译。但编译openvpn时,有用到compat项目生成的lib,所以我们先把准备工作做好,先讲下compat.lib的编译。

          2、将compat目录复制到我们新建的Openvpn工程目录中

           在新建的OpenVpn项目中,右键解决方案,添加现有项目,打开compat目录,把compat.vcxproj添加进工程中。这样,就把compat工程添加到我们自己的OpenVpn中了。

        3、右键compat生成,报了一堆错,我们一个个解决。

              a、无法打开包括文件:config-msvc.h

            这个文件就在openvpn-2.4.6下。我们可以看到有一个config-msvc.h和config-msvc-version.h.in文件。这两个文件就是我们想要的。

            在OpenVpn项目中新建一个ThirdInclude目录,将上面两个文件添加到C++包含目录中。其他依赖项的头文件,我们都会放在这个ThirdInclude目录中。这个目录也会被OpenVpna项目用到。

            b、inet_ntop,inet_pton重定义问题。

            相比于openvpn2.3.8,我们没有碰到inet_ntop重定义的问题。因为在config-msvc.h文件末尾对此做了处理:

#if _WIN32_WINNT >= _WIN32_WINNT_VISTA
    #define HAVE_INET_NTOP
    #define HAVE_INET_PTON
#endif

            c、重新生成,就在win32-output中生成了compat.lib。

    三,编译OpenVpn

        右键OpenVpn生成,报了一堆错

        1、无法打开包括文件:config-msvc.h

        与编译compat.lib库一样的解决方法,不赘述。

        2、无法打开包括文件:compat.h

        将openvpn2.4.6/src/compat目录中的compat.h和compat-lz4.h

        3、无法打开lzo文件

        还记得我们下载的lzo文件吗。解压后,打到include目录,将该目录添加到c++的包含目录中

        4、无法打开openssl文件。

        我们之前安装了openssl吗,把安装目录中的include/openssl目录,复制到ThirdInclude目录中

        5、console_systemd.c中无法打开config.h

        这是因为console_systemd.c中引用了config.h,但在windows下,我们不会引用 config.h,所以可以注释或者修改为:

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

        5、无法打开openvpn-plugin.h,openvpn-msg.h文件

        该文件在openvpn2.3.8下的include目录中,将该目录中这两个文件复制到ThirdInclude目录中

         

        6、无法打开pkcs11-helper-1.0/pkcs11h-certificate.h

        这是一难点。因为当把这个文件导入后,会引发出更多问题,到后面就走向了绝路。但事实上,这个文件其实根本没必要引入!

        我们打开config-msvc.h编辑,并注释以下:

        //#define ENABLE_PKCS11 1


        7、无法打开tap-windows.h

        该文件在tap-windows-9.9.0_master的include目录中,将该文件复制到ThirdInclude中


        8、如果出现错误:未知字符:0x40

        打开config-msvc-version.h,将下面三个宏

#define OPENVPN_VERSION_RESOURCE @PRODUCT_VERSION_RESOURCE@
#define TAP_WIN_MIN_MAJOR @PRODUCT_TAP_WIN_MIN_MAJOR@
#define TAP_WIN_MIN_MINOR @PRODUCT_TAP_WIN_MIN_MINOR@

改为

#define OPENVPN_VERSION_RESOURCE  2.4.6 
#define TAP_WIN_MIN_MAJOR 9
#define TAP_WIN_MIN_MINOR 21

          9、使用了未定义类型"evp_md_ctx_st"

         在config-msvc.h中编辑,把 ENABLE_CRYPTO;ENABLE_CRYPTO_OPENSSL; 这两个宏注释

          另外,再添加三个宏:

_WINSOCK_DEPRECATED_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
_CRT_NONSTDC_NO_WARNINGS
    到预处理器定义中


        10,错误C2146


error C2146: 语法错误: 缺少“)”(在标识符“PRIi64”的前面)	\openvpn\error.c	345.

PRIi6的定义是:

#define PRIi64       _PFX_64 "i"

在c:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\inttypes.h中被定义。但可能vs2017中没有相关定义。

这个定义只有在error.c 第345行中有引用。所以我们可以把代码改为:

fprintf(fp, "%i.%06lu %x %s%s%s%s",
        (int64_t)tv.tv_sec,
        (unsigned long)tv.tv_usec,
        flags,
        prefix,
        prefix_sep,
        m1,
        "\n");


         10、无法解析的外部符号 _imp_closesocket@4

        右键属性,链接器->输入->附加依赖项,添加wininet.lib;crypt32.lib;iphlpapi.lib;winmm.lib;ws2_32.lib;

        

        11、无法解析的外部符号 _basename。

        还记得我们编译出的compat.lib库吗。在VpnProj下新建lib目录,把compat.lib复制到此。然后把lib目录添加到属性-》链接器-》常规-》附加库目录中。然后把compat.lib添加到附加依赖项中。

        12、无法解析的外部符号 FwpmEngineClose0 

        FwpmEngineClose0有用到wdk10中的lib库。百度解决方法,说是要

添加库:ntoskrnl.lib ndis.lib fwpkclnt.lib uuid.lib

添加宏定义:NDIS_SUPPORT_NDIS6

     但没用。一开始我是用vs2013来编译,但vs2013中没有相关的库,或者准确讲上面几个库,只有wdk10中才有。

        为了解决这个问题,我下载了vs2017,并安装。(注:用vs2015安装也可以)

       无论是vs2015,还是vs2017,安装时要勾选wdk10,选最新的那个版本。安装完后,用vs2017打开工程,就没报这个错了。

        13、无法解析的外部符号 fwpmGetAppIdFromFileName0

        添加附加依赖项 Fwpuclnt.lib;


        14、生成项目,编译成功,至此大功告成。

       

        

四、如果出现以下错误

       

     1、如果出现语法错误;

问题定位到
const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
  __attribute__((nonnull));

无法识别__attribute,这是一个编译选项,注释就行。

const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
/*  __attribute__((nonnull))*/;

   



猜你喜欢

转载自blog.csdn.net/sspdfn/article/details/80665313