标签归档:cmake

在Win10中编译 Linphone SDK 的x64版本

官网提供了Win32的编译结果,可以直接下载到,但是链接的时候会出现如下错误:

Severity	Code	Description	Project	File	Line	Suppression State
Error	LNK2019	unresolved external symbol __imp_linphone_auth_info_new referenced in function "xxxxxxxxx

可以确认的是sdk的lib文件已经正确配置且可以加载,用dependency walker查看dll,也能看到linphone_auth_info_new()函数,但是以某种变态方式打开lib文件,发现此函数导出格式为:

__imp__linphone_auth_info_new

而不是想象中的

__imp_linphone_auth_info_new

根据以上错误,链接器的确是找’__imp_linphone_auth_info_new’而不是’__imp__linphone_auth_info_new’。 不确定为什么会出现这样的错误,但是官网给的文件名是带Win32的,不确定是win32 x86的,还是win32 x64的,无论如何,值得在本机编译一个x64的版本测试此链接问题。

在Windows下编译Linphone SDK 的确是一大考验,中间会碰到各种问题

git clone 源代码

官网git克隆源代码一定要带上’–recursive’参数,否则很多模块默认不下载:

git clone https://gitlab.linphone.org/BC/public/linphone-sdk.git --recursive

同样,更新源代码也得带上此参数:

git submodule update --init --recursive

python安装

linphone sdk是用cmake管理工程的,所以上来就先执行一下cmake指令:

cmake -H. -Bbuild -G"Visual Studio 16 2019" -Ax64

发现提示说python缺少pystache模块,打开命令模式,直接执行

pip install pystache

此模块安装比较顺利,再次执行以上指令,提示已经发现pystache模块,但是提示缺少six模块,继续执行:

pip install six

这次就没这么幸运了,提示连接错误,无法安装six模块,尝试很多方法无效,最终用某墙软件在app级别X墙,再次执行以上指令 ,成功下载并安装上了six模块。其实解决这个问题还有个办法,就是到six官网下载six包,直接本地安装,但本人没尝试过。

MinGW安装

linphone sdk 还用到了 pkg-config,但是这是类Unix系统下的东西,在windows下可以用MinGW来做到。 MinGW有两个版本,一个是MinGW,一个是Mingw-w64,注意,一定要安装MinGW版本,而且路径一定是C盘的C:\MinGW目录,因为linphone cmake脚本把这个路径写死了,直接用了C:\MinGW\bin目录。如果你已经安装到了不同目录,改一下CMakeList.txt文件也可以。

yasm安装

第一次接触yasm,不理解yasm是个什么东西,也不知道用来干什么,就按照说明做就是了,从官网下载一份放到C:\vsyasm-1.3.0-win64目录下,在系统环境变量的Path下加入此路径。 注意,这里可能要确保其有写权限,所以最好放到user目录下。注意一定要把原exe程序名改为yasm.exe,否则还会报找不到yasm.exe的错误。

pkg-config下载及安装

cmake会调用下载指令动态下载pgk-config程序,并将其放到MinGW\bin及其相关目录下。参考D:\linphone-sdk\cmake-builder\cmake\CheckBuildTools.cmake文件中的106~136行。问题在于,pkg及相关文件能正确下载到D:\linphone-sdk\build\desktop\pkg-config目录,但是拷贝到C:\MinGW\bin目录会出错,即便是cmd.exe程序以管理员方式打开也不行。 我的解决方法是,既然文件都被正确下载并解压到了D:\linphone-sdk\build\desktop\pkg-config目录,那么直接全选并粘贴到C:\MinGW目录下即可。

再次执行cmake生成指令,cmake配置通过了。

编译

生成配置成功后,会在build目录下生成sln解决方案文件,但是不要用vs打开此文件进行编译,因为编译过程会有错误,而vs只能提示编译规则rule有错误,不能提示代码错误,无法看出问题所在,且sdk编译只给出了rule文件,并没有将源代码包含到工程中,无法看到源代码,而命令模式会有更多更详细的信息 。

在命令模式下执行以下命令即可:

cmake --build build

编译结果会生成到build目录下的inphone-sdk\desktop目录下。

  • 注意,以上指令默认生成的是debug版,要生成release版,必须执行:
cmake --build build --config release

错误的链接debug版,会导致未知错误。

编译错误处理

EP_bctoolbox.vcprj

提示EP_bctoolbox项目编译出错,但是从linphone-sdk.sln文件中无法定位问题,直接打开EP_bctoolbox.vcprj,工程,再次编译,可以双击定位到错误点。 bctoolbox/include/bctoolbox/crypto.hh文件中增加

#include <string>

EP_linphone

EP_linphone项目中的private_functions.h文件,vs中编译只是提示如下错误:

Severity	Code	Description	Project	File	Line	Suppression State
Error	C2220	the following warning is treated as an error (compiling source file D:\linphone-sdk\liblinphone\coreapi\xml.c) [D:\linphone-sdk\build\WORK\desktop\Build\linphone\coreapi\linphone-coreapi.vcxproj]	EP_linphone	D:\linphone-sdk\liblinphone\coreapi\private_functions.h	400	

看了还是不知道什么错误,双击定位到第400行,其实貌似也没啥大问题(刚开始以为是函数定义找不到,notepad++打开找了半天也没找到),但其实如果在cmd中编译,发现是这个文件编码有问题,网上找了一堆什么另存为的方式都没解决。

既然是编码问题,那一定是文件BOM出问题了,我用了一招借尸还魂,先把private_functions.h文件拷贝出去备份好,另外找了一个编码没问题的.h文件,将文件名改为private_functions.h,然后打开,将备份的private_functions.h的内容全部粘贴到这个新文件里,重新编译,成功。

同样的编码问题出现在D:\linphone-sdk\liblinphone\tester\message_tester.c文件中,但是这是在BC_ASSERT_STRING_EQUAL(text, “TBD:WHAT?”)语句中的引号中包含了不可识别的字符串导致的,我也不知道是什么,一堆乱码,先改成可识别字符(”TBD:WHAT?”)先编译过去再说。

以上改完后,全部项目编译通过。

结论

官网提供的linphone-sdk-win32-xxx的确有问题,是不是win32的dll导出就是两个下划线?没仔细研究过。

用以上编译的x64文件替换后,项目链接成功。

附:linphone-desktop的编译

desktop版利用Qt作为界面库进行编译,需要设置Qt路径,没有太多可说的。先执行指令生成解决方案:

cmake -H. -Bbuild -G"Visual Studio 16 2019" -Ax64

基本不会有什么问题,然后执行编译指令:

cmake --build build --config release --target all_build

1、vpx.camke错误

执行以上指令,会报sdk生成错误:

    CMake Error at builders/vpx.cmake:122 (file):
      file failed to open for reading (No such file or directory):

        D:/VoIP_ICT_SF5GYY/linphone-desktop/build/WORK/desktop/windowsenv_include.txt
    Call Stack (most recent call first):
      cmake/CMakeLists.txt:316 (include)
      cmake/CMakeLists.txt:331 (linphone_builder_include_builder)
      cmake/CMakeLists.txt:376 (linphone_builder_add_builder_to_target)
      cmake/CMakeLists.txt:376 (linphone_builder_add_builder_to_target)
      cmake/CMakeLists.txt:285 (linphone_builder_add_builder_to_target)
      cmake/CMakeLists.txt:291 (lcb_declare_target)
      builders/CMakeLists.txt:71 (lcb_declare_targets)
      configs/config-desktop-common.cmake:93 (include)
      configs/config-desktop.cmake:29 (include)
      CMakeLists.txt:62 (include)

即cmake vpx项目时,在vpx.cmake中执行如下语句,并没有在指定目录下生成相应的文件:

execute_process(COMMAND "cmd.exe" "/c" "${CMAKE_CURRENT_SOURCE_DIR}/builders/vpx/windows_env.bat" "${VS_VERSION}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
)

这条指令会调用”D:\VoIP_ICT_SF5GYY\linphone-desktop\linphone-sdk\cmake-builder\builders\vpx\windows_env.bat”批处理指令生成如下四个文件:

windowsenv_include.txt
windowsenv_lib.txt
windowsenv_libpath.txt
windowsenv_path.txt

cmake的确调用了windows_env.bat文件,在里面加了旗子也输出了。诡异的是

@goto printenv

语句并没起作用,反而在此语句后面随便加点东西,此语句执行了:

:vs16
:: No more env variable without load VsDevCmd script
@if not "%DEVENVDIR%" == "" goto printenv
@call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"
@echo hhhhhhhhhhhhhh       11111111111  hhhhhhhhhhhhhhh
@goto printenv
@echo hhhhhhhhhhhhhh       22222222222  hhhhhhhhhhhhhhh

2、“C:\MinGW\bin\gcc.exe” is not able to compile a simple test program 问题

提示 “C:\MinGW\bin\gcc.exe” is not able to compile a simple test program错误,刚开始以为MinGW项目太多年没维护,gcc版本太低导致的,安装了 mingw-w64,问题仍然存在。

查了大量资料,说是sh.exe的问题,各种猜测和奇怪的解决方法能对付一部分人的问题,但是实际上是因为新的linphone vpx工程用了msys2编译,它默认用的是msys2中的sh.exe。所以,如果要用crygen、git等(他们里面都有sh.exe),确保PATH系统路径中的msys的bin目录“C:\msys64\usr\bin”在“C:\cygwin64\bin”、“C:\Program Files\Git\usr\bin”等有sh.exe文件的程序目录之前就行了。

再次编译,项目都配置成功了(除了一些编译错误,后期排查):

D:\VoIP_ICT_SF5GYY\linphone-desktop>cmake --build build --config release --target all_build
用于 .NET Framework 的 Microsoft (R) 生成引擎版本 16.9.0+5e4b48a27
版权所有(C) Microsoft Corporation。保留所有权利。

  Forcing build for 'desktop'
  Performing build step for 'sdk'
  用于 .NET Framework 的 Microsoft (R) 生成引擎版本 16.9.0+5e4b48a27
  版权所有(C) Microsoft Corporation。保留所有权利。

    Performing configure step for 'sdk'
    loading initial cache file D:/VoIP_ICT_SF5GYY/linphone-desktop/build/WORK/sdk-prefix/tmp/sdk-
  cache-Release.cmake
    CMake Warning (dev) in CMakeLists.txt:
      No project() command is present.  The top-level CMakeLists.txt file must
      contain a literal, direct call to the project() command.  Add a line of
      code such as

        project(ProjectName)

      near the top of the file, but after cmake_minimum_required().

      CMake is pretending there is a "project(Project)" command on the first
      line.
    This warning is for project developers.  Use -Wno-dev to suppress it.

    -- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19042.
    -- Using configuration file 'D:/VoIP_ICT_SF5GYY/linphone-desktop/linphone-sdk/cmake-builder/c
  onfigs/config-desktop.cmake'
    -- Installing windows tools : perl, yasm, gawk, bzip2, nasm, sed, patch
    :: 濮濓絽婀崥灞绢劄鏉烆垯娆㈤崠鍛殶閹诡喖绨?..
     mingw32 downloading...
     mingw64 downloading...
     ucrt64 downloading...
     clang64 downloading...
     msys downloading...
...
...

D:\VoIP_ICT_SF5GYY\linphone-desktop>

经过以上编译,sdk依赖项目都已正确生成,可执行如下命令开始编译:

cmake --build build --target ALL_BUILD

执行以上编译指令通常会有一些项目编译失败,通常都是rule错误,需要仔细查看输出提示。

3、EP_ffmpeg项目编译

由于 ffmpeg 是个可选项,项目deadline比较紧急,为不影响工作推进,这里先把video可选项关闭,即再根目录下的CMakeList.txt中的Option选项置为NO,不编译这个项目,后面有时间再打开;)

option(ENABLE_APP_PACKAGING "Enable packaging" NO)
option(ENABLE_UPDATE_CHECK "Enable update check." YES)
option(ENABLE_UNIT_TESTS "Enable unit test of SDK." NO )
option(ENABLE_TESTS "Build with testing binaries of SDK" NO )
option(ENABLE_TESTS_COMPONENTS "Build libbctoolbox-tester" NO )
option(ENABLE_TOOLS "Enable tools of SDK" NO)
option(ENABLE_STRICT "Build with strict compilator flags e.g. -Wall -Werror" NO)
option(ENABLE_FFMPEG "Build mediastreamer2 with ffmpeg video support." NO)
option(ENABLE_BUILD_VERBOSE "Enable the build generation to be more verbose" YES)
option(ENABLE_OPENH264 "Enable the use of OpenH264 codec" NO)
option(ENABLE_NON_FREE_CODECS "Enable the use of non free codecs" YES)
option(ENABLE_BUILD_APP_PLUGINS "Enable the build of plugins" YES)
option(ENABLE_BUILD_EXAMPLES "Enable the build of examples" NO)
option(ENABLE_VIDEO "Enable Video support." YES)

4、vpx项目编译

如果video开关打开,会发现生成vpx项目时会出现错误,原因是调用”linphone-sdk\cmake-builder\builders\vpx\windows_env.bat“文件生成如下四个文件失败:

@echo %PATH% > windowsenv_path.txt
@echo %INCLUDE% > windowsenv_include.txt
@echo %LIB% > windowsenv_lib.txt
@echo %LIBPATH% > windowsenv_libpath.txt

而之所以没有生成这几个文件,是因为vs16段的goto语句没有被执行,奇怪的是随便在它前面及后面加个echo输出语句就没问题了…

:vs16
:: No more env variable without load VsDevCmd script
@if not "%DEVENVDIR%" == "" goto printenv
@call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"
@echo Anything add at this line can make sure the command '@goto printenv' be ran correctly...
@goto printenv
@echo Anything add at this line can make sure the command '@goto printenv' be ran correctly...

经过以上修复,配置过了,然而在编译的时候又出现如下问题:

Creating directories for 'EP_vpx' Building Custom Rule D:/VoIP_ICT_SF5GYY/linphone-desktop/linphone-sdk/cmake-builder/CMakeLi sts.txt
No download step for 'EP_vpx'
No update step for 'EP_vpx'
No patch step for 'EP_vpx'
Performing configure step for 'EP_vpx'
0 [main] diff (13288) C:\Program Files\Git\usr\bin\diff.exe: *** fatal error - cyghea
p base mismatch detected - 0x180352408/0x180347408.

This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version. The most recent version should
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution. Rebooting is also suggested if you
are unable to find another cygwin DLL.

查了很多资料没解决,卡在这里了~~~

有资料说重启Windows10解决了,但是我重启并不能解决此问题。

有资料说是因为Windows10的Address Space Layout Randomization(aslr) 导致的这个问题,“随机化内存分配(自下而上ASLR)”默认是关闭的,如果打开,需要在ASLR中把git排除掉。而git有很多exe程序,所以要通过如下指令进行批处理:

以管理员身份启动PowerShell,执行

Get-Item -Path "C:\Program Files\Git\usr\bin\*.exe" | %{ Set-ProcessMitigation -Name $_.Name -Disable ForceRelocateImages }

“随机化内存分配(自下而上ASLR)”默认是关闭的,比较担心打开会对整个系统产生不可预知的影响,没敢尝试。放弃ASLR的任何尝试。。。

5、禁用VIDEO

以上尝试大部分是失败的,考虑到openh264、ffmpeg、vpx项目均与video有关,干脆在根目录下的CMakeList.txt文件中禁用video:

option(ENABLE_VIDEO "Enable Video support." NO)

果然, openh264、ffmpeg、vpx 相关的项目均没编译,除了OPEN_LDAP项目,其他都成功了。

6、openldap项目

ldap也是一个批处理编译的项目,这样的项目使用Windows版posix编译器msys2编译,安装配置不好很容易出错。编译的出错信息写入了如下文件:

D:\VoIP_ICT_SF5GYY\NoitomVoIPCloudVR-desktop\build32\WORK\desktop\EP_openldap.log

错误信息:

configure: loading site script /etc/config.site
Configuring OpenLDAP 2.4.X-Engineering …
checking build system type… i686-w64-mingw32
checking host system type… i686-w64-mingw32
checking target system type… i686-pc-mingw32
checking for a BSD-compatible install… /usr/bin/install -c
checking whether build environment is sane… yes
checking for gawk… gawk
checking whether make sets $(MAKE)… no
checking configure arguments… done
checking for style of include used by make… none
checking for gcc… C:/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/gcc.exe
checking whether the C compiler works… no

类似于make或sh文件找不到或本身有问题而出错,目前没有找到好办法。用notepadd++在整个sdk目录中搜索”ENABLE_LDAP”,发现它是个可选项,在文件D:\VoIP_ICT_SF5GYY\linphone-desktop\linphone-sdk\cmake-builder\configs\options-desktop.cmake中有设置,既然是可选项,就关了吧,先编译通再说:

# Define default values for the linphone builder options
...
set(DEFAULT_VALUE_ENABLE_MKV ON)
set(DEFAULT_VALUE_ENABLE_NLS OFF)
set(DEFAULT_VALUE_ENABLE_LDAP OFF)
set(DEFAULT_VALUE_ENABLE_OPUS ON)
...

经过以上配置,整个linphone-desktop项目均配置成功。

7、liblinphone编译错误

配置完成后,进入编译期,发现编译liblinphone的coreapi时,提示private_functions.h文件有unicode编码问题:

3>D:\VoIP_ICT_SF5GYY\NoitomVoIPCloudVR-desktop\linphone-sdk\liblinphone\coreapi\private_functions.h(409,1): error C2220: the following warning is treated as an error (compiling source file D:\VoIP_ICT_SF5GYY\NoitomVoIPCloudVR-desktop\linphone-sdk\liblinphone\src\conference\handlers\local-conference-event-handler.cpp)
3>D:\VoIP_ICT_SF5GYY\NoitomVoIPCloudVR-desktop\linphone-sdk\liblinphone\coreapi\private_functions.h(409,1): warning C4819: The file contains a character that cannot be represented in the current code page (936). Save the file in Unicode format to prevent data loss (compiling source file D:\VoIP_ICT_SF5GYY\NoitomVoIPCloudVR-desktop\linphone-sdk\liblinphone\src\conference\handlers\local-conference-event-handler.cpp)

同样用文件内容替换的办法解决:

  • 将private_functions.h重命名为private_functions-bak.h做备份
  • 拷贝一份private.h文件,将其重命名为private_functions.h,在vs中打开
  • 将 private_functions-bak.h 的内容全部拷贝替换到新 private_functions.h 文件中,保存,提示编码问题,不管,继续保存
  • 重新编译,通过

到此为止,整个系统编译完成

总结

实在是deadline接近了,没时间研究细节,只能先把项目完成再说。以上各种配置期错误、编译期错误均与video模块相关,可见实在是不太成熟,能不用就先不用了。

总结下来,把有问题的模块先禁用,别影响进度,编译过去再说吧。

zmq、czmq及其他相关动态库的编译和生成

zeromq是非常优秀的开源库,但是由于作者感觉visual studio的编译工具维护起来相当费事,当然也可能是作者更多的是在非windows下工作的原因吧,msvc build不再维护了,这导致了很多在windows下的用户编译zmq非常不方便。尝试了一下,libzmq\builds\deprecated-msvc\vs20xx的工具的确很多已经不工作了。
下面记录一下通过cmake编译windows下的工程的方法及步骤。
我在项目中用到了zmq、czmq、zyre,由于后两个项目都要依赖前一个项目,所以我们需要统一管理起来。
1、建立一个zeromq_v4.3.1目录(我编译的是4.3.1,所以最好带上版本号,方便后期维护);

2、克隆代码
cmd进入此目录,执行:

https://github.com/zeromq/libzmq.git

将libzmq克隆到zeromq_v4.3.1目录下;

执行:

https://github.com/zeromq/czmq.git

将czmq克隆到zeromq_v4.3.1目录下;

执行:

https://github.com/jedisct1/libsodium.git

将libsodium克隆到zeromq_v4.3.1目录下。
libsodium是一个加密库,czmq将要依赖它,所以这里预先准备好。
执行:

https://github.com/zeromq/zyre.git

将zyre克隆到zeromq_v4.3.1目录下。

3、cmake配置zmq库
cd进入libzmq目录,执行:

cmake -H. -Bbuild -G"Visual Studio 14 2015 Win64"

通常cmake都能成功,这就在build目录下生成了一个vs2015的编译工程,名称是ZeroMQ.sln

需要注意的是,ZeroMQ.sln生成的zmq文件名是带版本号的,类似libzmq-mt-gd-4_3_1.dll这样的格式。这会导致我们项目引用配置的频繁更改,也不利于通过dll替换的方式升级zmq,所以把zmq的CMakeLists.txt配置改一下,让他按libzmq.dll文件名的方式生成:

if(MSVC)
# Suppress linker warnings caused by #ifdef omission
# of file content.
set(CMAKE_STATIC_LINKER_FLAGS “${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221”)
set(PDB_OUTPUT_DIRECTORY “${CMAKE_CURRENT_BINARY_DIR}/bin”)
set(PDB_NAME “libzmq${MSVC_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”)
function(enable_vs_guideline_checker target)
set_target_properties(${target} PROPERTIES
VS_GLOBAL_EnableCppCoreCheck true
VS_GLOBAL_CodeAnalysisRuleSet CppCoreCheckRules.ruleset
VS_GLOBAL_RunCodeAnalysis true)
endfunction()
if(BUILD_SHARED)
add_library(libzmq SHARED ${sources} ${public_headers} ${html-docs} ${readme-docs} ${CMAKE_CURRENT_BINARY_DIR}/NSIS.template.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
if(ENABLE_ANALYSIS)
enable_vs_guideline_checker(libzmq)
endif()
set_target_properties(libzmq PROPERTIES
PUBLIC_HEADER “${public_headers}”
#RELEASE_POSTFIX “${MSVC_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
#RELWITHDEBINFO_POSTFIX “${MSVC_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
#MINSIZEREL_POSTFIX “${MSVC_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
#DEBUG_POSTFIX “${MSVC_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
RUNTIME_OUTPUT_DIRECTORY “${CMAKE_RUNTIME_OUTPUT_DIRECTORY}”
COMPILE_DEFINITIONS “DLL_EXPORT”
OUTPUT_NAME “libzmq”)
endif()

if(BUILD_STATIC)
add_library(libzmq-static STATIC ${sources} ${CMAKE_CURRENT_BINARY_DIR}/version.rc)
set_target_properties(libzmq-static PROPERTIES
PUBLIC_HEADER “${public_headers}”
#RELEASE_POSTFIX “${MSVC_TOOLSET}-mt-s-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
#RELWITHDEBINFO_POSTFIX “${MSVC_TOOLSET}-mt-s-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
#MINSIZEREL_POSTFIX “${MSVC_TOOLSET}-mt-s-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
#DEBUG_POSTFIX “${MSVC_TOOLSET}-mt-sgd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}”
COMPILE_FLAGS “/DZMQ_STATIC”
OUTPUT_NAME “libzmq”)
endif()
else()

……

就是把一些’POSTFIX’注释掉了,让他不要自动在文件名后串接版本号和编译器等信息。

当然还有个方法就是手动修改项目属性,直接在visual studio中,在libzmq工程上mouse right button -> Properties,在弹出来的属性框中,手动把 Configuration Properties -> General -> Target Name 改成 “libzmq”,记得把需要的configuration都改一下(Debug、Release、RelWithDebInfo…)。另外还得把lib文件名也改了:
Configuration Properties -> Linker -> Advanced -> Import Library 改成 “xxxxxxx/libzmq.lib”
同样,如果需要pdb文件,把pdb文件名也改了:
Configuration Properties -> Linker -> Debugging -> Generate Program Database File 改成 “xxxxxxx/libzmq.pdb”。

4、生成zmq库
编译ZeroMQ.sln,一般都能正确编译的。

5、cmake配置czmq库
czmq也抛弃了windows,所以也得自己配置。
czmq配置相对麻烦一些,因为他要依赖zmq,所以我们需要改一下czmq目录下的Findlibzmq.cmake文件,让cmake能正确找到我们刚才编译的zmq的lib文件。

################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Read the zproject/README.md for information about making permanent changes. #
################################################################################

if (NOT MSVC)
    include(FindPkgConfig)
    pkg_check_modules(PC_LIBZMQ "libzmq")
    if (PC_LIBZMQ_FOUND)
        # add CFLAGS from pkg-config file, e.g. draft api.
        add_definitions(${PC_LIBZMQ_CFLAGS} ${PC_LIBZMQ_CFLAGS_OTHER})
        # some libraries install the headers is a subdirectory of the include dir
        # returned by pkg-config, so use a wildcard match to improve chances of finding
        # headers and SOs.
        set(PC_LIBZMQ_INCLUDE_HINTS ${PC_LIBZMQ_INCLUDE_DIRS} ${PC_LIBZMQ_INCLUDE_DIRS}/*)
        set(PC_LIBZMQ_LIBRARY_HINTS ${PC_LIBZMQ_LIBRARY_DIRS} ${PC_LIBZMQ_LIBRARY_DIRS}/*)
    endif(PC_LIBZMQ_FOUND)
else()
	set(PC_LIBZMQ_INCLUDE_DIRS ../libzmq/include)
	set(PC_LIBZMQ_LIBRARY_DIRS ../libzmq/build/lib/Release)	
	set(PC_LIBZMQ_INCLUDE_HINTS ${PC_LIBZMQ_INCLUDE_DIRS} ${PC_LIBZMQ_INCLUDE_DIRS}/*)
	set(PC_LIBZMQ_LIBRARY_HINTS ${PC_LIBZMQ_LIBRARY_DIRS} ${PC_LIBZMQ_LIBRARY_DIRS}/*)
endif (NOT MSVC)

message("######## ${PC_LIBZMQ_INCLUDE_HINTS}")
message("######## ${PC_LIBZMQ_LIBRARY_HINTS}")

find_path (
    LIBZMQ_INCLUDE_DIRS
    NAMES zmq.h
    HINTS ${PC_LIBZMQ_INCLUDE_HINTS}
)

find_library (
    LIBZMQ_LIBRARIES
    NAMES libzmq
    HINTS ${PC_LIBZMQ_LIBRARY_HINTS}
)

include(FindPackageHandleStandardArgs)

find_package_handle_standard_args(
    LIBZMQ
    REQUIRED_VARS LIBZMQ_LIBRARIES LIBZMQ_INCLUDE_DIRS
)
mark_as_advanced(
    LIBZMQ_FOUND
    LIBZMQ_LIBRARIES LIBZMQ_INCLUDE_DIRS
)

################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Read the zproject/README.md for information about making permanent changes. #
################################################################################

czmq依赖的另一个库是libsodium,还好,libsodium的vs编译还在,打开libsodium\builds\msvc\vs2015目录下的libsodium.sln文件,可直接生成对应的libsodium.dll和libsodium.lib
然后在czmq目录下找到Findlibsodium.cmake文件,修改如下:

################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Please refer to the README for information about making permanent changes.  #
################################################################################

if (NOT MSVC)
    include(FindPkgConfig)
    pkg_check_modules(PC_LIBSODIUM "libsodium")
    if (NOT PC_LIBSODIUM_FOUND)
        pkg_check_modules(PC_LIBSODIUM "libsodium")
    endif (NOT PC_LIBSODIUM_FOUND)
    if (PC_LIBSODIUM_FOUND)
        # some libraries install the headers is a subdirectory of the include dir
        # returned by pkg-config, so use a wildcard match to improve chances of finding
        # headers and SOs.
        set(PC_LIBSODIUM_INCLUDE_HINTS ${PC_LIBSODIUM_INCLUDE_DIRS} ${PC_LIBSODIUM_INCLUDE_DIRS}/*)
        set(PC_LIBSODIUM_LIBRARY_HINTS ${PC_LIBSODIUM_LIBRARY_DIRS} ${PC_LIBSODIUM_LIBRARY_DIRS}/*)
    endif(PC_LIBSODIUM_FOUND)
else()
	set(PC_LIBSODIUM_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../libsodium/src/libsodium/include)
	set(PC_LIBSODIUM_LIBRARY_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../libsodium/bin/x64/Release/v140/dynamic)	
	set(PC_LIBSODIUM_INCLUDE_HINTS ${PC_LIBSODIUM_INCLUDE_DIRS} ${PC_LIBSODIUM_INCLUDE_DIRS}/*)
	set(PC_LIBSODIUM_LIBRARY_HINTS ${PC_LIBSODIUM_LIBRARY_DIRS} ${PC_LIBSODIUM_LIBRARY_DIRS}/*)
endif (NOT MSVC)

find_path (
    LIBSODIUM_INCLUDE_DIRS
    NAMES sodium.h
    HINTS ${PC_LIBSODIUM_INCLUDE_HINTS}
)

find_library (
    LIBSODIUM_LIBRARIES
    NAMES libsodium
    HINTS ${PC_LIBSODIUM_LIBRARY_HINTS}
)

include(FindPackageHandleStandardArgs)

find_package_handle_standard_args(
    LIBSODIUM
    REQUIRED_VARS LIBSODIUM_LIBRARIES LIBSODIUM_INCLUDE_DIRS
)
mark_as_advanced(
    LIBSODIUM_FOUND
    LIBSODIUM_LIBRARIES LIBSODIUM_INCLUDE_DIRS
)

################################################################################
#  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #
#  Please refer to the README for information about making permanent changes.  #
################################################################################

6、生成czmq库
这个就简单了,打开编译就行啦

7、zyre依赖zmq和czmq,参考czmq,把对应的依赖项Findlibzmq.cmake、Findczmq.cmake、Findlibsodium.cmake改为对应的目录和文件就行了。

8、czmq的版本号问题
czmq通过cmake编译完的windows dll是不带版本号的,也就是从dll文件的属性里看不到版本号信息,这让我们在使用时很难确定其版本号,还好builds/msvc目录下有个resource.rc文件,只要在如下地方把这个rc文件加进去就可以了:

# shared
if (CZMQ_BUILD_SHARED)
  IF (MSVC)
    add_library(czmq SHARED ${czmq_sources} ${CMAKE_CURRENT_SOURCE_DIR}/builds/msvc/resource.rc)
  ELSE (MSVC)
    add_library(czmq SHARED
 
lt;TARGET_OBJECTS:czmq_objects>) ENDIF (MSVC) set_target_properties (czmq PROPERTIES PUBLIC_HEADER "${public_headers}" DEFINE_SYMBOL "CZMQ_EXPORTS" SOVERSION "4" VERSION "${CZMQ_VERSION}" COMPILE_DEFINITIONS "DLL_EXPORT" OUTPUT_NAME "czmq" PREFIX "lib" ) target_link_libraries(czmq PUBLIC ${MORE_LIBRARIES} ) install(TARGETS czmq EXPORT czmq-targets LIBRARY DESTINATION "lib${LIB_SUFFIX}" # .so file ARCHIVE DESTINATION "lib${LIB_SUFFIX}" # .lib file RUNTIME DESTINATION bin # .dll file ) target_include_directories(czmq PUBLIC
 
lt;BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
 
lt;INSTALL_INTERFACE:include> ) endif() # static if (CZMQ_BUILD_STATIC) IF (MSVC) add_library(czmq-static STATIC ${czmq_sources} ${CMAKE_CURRENT_SOURCE_DIR}/builds/msvc/resource.rc) ELSE (MSVC) add_library(czmq-static STATIC
 
lt;TARGET_OBJECTS:czmq_objects>) ENDIF (MSVC) set_target_properties(czmq-static PROPERTIES PUBLIC_HEADER "${public_headers}" COMPILE_DEFINITIONS "CZMQ_STATIC" OUTPUT_NAME "czmq" PREFIX "lib" ) target_link_libraries(czmq-static PUBLIC ${MORE_LIBRARIES} ) install(TARGETS czmq-static EXPORT czmq-targets LIBRARY DESTINATION "lib${LIB_SUFFIX}" # .so file ARCHIVE DESTINATION "lib${LIB_SUFFIX}" # .lib file RUNTIME DESTINATION bin # .dll file ) target_include_directories(czmq-static PUBLIC
 
lt;BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
 
lt;INSTALL_INTERFACE:include> ) target_compile_definitions(czmq-static PUBLIC CZMQ_STATIC ) endif()

在Windows 10中编译libzip

slam dso依赖libzip,libzip又依赖zlib。zlib本身很好编译通过,但是libzip在通过cmake查找zlib时,规则、文件夹结构很奇怪,费了好大劲才配置好,将libzip编译过去,这里记录一下注意事项。

cmake中内嵌了一些常用模块的查找脚本,zlib就是一个。从官网上下载zlib源码,也是通过cmake指令:cmake -H. -Bbuild -G”Visual Studio 14 2015 Win64″ 生成vs2015的x64解决方案,很容易就编译除了x64的debug和release版本,但是cmake的内嵌缺省FindZlib.cmake查找zlib对目录结构有一定要求。

1、首先,将下载到的源代码放入如下目录

C:/Program Files/zlib-1.2.11

2、然后在libzip的CMakeLists.txt文件中加入:

set(ZLIB_ROOT "C:/Program Files/zlib-1.2.11")

这是设置了cmake的缺省FindZlib.cmake中的ZLIB_ROOT变量,以便libzip在查找依赖项时能用正确的目录去查

3、在C:/Program Files/zlib-1.2.11下新建一个文件夹,lib,然后将刚才编译好的zlib.lib、zilb.dll文件放在lib目录下

因为FindZlib.cmake在ZLIB_ROOT目录下查找到zlib.h文件并获取到版本号后,接着在ZLIB_ROOT/lib目录下查找.lib文件。

这是缺省FindZlib.cmake对zlib目录结构的要求。

我只编译了x64的版本,x86的需要用cmake指令另外生成解决方案:

cmake -H. -Bbuild-win32 -G"Visual Studio 14 2015"