编译环境:Win10 + Visual Studio 2019
一、编译OpenSSL
openssl下载地址:openssl/openssl
1.1 编译
以编译64位为例,假设openssl源码放在c:\ddksample\openssl。
开始菜单中“以管理员身份运行”“x64 Native Tools Command Prompt for VS 2019”
cd c:\ddksample\openssl perl Configure VC-WIN64A nmake depend nmake install_dev
注:32位时,相关步骤改为“x86 Native Tools Command Prompt for VS 2019”、“perl Configure VC-WIN32”

成功后便会生成C:\Program Files\OpenSSL目录,该目录下三个子目录:bin、include和lib。

1.2 不以管理员身份运行或如何把编译结果放到自定义目录
如果不是以管理员身份运行,在nmake install_dev步骤,编译出libcrypto-3.dll、libssl-3.dll后会报下面错误。
*** Installing runtime libraries Can't Open C:/Program Files/OpenSSL/bin/libcrypto-3.dll at .\util\copy.pl line 69. NMAKE : fatal error U1077: 'if' : return code '0xd' Stop.
根据信息进入<openssl>/Configurations/windows-makefile.tmpl,错误是发生在下面代码中的copy.pl $(INSTALL_SHLIBS)时。
<openssl>\Configurations\windows-makefile.tmpl install_runtime_libs: build_libs @if "$(INSTALLTOP)"=="" ( $(ECHO) "INSTALLTOP should not be empty" & exit 1 ) @$(ECHO) "*** Installing runtime libraries" @"$(PERL)" "$(SRCDIR)\util\mkdir-p.pl" "$(INSTALLTOP)\bin" @if not "$(SHLIBS)"=="" \ "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_SHLIBS) "$(INSTALLTOP)\bin" @if not "$(SHLIBS)"=="" \ "$(PERL)" "$(SRCDIR)\util\copy.pl" $(INSTALL_SHLIBPDBS) \ "$(INSTALLTOP)\bin" 以下是三个变量的值。 INSTALL_SHLIBS: libcrypto-3.dll libssl-3.dll INSTALL_SHLIBPDBS: libcrypto-3.pdb libssl-3.pdb INSTALLTOP: C:\Program Files\OpenSSL
脚本逻辑:在C:\Program Files新建OpenSSL\bin目录,然后执行两次复制。第一次是把libcrypto-3.dll libssl-3.dll复制到bin,第二次是把libcrypto-3.pdb libssl-3.pdb复制到bin。提示的错误出在第一次复制copy.pl时,但其实上一步mkdir-p.pl就没创建OpenSSL\bin目录。即使我在C:\Program Files下手动创建出OpenSSL\bin,后面的复制还是失败。
问题原因:C:\Program Files是受操作系统保护的目录,操作它需要管理员权限,mdir-p.pl、copy.pl因权限不够而失败。既是如此,改为让$(INSTALLTOP)指向非操作系统目录,像C:\ddksample\install_openssl。要怎么改,让先看INSTALLTOP是怎么被赋值。
INSTALLTOP=$(INSTALLTOP_dev)$(INSTALLTOP_dir)
不改时后面两变量值
INSTALLTOP_dev: C: INSTALLTOP_dir: \Program Files\OpenSSL
于是要改的就是INSTALLTOP_dir。
INSTALLTOP_dir={- canonpath($prefix_dir) -} 改为 INSTALLTOP_dir="\ddksample\install_openssl"
经过测试,$(INSTALLTOP)改为C:\ddksample\install_openssl后,install_openssl下成功生成openssl的编译结果。
二、编译openh264
须要openh264编/解码时才须要编译openh264,即打开了WITH_OPENH264开关。
- 下载openh264源码:cisco/openh264
- 安装MinGW,假设安装到的目录是“C:\MinGW”。添加C:\MinGW\bin到系统环境变量Path中。注意,MSYS是MinGW内的包,默认没安装的话,须要单独安装。
- 运行Visual Studio 2019的Developer Command Prompt for VS2019,操作细节参考“http://msdn.microsoft.com/en-us/library/ms229859(v=vs.110).aspx”。
- 在命令行窗口中,执行C:\MinGW\msys\1.0\msys.bat,把MSYS命令行窗口弹出来。
- MSYS中,把当前目前切到openh264源码所在目录,像“c:/ddksample/openh264”。
- 在openh264目录,执行make OS=msvc(注意大小写)。make结束后,openh264目录下会生成openh264.dll等数个文件。
图3 MSYS是MinGW内的包
编译openh264时,encoder和encoder会存在同名头文件。举个例子,deblocking.h,<openh264>/codec/encoder/core/inc和<openh264>/codec/decoder/core/inc都有这么文件,但内容不一样。这样一来,decoder下的cpp若需要deblocking.h,但找到的是encoder目录下时,编译自然失败。对不会在每个cpp源文件设include目录的项目,这问题还真不好解决,所以像Rose,既然只用openh264的encoder部分,直接不编译decoder,这样也就不必在include中增加decoder/core/inc、decoder/plug/inc,encoder也就不会找错了。
三、编译FreeRDP
FreeRDP下载地址:FreeRDP/FreeRDP
3.1 编译
- <FreeRDP>下新建目录“out”,作为sln的生成目录。
- 运行CMake(cmake-gui)。
- 单击“Configuration”。
- 单击“Generate”,cmake便会在out目下生成工程文件FreeRDP.sln。
图4 CMake: Configure成功后
3.2 “Configuration”时可能出现的错误
“Configuration”过程极可能会出错,以下是可能出现在错误及修改方法。
<FreeRDP>\CMakeCPack.cmake ------ SET(CPACK_BINARY_ZIP "ON") 改为 # SET(CPACK_BINARY_ZIP "ON") ==>错误提示 CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.16/Modules/CPack.cmake:585 (option): Policy CMP0077 is not set: option() honors normal variables. Run "cmake --help-policy CMP0077" for policy details. Use the cmake_policy command to set the policy and suppress this warning. For compatibility with older versions of CMake, option is clearing the normal variable 'CPACK_BINARY_ZIP'. Call Stack (most recent call first): CMakeCPack.cmake:102 (include) CMakeLists.txt:1131 (include) This warning is for project developers. Use -Wno-dev to suppress it.
错误概述。cmake中的option命令提供一个让用户可指定命令行参数的可选项。
option(<variable> "<help_text>" [value]) 实例:option(TEST_DEBUG "option for debug" OFF)
opation提供了一个选项,用户可以把它置为ON或OFF。如果没有为该选项指定初始值<value>,默认为OFF。运行命令行,在执行cmake时可以指定一些参数(-D修饰),这里的选项就是那些参数。如果命令行中没专门指定参数要设定到的值,则使用option(<variable> "<help_text>" [value])中的value,否则使用命令行中给的值。option更多注释参考“CMake option选项开关”。如果<variable>已经被定义为一个正常变量,该命令不做任何动作,这正是此处发生的CMP0077。为避免这问题,于是注释掉正常变量CPACK_BINARY_ZIP。
<FreeRDP>/cmake/ConfigOptions.cmake ------ option(WITH_CLANG_FORMAT "Detect clang-format. run 'cmake --build . --target clangformat' to format." ON) 改为 option(WITH_CLANG_FORMAT "Detect clang-format. run 'cmake --build . --target clangformat' to format." OFF) ==>错误提示 CMake Warning at cmake/ClangFormat.cmake:14 (message): clang-format not found in path! code format target not available. Call Stack (most recent call first): CMakeLists.txt:55 (include)
错误概述。系统没可以判断CLANG_FORMAT的工具,那就改为默认不查。
<FreeRDP>/cmake/FindOpenSSL.cmake ------ list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR) list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR) from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR) list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX) from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX) list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH) 改为 # list(GET OPENSSL_VERSION_LIST 0 OPENSSL_VERSION_MAJOR) # list(GET OPENSSL_VERSION_LIST 1 OPENSSL_VERSION_MINOR) from_hex("${OPENSSL_VERSION_MINOR}" OPENSSL_VERSION_MINOR) # list(GET OPENSSL_VERSION_LIST 2 OPENSSL_VERSION_FIX) from_hex("${OPENSSL_VERSION_FIX}" OPENSSL_VERSION_FIX) # list(GET OPENSSL_VERSION_LIST 3 OPENSSL_VERSION_PATCH) 306, 307, 309, 311 ==>错误提示 CMake Error at cmake/FindOpenSSL.cmake:306 (list): list GET given empty list Call Stack (most recent call first): cmake/FindFeature.cmake:16 (find_package) CMakeLists.txt:854 (find_feature) CMake Error at cmake/FindOpenSSL.cmake:307 (list): list GET given empty list Call Stack (most recent call first): cmake/FindFeature.cmake:16 (find_package) CMakeLists.txt:854 (find_feature) CMake Error at cmake/FindOpenSSL.cmake:309 (list): list GET given empty list Call Stack (most recent call first): cmake/FindFeature.cmake:16 (find_package) CMakeLists.txt:854 (find_feature) CMake Error at cmake/FindOpenSSL.cmake:311 (list): list GET given empty list Call Stack (most recent call first): cmake/FindFeature.cmake:16 (find_package) CMakeLists.txt:854 (find_feature)