MSVC/MinGW中导入glog静态库的正确方式

在linux下使用glog静态库,编译连接时只要加上glog静态库文件(.a)就可以了,在windows环境,我也同样的办法在自己的项目中使用glog静态库,用msvc/mingw编译。。。然而链接时报错了,无数的错误都是找不到glog的符号(undefined reference)… 我的项目是cmake生成的工程文件,glog也是我自己用cmake编译出来的,为了查找原因我查看了glog提供的cmake脚本。在lib/cmake/glog/glog-targets.cmake文件中找到如下脚本:

set_target_properties(glog::glog PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "GFLAGS_DLL_DECLARE_FLAG=;GFLAGS_DLL_DEFINE_FLAG=;GLOG_NO_ABBREVIATED_SEVERITIES;GOOGLE_GLOG_DLL_DECL="
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
  INTERFACE_LINK_LIBRARIES "gflags_static"
)

看到这个INTERFACE_COMPILE_DEFINITIONS 属性指定的一堆符号,我明白了。原来在windows下要连接glog静态库,必须要在编译时或在源码中添加下面四个宏定义 GFLAGS_DLL_DECLARE_FLAG, GFLAGS_DLL_DEFINE_FLAG, GLOG_NO_ABBREVIATED_SEVERITIES, GOOGLE_GLOG_DLL_DECL

目的是告诉连接器使用glog静态库的符号表,否则连接器默认会把glog的函数定义当做动态库函数来处理。

如果你是用cmake脚本来编译自己的项目的,如果是用下面的方式来导入glog(caffe就是这么干的,linux下是没问题的),那么连接时肯定会报错,原因就是没加入上面说的宏定义

# GLOG_ROOT_DIR 是glog 的安装路径
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS ${GLOG_ROOT_DIR}/include)
find_library(GLOG_LIBRARY glog 
PATHS ${GLOG_ROOT_DIR}/lib)
...
include_directories(${GLOG_INCLUDE_DIR})
target_link_libraries(your_project ${GLOG_LIBRARY})

在cmake中,加入glog静态库的正确方式是这样的:

# GLOG_ROOT_DIR 是glog 的安装路径
find_package(glog REQUIRED CONFIG HINTS ${GLOG_ROOT_DIR})
set(GLOG_INCLUDE_DIR ${GLOG_ROOT_DIR}/include)
# glog::glog is imported target
set(GLOG_LIBRARY glog::glog)
...
target_link_libraries(your_project ${GLOG_LIBRARY})

上面的代码中使用find_package来查找静态库而不是find_library,find_package(glog)会创建一个名为glog:glog的imported target. glog::glog就是lib/cmake/glog/glog-targets.cmake定义的imported target(本文最开始提到的),因为这个target的INTERFACE_COMPILE_DEFINITIONS属性中指定了上面4个宏定义,所以聪明的cmake在生成Makefile时会自动在your_project target的编译选项中加入-DGFLAGS_DLL_DECLARE_FLAG -DGFLAGS_DLL_DEFINE_FLAG -DGLOG_NO_ABBREVIATED_SEVERITIES -DGOOGLE_GLOG_DLL_DECL 所以就不需要再执行include_directories(${GLOG_INCLUDE_DIR})

关于imported library, 参见 https://cmake.org/cmake/help/v3.8/manual/cmake-buildsystem.7.html#imported-targets

如下是cmake生成的编译工程文件(flags.make)的样例,可以看到CXX_DEFINES 中已经自动添加了上面的4个宏定义,并且将glog include文件夹也自动加到了CXX_INCLUDES

# CMAKE generated file: DO NOT EDIT!
# Generated by "NMake Makefiles JOM" Generator, CMake Version 3.8

# compile CXX with C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
CXX_FLAGS = /wd4996 /wd4267 /wd4244 /wd4018 /wd4800 /wd4661 /wd4812 /wd4309 /wd4305 /wd4819  /DWIN32 /D_WINDOWS /W3 /GR /EHsc /MT /O2 /Ob2 /DNDEBUG  

CXX_DEFINES = -DBOOST_ALL_NO_LIB -DCAFFE_VERSION=1.0.0 -DCMAKE_WINDOWS_BUILD -DCPU_ONLY -DGFLAGS_DLL_DECLARE_FLAG="" -DGFLAGS_DLL_DEFINE_FLAG="" -DGFLAGS_IS_A_DLL=0 -DGLOG_NO_ABBREVIATED_SEVERITIES -DGOOGLE_GLOG_DLL_DECL="" -DUSE_LEVELDB -DUSE_LMDB -DUSE_OPENCV

CXX_INCLUDES = -ID:\caffe-static\source\caffe-windows\build.vs2015\include -ID:\caffe-static\release\opencv_windows_vc140_x86_64_mt\include -ID:\caffe-static\release\opencv_windows_vc140_x86_64_mt\include\opencv -ID:\caffe-static\source\caffe-windows\build.vs2015 -ID:\caffe-static\release\boost_windows_vc140_x86_64_mt\include\boost-1_62 -ID:\caffe-static\release\glog_windows_vc140_x86_64_mt\include -ID:\caffe-static\release\gflags_windows_vc140_x86_64_mt\Include -ID:\caffe-static\release\protobuf_windows_vc140_x86_64_mt\include -ID:\caffe-static\release\hdf5_windows_vc140_x86_64_mt\include -ID:\caffe-static\release\lmdb_windows_vc140_x86_64_mt\include -ID:\caffe-static\release\leveldb_windows_vc140_x86_64_mt\include -ID:\caffe-static\release\OpenBLAS_windows_vc140_x86_64_mt\include -ID:\caffe-static\source\caffe-windows\include 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Kubernetes

原 荐 Kubernetes Statefu

Author: xidianwangtao@gmail.com,Based on Kubernetes 1.9 摘要:Kubernetes Statef...

3548
来自专栏技术博文

Linux id命令

id 命令可以显示真实有效的用户 ID(UID) 和组 ID(GID)。UID 是对一个用户的单一身份标识。组 ID(GID)则对应多个UID。 Usage: ...

28511
来自专栏林德熙的博客

C# 对 byte 数组进行模式搜索

最简单的方法是进行数值判断,但是代码最少是使用Linq ,效率比较高是使用 Boyer-Moore 算法,下面就告诉大家几个算法的代码

381
来自专栏Porschev[钟慰]的专栏

项目中对图片的缩放和水印效果

///<summary> /// 获取一个图片按等比例缩小后的大小。 ///</summary> ///<param name="maxWidth">需要缩小到...

1566
来自专栏跟着阿笨一起玩NET

C# EPL USB 指令打印

341
来自专栏岑玉海

WF追忆

  前一阵子学习了一下工作流,现在写个总结记录一下这个过程。要弄工作流,首先就要有个界面来画图,做web的,没办法,只能选择javascript和silverl...

2696
来自专栏数据之美

玩转千位分隔符输出

1、Python 1.1 format方法: 2.7版本以上直接用format设置千分位分隔符 Python 2.7 (r27:82500, Nov 23 20...

2265
来自专栏Windows Community

Extensions in UWP Community Toolkit - Visual Extensions

概述 UWP Community Toolkit Extensions 中有一个为可视元素提供的扩展 - VisualExtensions,本篇我们结合代码详细...

2585
来自专栏烙馅饼喽的技术分享

asp.net生成透明gif的准完美方案

       我最近在实现我的WMS服务器的时候,发现了一个超级郁闷的问题,问题描述如下:客户需要动态叠加一个透明层到底图上,比如说公交线路层,这个层有透明背景...

4137
来自专栏极客编程

测试利器Mocha

mocha 是一个功能丰富的javascript测试框架,可以运行在nodejs和浏览器环境,使异步测试变得简单有趣。mocha 串联运行测试,允许灵活和精确地...

642

扫码关注云+社区