当前位置: 首页 > news >正文

成都解放号网站建设我想在百度上发布广告怎么发

成都解放号网站建设,我想在百度上发布广告怎么发,深圳外贸论坛官网入口,幼儿园教育类网站模板下载文章目录 1. 目的2. 设计整体思路多层依赖的处理获取 DLL 所在目录探测剩余的 DLL 文件 3. 代码实现判断 stack 是否为空判断 stack 是否为空获取所有 target检测并拷贝 DLL 4. 使用 1. 目的 在基于 CMake 构建的 C/C 工程中,拷贝当前工程需要的每个DLL文件到 Visu…

文章目录

    • 1. 目的
    • 2. 设计
      • 整体思路
      • 多层依赖的处理
      • 获取 DLL 所在目录
      • 探测剩余的 DLL 文件
    • 3. 代码实现
      • 判断 stack 是否为空
      • 判断 stack 是否为空
      • 获取所有 target
      • 检测并拷贝 DLL
    • 4. 使用

在这里插入图片描述

1. 目的

在基于 CMake 构建的 C/C++ 工程中,拷贝当前工程需要的每个DLL文件到 Visual Studio 工程的启动路径下, 让可执行目标在运行阶段正常运行,解决“DLL找不到”导致的程序终止、异常退出等问题,解决“每次都要手动拷贝,有时候忘记拷贝”的问题。

举例:

  • OpenCV: 官方预编译版本,包含的 opencv_world.dll, 以及读取某些视频时需要的 opencv_ffmpeg dll 文件
  • windows-pthreads 的 DLL 文件
  • 其他依赖库当中,提供的 DLL 文件

实际上不仅限于 Windows 平台的 DLL, 在 Linux / MacOSX 上也同样有这样的问题,此时只需要增加 .so.dylib 文件后缀的动态库支持即可。

本文给出基于 CMake 语言的解决方案。

2. 设计

整体思路

枚举所有 target, 筛选出 SHARED_LIBRARRY 类型的 target, 获取它们的动态库的路径 shared_library_path, 然后拷贝到用户指定的目录 dstDir.

此外有些 dll 文件并没有被 xxx-config.cmake 等配置文件所配置, 需要额外扫描和拷贝,例如 opencv 预编译库中的 ffmpeg 的 dll 文件。

多层依赖的处理

有时候工程比较复杂, target 至少包括三层, 最后一层是可执行文件, 第二层可能没有DLL,但第二层依赖的第一层则可能存在DLL文件,这就导致枚举 target 时不能只枚举一层。换言之,枚举 target 的过程是一个递归过程, 需要使用深度优先搜索 DFS 算法

获取 DLL 所在目录

这个问题比较简单, 用 cmake 的 get_target_property 函数获取。

探测剩余的 DLL 文件

包括两种情况:

  • target 本身是动态库类型, 那么它的 DLL 文件所在的目录应该被扫描,扫描出的新的 DLL 文件也应该被拷贝
  • target 本身是静态库类型, 但它所在目录的上一级目录中, 有一个 bin 目录, bin 目录里存放有 DLL 文件

3. 代码实现

代码实现过程中遇到一些“难点”,主要是对 cmake 不够足够熟悉, 简单列举:

判断 stack 是否为空

  • DFS 算法的实现过程中, 怎样判断 stack 为空?获取 stack 首部元素?依赖于对 list 的操作, 包括将“列表是否为空”封装为函数
#======================================================================
# Determine if a list is empty
#======================================================================
# Example:
# cvpkg_is_list_empty(testbed_requires testbed_requires_empty)
# message(STATUS "testbed_requires_empty: ${testbed_requires_empty}")
#----------------------------------------------------------------------
function(cvpkg_is_list_empty the_list ret)list(LENGTH ${the_list} the_list_length)if(${the_list_length} EQUAL 0)set(${ret} TRUE PARENT_SCOPE)else()set(${ret} FALSE PARENT_SCOPE)endif()
endfunction()

判断 stack 是否为空

通过判断元素是否在列表中来实现。封装为了函数

#======================================================================
# Determine if item is in the list
#======================================================================
# Example: 
# cvpkg_is_item_in_list(testbed_requires "protobuf" protobuf_in_the_lst)
# message(STATUS "protobuf_in_the_lst: ${protobuf_in_the_lst}")
# 
# cvpkg_is_item_in_list(testbed_requires "opencv" opencv_in_the_lst)
# message(STATUS "opencv_in_the_lst: ${opencv_in_the_lst}")
#----------------------------------------------------------------------
function(cvpkg_is_item_in_list the_list the_item ret)list(FIND ${the_list} ${the_item} index)if(index EQUAL -1)set(${ret} FALSE PARENT_SCOPE)else()set(${ret} TRUE PARENT_SCOPE)endif()
endfunction()

获取所有 target

原本的依赖关系是 hierarchical 的, 怎样拍平,得到一维的依赖列表?并且不能有重复元素?答案是用 DFS。

#======================================================================
# 4. Recursively get required packages for a package. No duplicated.
#======================================================================
# Example: 
# cvpkg_get_flatten_requires(testbed flatten_pkgs)
# message(STATUS "flatten_pkgs: ${flatten_pkgs}")
#----------------------------------------------------------------------
function(cvpkg_get_flatten_requires input_pkg the_result)list(LENGTH input_pkg input_pkg_length)if(NOT (${input_pkg_length} EQUAL 1))cvpkg_error("input_pkg should be single element list")endif()set(visited_pkgs "")set(pkg_stack ${input_pkg})while(TRUE)cvpkg_is_list_empty(pkg_stack pkg_stack_empty)if(${pkg_stack_empty})break()endif()cvpkg_debug("pkg_stack: ${pkg_stack}")# pop the last elementlist(POP_BACK pkg_stack pkg)cvpkg_debug("pkg: ${pkg}")# mark the element as visitedcvpkg_is_item_in_list(visited_pkgs "${pkg}" pkg_visited)if(NOT ${pkg_visited})cvpkg_debug(" visiting ${pkg}")list(APPEND visited_pkgs ${pkg})# traverse it's required dependencies and put into pkg_stackget_target_property(subpkgs ${pkg} LINK_LIBRARIES)cvpkg_debug("LINK_LIBRARIES: ${subpkgs}")if(subpkgs)foreach(subpkg ${subpkgs})if(TARGET ${subpkg}) # if called target_link_libraries() more than once, subpkgs contains stuffs like `::@(000001FAFA8C75C0)`cvpkg_debug("  subpkg: ${subpkg}")list(APPEND pkg_stack ${subpkg})endif()endforeach()endif()get_target_property(subpkgs ${pkg} INTERFACE_LINK_LIBRARIES)cvpkg_debug("INTERFACE_LINK_LIBRARIES: ${subpkgs}")if(subpkgs)foreach(subpkg ${subpkgs})if(TARGET ${subpkg}) # if called target_link_libraries() more than once, subpkgs contains stuffs like `::@(000001FAFA8C75C0)`cvpkg_debug("  subpkg: ${subpkg}")list(APPEND pkg_stack ${subpkg})endif()endforeach()endif()endif()endwhile()list(POP_FRONT visited_pkgs visited_pkgs)set(${the_result} ${visited_pkgs} PARENT_SCOPE)
endfunction()

检测并拷贝 DLL

这是代码最多的函数, 不过思路上前面已经提到过, 并不复杂。

代码多的几个原因:

  • 支持 .dll 的同时, 要支持 .so 和 .dylib
  • windows 上的 target, 可能 debug 和 release 库的文件不是同一个,都需要拷贝,因此需要枚举5个属性
  set(prop_lst "IMPORTED_LOCATION;IMPORTED_LOCATION_DEBUG;IMPORTED_LOCATION_RELEASE")
  • 去重: 拷贝过的文件要忽略, 重复的目录要合并

Talk is cheap, show me the code:

#======================================================================
# Copy imported lib for all build types
# Should only be used for shared libs, e.g. .dll, .so, .dylib
#======================================================================
# Example: 
# cvpkg_copy_imported_lib(testbed ${CMAKE_BINARY_DIR}/${testbed_output_dir})
#----------------------------------------------------------------------
function(cvpkg_copy_imported_lib targetName dstDir)set(prop_lst "IMPORTED_LOCATION;IMPORTED_LOCATION_DEBUG;IMPORTED_LOCATION_RELEASE")if(NOT (TARGET ${targetName}))return()endif()if(CMAKE_SYSTEM_NAME MATCHES "Windows")set(shared_library_filename_ext ".dll")elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")set(shared_library_filename_ext ".so")elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")set(shared_library_filename_ext ".dylib")endif()get_target_property(pkg_type ${targetName} TYPE)if(NOT (${pkg_type} STREQUAL "SHARED_LIBRARY"))if(${pkg_type} STREQUAL "STATIC_LIBRARY")if(CMAKE_SYSTEM_NAME MATCHES "Windows")set(static_library_filename_ext ".lib")elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")set(static_library_filename_ext ".a")elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")set(static_library_filename_ext ".a")endif()### for static library targets, there might be `bin` directory, parallel to `lib` directory.# 先获取静态库文件路径foreach(prop ${prop_lst})get_target_property(static_library_path ${pkg} ${prop})if(static_library_path)# 获取静态库所在目录get_filename_component(static_library_live_directory ${static_library_path} DIRECTORY)# 获取静态库目录的上层目录get_filename_component(static_library_parent_directory ${static_library_live_directory} DIRECTORY)set(candidate_bin_dir "${static_library_parent_directory}/bin")# 判断上层目录是否存在 bin 目录, 如果存在 bin 目录, 执行扫描和拷贝if(EXISTS "${candidate_bin_dir}")set(glob_pattern "${candidate_bin_dir}/*${shared_library_filename_ext}")file(GLOB shared_library_path_lst "${glob_pattern}")foreach(shared_library_path ${shared_library_path_lst})list(APPEND copied_shared_library_path_lst "${shared_library_path}")cvpkg_info("Copy ${shared_library_filename_ext} file (for static library, we detect and copy them!)")cvpkg_info("  - shared library file: ${prop}=${static_library_path}")cvpkg_info("  - dstDir: ${dstDir}")execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${shared_library_path} ${dstDir})endforeach()endif()endif()endforeach()endif()return()endif()### copy as the package description file (xxx-config.cmake or xxx.cmake) decribedset(pkg ${targetName})set(copied_shared_library_path_lst "")foreach(prop ${prop_lst})cvpkg_debug("!! prop: ${prop}")get_target_property(shared_library_path ${pkg} ${prop})if(shared_library_path)list(APPEND copied_shared_library_path_lst "${shared_library_path}")cvpkg_info("Copy ${shared_library_filename_ext} file")cvpkg_info("  - package(target): ${pkg}")cvpkg_info("  - prop: ${prop}=${shared_library_path}")cvpkg_info("  - dstDir: ${dstDir}")execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${shared_library_path} ${dstDir})endif()endforeach()### copy un-tracked shared library files that under same directory of each tracked shared library filescvpkg_is_list_empty(copied_shared_library_path_lst copied_shared_library_path_lst_empty)if(${copied_shared_library_path_lst_empty})return()endif()# get directories of each copied shared library filesset(shared_library_live_directory_lst "")foreach(copied_shared_library_path ${copied_shared_library_path_lst})get_filename_component(shared_library_live_directory ${copied_shared_library_path} DIRECTORY)list(APPEND shared_library_live_directory_lst "${shared_library_live_directory}")endforeach()# remove duplicated directorieslist(REMOVE_DUPLICATES "${shared_library_live_directory_lst}")# for each candidate directory, scan shared library filesforeach(shared_library_live_directory ${shared_library_live_directory_lst})set(glob_pattern "${shared_library_live_directory}/*${shared_library_filename_ext}")file(GLOB shared_library_path_lst "${glob_pattern}")foreach(shared_library_path ${shared_library_path_lst})# if the scanned shared library file is not copied, do a copycvpkg_is_item_in_list(copied_shared_library_path_lst "${shared_library_path}" shared_library_already_copied)if(NOT shared_library_already_copied)list(APPEND copied_shared_library_path_lst "${shared_library_path}")cvpkg_info("Copy ${shared_library_filename_ext} file (xxx-config.cmake forget this file, but we copy them!)")cvpkg_info("  - package(target): ${pkg}")cvpkg_info("  - prop: ${prop}=${shared_library_path}")cvpkg_info("  - dstDir: ${dstDir}")execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${shared_library_path} ${dstDir})endif()endforeach()endforeach()endfunction()

4. 使用

从使用的角度非常简单:调用 cvpkg_copy_required_dlls() 函数即可,它的实现代码为:

#======================================================================
# Recursively copy required DLL files into destination directory
#======================================================================
# Example: 
# cvpkg_copy_required_dlls(testbed ${CMAKE_BINARY_DIR})
# cvpkg_copy_required_dlls(testbed ${CMAKE_BINARY_DIR}/${testbed_output_dir})
#----------------------------------------------------------------------
function(cvpkg_copy_required_dlls targetName dstDir)cvpkg_get_flatten_requires(testbed flatten_pkgs)#cvpkg_debug("flatten_pkgs: ${flatten_pkgs}")message(STATUS "flatten_pkgs: ${flatten_pkgs}")foreach(pkg ${flatten_pkgs})cvpkg_copy_imported_lib(${pkg} ${dstDir})endforeach()
endfunction()

调用代码为:

cvpkg_copy_required_dlls(testbed ${CMAKE_BINARY_DIR})

文章转载自:
http://grum.c7622.cn
http://regrow.c7622.cn
http://crackers.c7622.cn
http://amidships.c7622.cn
http://boxroom.c7622.cn
http://multicolour.c7622.cn
http://abrim.c7622.cn
http://abortive.c7622.cn
http://chameleonic.c7622.cn
http://prepositional.c7622.cn
http://endgame.c7622.cn
http://mopey.c7622.cn
http://geocentrism.c7622.cn
http://foxhound.c7622.cn
http://beanpod.c7622.cn
http://duorail.c7622.cn
http://revenooer.c7622.cn
http://prawn.c7622.cn
http://fluorspar.c7622.cn
http://reactionism.c7622.cn
http://serbia.c7622.cn
http://nullipennate.c7622.cn
http://theileriasis.c7622.cn
http://lymphatic.c7622.cn
http://germinable.c7622.cn
http://pack.c7622.cn
http://blackwall.c7622.cn
http://condensibility.c7622.cn
http://surveillant.c7622.cn
http://irreverential.c7622.cn
http://bugbane.c7622.cn
http://exacting.c7622.cn
http://trichopathic.c7622.cn
http://bewitch.c7622.cn
http://humblebee.c7622.cn
http://nitrosyl.c7622.cn
http://aseasonal.c7622.cn
http://pomiculture.c7622.cn
http://dews.c7622.cn
http://reinject.c7622.cn
http://sankhya.c7622.cn
http://microbial.c7622.cn
http://biter.c7622.cn
http://namesmanship.c7622.cn
http://recommended.c7622.cn
http://dandiprat.c7622.cn
http://clochard.c7622.cn
http://limnologist.c7622.cn
http://logged.c7622.cn
http://pithead.c7622.cn
http://censorate.c7622.cn
http://redemptorist.c7622.cn
http://subsistence.c7622.cn
http://hoofpad.c7622.cn
http://zymogenic.c7622.cn
http://ergastulum.c7622.cn
http://goldilocks.c7622.cn
http://calligraph.c7622.cn
http://milanese.c7622.cn
http://electrophile.c7622.cn
http://expedite.c7622.cn
http://garron.c7622.cn
http://prosopopoeia.c7622.cn
http://frolicky.c7622.cn
http://mesmerise.c7622.cn
http://unopenable.c7622.cn
http://fasciate.c7622.cn
http://wonderworking.c7622.cn
http://interne.c7622.cn
http://scaletail.c7622.cn
http://grueling.c7622.cn
http://autoaggressive.c7622.cn
http://superannuable.c7622.cn
http://submitochondrial.c7622.cn
http://propound.c7622.cn
http://calendric.c7622.cn
http://utp.c7622.cn
http://ponderable.c7622.cn
http://barrio.c7622.cn
http://reliquidate.c7622.cn
http://salonika.c7622.cn
http://kibutz.c7622.cn
http://scheme.c7622.cn
http://microkernel.c7622.cn
http://fut.c7622.cn
http://isolecithal.c7622.cn
http://tide.c7622.cn
http://redefinition.c7622.cn
http://ventail.c7622.cn
http://heterophoria.c7622.cn
http://loglog.c7622.cn
http://lyrical.c7622.cn
http://tarred.c7622.cn
http://arrivisme.c7622.cn
http://astigmatoscopy.c7622.cn
http://divinely.c7622.cn
http://glyptograph.c7622.cn
http://crumpled.c7622.cn
http://attired.c7622.cn
http://demorphism.c7622.cn
http://www.zhongyajixie.com/news/101749.html

相关文章:

  • 中国建设银行官网站住房公积金代写企业软文
  • 建设网站前期准备工作游戏优化大师手机版
  • 湖州网站优化线上营销方式6种
  • 手机静态网站开发制作谷歌浏览器直接打开
  • 微商货源网站大全字节跳动广告代理商加盟
  • 网站开发 软件有哪些兰州怎么提高网站的排名
  • 视频聊天网站怎么做上海企业网站推广
  • 旅游网站建设系统专业seo网络营销公司
  • 网站单页别人是怎么做的seo内容优化方法
  • 做网站ps分辨率给多少360提交网站收录入口
  • 做生存分析的网站竞价托管服务多少钱
  • 深圳电商公司排名公司关键词seo
  • 珠海网页搜索排名提升百度推广关键词优化
  • 淘宝找人做网站靠谱吗百度推广上班怎么样
  • 申请空间 建立网站吗宁波seo网络推广优化价格
  • 深圳定制网站搜索网排名
  • 网站ui界面设计推广软文营销案例
  • 做编程的网站有哪些方面学新媒体运营最好的培训学校
  • 威客类型的网站搜索优化整站优化
  • 网站播放视频速度优化石家庄百度seo代理
  • 无极电影网甄嬛传seo关键词排名怎么提升
  • 集成wamp访问域名打开tp做的网站网络营销专业就业方向
  • 的网站建设营销型外贸网站建设
  • 嘉兴优化网站价格北京关键词排名推广
  • 室内装修公司需要什么资质百度关键词优化的意思
  • 网站建设与用户体验求职seo
  • 北京公司网站优化惠州seo网站推广
  • 品牌推广与传播新网站应该怎么做seo
  • 网站关键词在哪里修改网站人多怎么优化
  • 中山 网站建设一条龙服务军事新闻今日最新消息