OpenBLAS:改进OpenBLASConfig.cmake生成方式,解除cmake脚本的路
问题描述当我们用OpenBLAS提供的Makefile进行编译,并用 /you/install/path/lib/cmake/openblas/OpenBLASConfig.cmake SET(OpenBLAS_VERSION "0.2.18")
SET(OpenBLAS_INCLUDE_DIRS /home/hadoop/Desktop/caffe-static/release/OpenBLAS_linux_x86_64/include)
SET(OpenBLAS_LIBRARIES /home/hadoop/Desktop/caffe-static/release/OpenBLAS_linux_x86_64/bin/libopenblas.so)
(linux下生成静态库) SET(OpenBLAS_VERSION "0.2.18")
SET(OpenBLAS_INCLUDE_DIRS /home/hadoop/Desktop/caffe-static/release/OpenBLAS_linux_x86_64/include)
SET(OpenBLAS_LIBRARIES /home/hadoop/Desktop/caffe-static/release/OpenBLAS_linux_x86_64/lib/libopenblas.a)
(windows下生成动态库) SET(OpenBLAS_VERSION "0.2.18")
SET(OpenBLAS_INCLUDE_DIRS D:/caffe-static/release/OpenBLAS_windows_vc140_x86_mt/include)
SET(OpenBLAS_LIBRARIES D:/caffe-static/release/OpenBLAS_windows_vc140_x86_mt/bin/libopenblas.dll)
如果你编译OpenBLAS只是在本机使用,那没啥问题,如果想把这个编译好的OpenBLAS 移到别的位置或提供给别人使用,并且也是用cmake编译项目。那么问题就来了,因为OpenBLASConfig.cmake中的路径依赖问题,导致cmake脚本中调用 而且你发现没有?上面Windows下生成的OpenBLASConfig.cmake中OpenBLAS_LIBRARIES的值居然是.dll的路径。而不是动态库导入库(import library)(.dll.a)的路径,也就是说OpenBLAS在生成OpenBLASConfig.cmake没有考虑到linux和windows的区别,只是按linux的方式将OpenBLAS_LIBRARIES置为静态库/动态库(.a,.so,dll)的路径。 如果你是用手工在Visual Studio中创建工程并设置工程参数,那么这都不是问题,对你没有任何影响,但如果你像我一样,用cmake进行工程编译,这是个很要命的问题,因为cmake根据这些错误的信息无法生成正确的Makefile,当然也不能正常编译。 原因分析怎么办呢?指望OpenBLAS官方修改这个问题怕是来不及了,只能自己想办法解决。 而在这其中生成OpenBLASConfig.cmake的代码就是如下几行(line 97-116 OpenBLAS 0.2.18) #Generating OpenBLASConfig.cmake
@echo Generating $(OPENBLAS_CMAKE_CONFIG) in $(DESTDIR)$(OPENBLAS_CMAKE_DIR)
# 对应OpenBLASConfig.cmake中line 1
@echo "SET(OpenBLAS_VERSION "${VERSION}")" > $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
# 对应OpenBLASConfig.cmake中line 2
@echo "SET(OpenBLAS_INCLUDE_DIRS ${OPENBLAS_INCLUDE_DIR})" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
ifndef NO_SHARED
#ifeq logical or
# 判断操作系统将OpenBLAS_LIBRARIES置为动态库文件路径
ifeq ($(OSNAME),$(filter $(OSNAME),Linux FreeBSD NetBSD))
# 对应OpenBLASConfig.cmake中line 3
@echo "SET(OpenBLAS_LIBRARIES ${OPENBLAS_LIBRARY_DIR}/$(LIBPREFIX).so)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
ifeq ($(OSNAME),WINNT CYGWIN_NT))
# 对应OpenBLASConfig.cmake中line 3
# 这里 LIBDLLNAME = $(LIBPREFIX).dll 参见 Makefile.system
@echo "SET(OpenBLAS_LIBRARIES ${OPENBLAS_BINARY_DIR}/$(LIBDLLNAME))" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
ifeq ($(OSNAME),Darwin)
# 对应OpenBLASConfig.cmake中line 3
@echo "SET(OpenBLAS_LIBRARIES ${OPENBLAS_LIBRARY_DIR}/$(LIBPREFIX).dylib)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
else
# 将OpenBLAS_LIBRARIES置为静态库文件路径
#only static
# 对应OpenBLASConfig.cmake中line 3
@echo "SET(OpenBLAS_LIBRARIES ${OPENBLAS_LIBRARY_DIR}/$(LIBPREFIX).$(LIBSUFFIX))" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
上面的三行 解决方法原因搞清楚就好办了,要解决问题,只要修改上面这段代码,改进生成OpenBLASConfig.cmake的逻辑就可以了。 以下是上面代码(Makefile.install)修改后的版本: #Generating OpenBLASConfig.cmake
# modified by guyadong for windows build
@echo Generating $(OPENBLAS_CMAKE_CONFIG) in $(DESTDIR)$(OPENBLAS_CMAKE_DIR)
@echo "SET(OpenBLAS_VERSION "${VERSION}")" > $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "# modified by guyadong,use relative path instead of absolute path" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "# Compute the installation prefix relative to this file." >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "get_filename_component(_IMPORT_PREFIX "$${CMAKE_CURRENT_LIST_DIR}" PATH)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "get_filename_component(_IMPORT_PREFIX "$${_IMPORT_PREFIX}" PATH)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "get_filename_component(_IMPORT_PREFIX "$${_IMPORT_PREFIX}" PATH)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "if(_IMPORT_PREFIX STREQUAL "/")" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " set(_IMPORT_PREFIX "")" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "endif()" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "SET(OpenBLAS_INCLUDE_DIRS $${_IMPORT_PREFIX}/include)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
ifndef NO_SHARED
#ifeq logical or
ifeq ($(OSNAME),Linux FreeBSD NetBSD))
@echo "SET(OpenBLAS_LIBRARIES $${_IMPORT_PREFIX}/lib/$(LIBPREFIX).so)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
ifeq ($(OSNAME),WINNT CYGWIN_NT))
# windows下编译时生成条件判断语句
@echo "# use dynamic import library if MSVC" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "if(MSVC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " SET(OpenBLAS_LIBRARIES $${_IMPORT_PREFIX}/lib/$(LIBDLLNAME).a)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "else(MSVC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " SET(OpenBLAS_LIBRARIES $${_IMPORT_PREFIX}/bin/$(LIBDLLNAME))" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "endif(MSVC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "SET(OPENBLAS_IS_DYNAMIC true)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
ifeq ($(OSNAME),Darwin)
@echo "SET(OpenBLAS_LIBRARIES $${_IMPORT_PREFIX}/lib/$(LIBPREFIX).dylib)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
else
#only static
@echo "SET(OpenBLAS_LIBRARIES $${_IMPORT_PREFIX}/lib/$(LIBPREFIX).$(LIBSUFFIX))" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
# windows下编译时生成条件判断语句
ifeq ($(OSNAME),WINNT CYGWIN_NT))
@echo "if(MSVC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " message(STATUS "OpenBLAS_LIBRARIES(static library):$${OpenBLAS_LIBRARIES}" )" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " message(FATAL_ERROR "With Visual Studio,only dynamic linking is supported,please reinstall OpenBLAS without NO_STATIC=1" )" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "endif(MSVC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "SET(OPENBLAS_IS_DYNAMIC false)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
endif
ifeq ($(OSNAME),WINNT CYGWIN_NT))
@echo "# if OpenBlas_USE_STATIC is true,force to use static library with MinGW" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "if(OPENBLAS_IS_DYNAMIC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " if(EXISTS "$${_IMPORT_PREFIX}/lib/$(LIBPREFIX).$(LIBSUFFIX)" AND OpenBlas_USE_STATIC AND NOT MSVC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " MESSAGE(STATUS "use OpenBlas static library")" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " SET(OpenBLAS_LIBRARIES $${_IMPORT_PREFIX}/lib/$(LIBPREFIX).$(LIBSUFFIX))" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo " endif()" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "endif(OPENBLAS_IS_DYNAMIC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
@echo "unset(OPENBLAS_IS_DYNAMIC)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
endif
@echo "unset(_IMPORT_PREFIX)" >> $(DESTDIR)$(OPENBLAS_CMAKE_DIR)/$(OPENBLAS_CMAKE_CONFIG)
经过上面的修改,再重新执行 # modified by guyadong,use relative path instead of absolute path
# Compute the installation prefix relative to this file.
# 三次调用 get_filename_component 计算 OpenBLAS安装路径
# _IMPORT_PREFIX为OpenBLAS安装路径
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_DIR}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
SET(OpenBLAS_INCLUDE_DIRS ${_IMPORT_PREFIX}/include)
SET(OpenBLAS_LIBRARIES ${_IMPORT_PREFIX}/lib/libopenblas.a)
unset(_IMPORT_PREFIX)
(windows下生成动态库) # modified by guyadong,use relative path instead of absolute path
# Compute the installation prefix relative to this file.
# 三次调用 get_filename_component 计算 OpenBLAS安装路径
# _IMPORT_PREFIX为OpenBLAS安装路径
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_DIR}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
SET(OpenBLAS_INCLUDE_DIRS ${_IMPORT_PREFIX}/include)
# 判断编译器类型,MSVC下置为import library(.dll.a),否则(MinGW)置为.dll
if(MSVC)
SET(OpenBLAS_LIBRARIES ${_IMPORT_PREFIX}/lib/libopenblas.dll.a)
else(MSVC)
SET(OpenBLAS_LIBRARIES ${_IMPORT_PREFIX}/bin/libopenblas.dll)
endif(MSVC)
SET(openblas_is_dynamic true)
# if OpenBlas_USE_STATIC is true,force to use static library with MinGW
if(openblas_is_dynamic)
# 使用MinGW编译时,如果定义了OpenBlas_USE_STATIC,则置为静态库
if(EXISTS "${_IMPORT_PREFIX}/lib/libopenblas.a" AND OpenBlas_USE_STATIC AND NOT MSVC)
SET(OpenBLAS_LIBRARIES ${_IMPORT_PREFIX}/lib/libopenblas.a)
endif()
endif(openblas_is_dynamic)
unset(openblas_is_dynamic)
unset(_IMPORT_PREFIX)
完整代码修改后的OpenBLAS Makefile.install完整代码参见 :
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |