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

相关文章

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

11g Dataguard中的snapshot standby特性(r8笔记第49天)

11g中的ADG特性本身已经非常有特色,促使很多对于10g中不太灵便的备库升级到11g,对于DBA是一大福利,那么还有一个福利就是snapshot standb...

2815
来自专栏潇涧技术专栏

Gradle Plugin for Android Development User Guide 2

Gradle Plugin for Android Development User Guide (2)

811
来自专栏用户2442861的专栏

cmake教程4(find_package使用)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

1823
来自专栏Objective-C

iOS-安装和使用 CocoaPods

3657
来自专栏技术总结

献给移动端的服务器搭建

application.properties这个是项目的一些配置,举例一下默认是8080端口,我们如果想改下端口的话,就可以在配置增加

1622
来自专栏微信音视频小程序

教你1天搭建自己的“微视”

A simple iOS Application project is shown below to illustrate how to configure S...

9015
来自专栏乐沙弥的世界

ORA-27090 故障一例

    最近的alert日志中碰到了ORA-27090的错误信息,其错误提示为Unable to reserve kernel resources for as...

662
来自专栏Netkiller

以太坊私链入门

中国广东省深圳市龙华新区民治街道溪山美地 518131 +86 13113668890 <netkiller@msn.com>

2.5K9
来自专栏bboysoul

linux编译安装apache

wget http://mirrors.ustc.edu.cn/apache/httpd/httpd-2.4.25.tar.gz tar -zxvf http...

1413
来自专栏后端之路

chrome 插件实现mac地址获取

浏览器无法通过js获取到硬件信息众所周知,ie是也是通过ActiveX来完成的。 由于我们一直使用Chrome,因此考虑开发chrome插件。 普通chrome...

2.7K10

扫码关注云+社区