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 条评论
登录 后参与评论

相关文章

来自专栏杨建荣的学习笔记

数据库静默安装总结(r3笔记第58天)

在学习数据库的时候,不知道dbca的命令用了多少遍,但是越是安装也是觉得自己会的越少,因为图形界面的清晰直白反而不知道哪些准备工作是需要特别准备的,如果在远程支...

2948
来自专栏杂烩

spark整合hive+hbase做数据实时插入及实时查询分析

        使用的spark是2.0.1,hive是1.2.1,hbase是1.2.4,hadoop是2.6.0,zookeeper是3.4.9

764
来自专栏IMWeb前端团队

Common Pitfalls to Avoid when using HTML5 Application Cache

本文作者:IMWeb 黎腾 原文出处:IMWeb社区 未经同意,禁止转载 Application Cache, also known as AppCa...

1807
来自专栏bboysoul

使用永恒之蓝(MS17-010)漏洞入侵windows7

前几天,被勒索病毒(Wannacry)刷屏了,这个病毒是大家知道了备份文件的重要性,当然,我是不怕什么病毒的,因为我是一天备份一次文件,而且微云一份,坚果云,移...

2904
来自专栏CreateAMind

国产ros小车及相关文档

Roch(robot platform for commecial and home) integrated multiple different RGBD c...

1082
来自专栏Pulsar-V

原 跨平台预编译参数

1142
来自专栏C# 编程

[C#]使用Costura.Fody将源DLL合并到目标EXE

本文为原创文章,如转载,请在网页明显位置标明原文名称、作者及网址,谢谢! 一、本文主要是使用Costura.Fody工具将源DLL合并到目标EXE,因此,需要...

2200
来自专栏Pulsar-V

跨平台编译-判断平台的预编译方法

1475
来自专栏菩提树下的杨过

mac:在当前文件夹打开terminal终端

System Preferences -> Keyboard -> Shortcuts -> Services -> New Terminal at Folde...

2028
来自专栏张善友的专栏

SharpForge - Open source SourceForge / CodePlex implementation

SharpForge - Open source SourceForge / CodePlex implementation SharpForge suppo...

17910

扫码关注云+社区