专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

CMake库搜索函数居然不搜索LDLIBRARYPATH

  摘要:本文通过编译后运行找不到库文件的问题引入,首先分析了findpackage(JNI)的工作流程,而后针对cmake不搜索LDLIBRARYPATH的问题,提出了一种通用的解决办法。
  本文分享自华为云社区《CMake库搜索函数居然不搜索LDLIBRARYPATH?由编译工具使用体验而引发的思考云社区华为云》,作者:蜉蝣与海。
  最近产品要使用JNI技术,CMake编译C代码时需要对外链接libjvm。so库。代码编译倒是正常,系统中也有libjvm。so,然而使用时却报了如下异常:errorwhileloadingsharedlibraries:libjvm。so:cannotopensharedobjectfile:Nosuchfileordirectory
  这个报错表示,操作系统并没有找到libjvm。so,我们的操作系统是从LDLIBRARYPATH中搜索这些动态链接库,很显然目前libjvm。so并不在这个目录下。
  问题的解决倒是简单,直接在LDLIBRARYPATH里加入libjvm。so的库即可。但是这却引发了我的思考:为什么构建时可以找到libjvm。so,运行时却找不到呢?
  这个问题的回答,既可以有简明扼要版解释,又可以刨根问底深挖。
  先来看简明扼要版解释:
  代码的CMakeList中使用了下列语句,在编译过程中寻找并链接libjvm。so,这个搜索方式和操作系统的搜索方式不同:findpackage(JNI)getfilenamecomponent(JVMLIBPATH{JAVAJVMLIBRARY}DIRECTORY)getfilenamecomponent(JAVALIBPATH{JVMLIBPATH}DIRECTORY)linkdirectories({JVMLIBPATH}{JAVALIBPATH})settargetproperties({NAME}PROPERTIESLINKFLAGSljvm)
  其中findpackage(JNI)会搜索libjvm。so可能存在的路径,通过getfilenamecomponent来获得libjvm。so的文件夹,并把这个文件夹设为默认搜索库路径。而后settargetproperties会进行链接工作。
  这个答案只能告诉我们是什么,但是作为一只程序猿,还要了解为什么,这里引申几个问题讨论:1、findpackage(JNI)的工作过程是怎样的?为什么LDLIBRARYPATH里没找到的依赖库,cmake可以找到2、cmake的库搜索函数findlibrary会搜索LDLIBRARYPATH吗,如果不会,可以通过设置来搜索LDLIBRARYPATH吗?问题一:findpackage(JNI)的工作过程是怎样的
  为了方便开发者引用外部包,cmake官方预定义了许多寻找依赖包的Module,他们存储在cmake的sharecmakeModules目录下。每个以Find。cmake命名的文件都可以帮我们找到一个包〔1〕。在本地计算机执行以下指令,即可找到findpackage(JNI)使用的脚本文件。findnameFindJNI。cmake
  打开自己的cmake对应的FindJNI文件,可以看到密密麻麻的注释和脚本,通过阅读这些脚本,我们得以得知FindJNI是如何工作的。
  分析问题前,先看问题带来的结果,文件最上方注释有如下说明:Thismodulesetsthefollowingresultvariables:JNIINCLUDEDIRStheincludedirstouseJNILIBRARIESthelibrariestouse(JAWTandJVM)JNIFOUNDTRUEifJNIheadersandlibrarieswerefound。CacheVariablesThefollowingcachevariablesarealsoavailabletosetoruse:JAVAAWTLIBRARYthepathtotheJavaAWTNativeInterface(JAWT)libraryJAVAJVMLIBRARYthepathtotheJavaVirtualMachine(JVM)libraryJAVAINCLUDEPATHtheincludepathtojni。hJAVAINCLUDEPATH2theincludepathtojnimd。handjniport。hJAVAAWTINCLUDEPATHtheincludepathtojawt。h
  这段代码表明,执行findpackage(JNI)之后,会有一系列变量被设置,其中包括表示JNI是否被找到的变量JNIFOUND,以及表示libjvm。so的变量JAVAJVMLIBRARY。这些变量在设定之后,通过FindPackageHandleStandardArgs导出,返回调用处,FindPackageHandleStandardArgs是cmake专门用来导出变量的宏〔2〕:include({CMAKECURRENTLISTDIR}FindPackageHandleStandardArgs。cmake)FINDPACKAGEHANDLESTANDARDARGS(JNIDEFAULTMSGJAVAAWTLIBRARYJAVAJVMLIBRARYJAVAINCLUDEPATHJAVAINCLUDEPATH2JAVAAWTINCLUDEPATH)
  在文件中定位JAVAJVMLIBRARY,可以追踪到下述代码片段:foreach(search{JNISEARCHES})findlibrary(JAVAJVMLIBRARY{JNI{search}JVM})findlibrary(JAVAAWTLIBRARY{JNI{search}JAWT})if(JAVAJVMLIBRARY)break()endif()endforeach()
  由此可知,JAVAJVMLIBRARY这个变量,是通过逐个搜索{JNI{search}JVM}里的文件夹进而确定JAVAJVMLIBRARY的。而{JNI{search}JVM}相关的定义语句如图:set(JNIFRAMEWORKJVMNAMESJavaVM)set(JNINORMALJVMNAMESjvmPATHS{JAVAJVMLIBRARYDIRECTORIES})
  其中JAVAJVMLIBRARYDIRECTORIES中涉及了大量可能的libjvm。so存在的路径。set(JAVAJVMLIBRARYDIRECTORIES)foreach(dir{JAVAAWTLIBRARYDIRECTORIES})list(APPENDJAVAJVMLIBRARYDIRECTORIES{dir}{dir}client{dir}serverIBMSDK,JavaTechnologyEdition,specificpaths{dir}j9vm{dir}default)endforeach()set(JAVAAWTLIBRARYDIRECTORIES)if(JAVAHOME)JAVAAPPENDLIBRARYDIRECTORIES(JAVAAWTLIBRARYDIRECTORIES{JAVAHOME}jrelib{libarch}{JAVAHOME}jrelib{JAVAHOME}lib{libarch}{JAVAHOME}lib{JAVAHOME})endif()JAVAAPPENDLIBRARYDIRECTORIES(JAVAAWTLIBRARYDIRECTORIES{JNIJAVAAWTLIBRARYTRIES})foreach(javadirINLISTSJNIJAVADIRECTORIESBASE)list(APPENDJNIJAVAAWTLIBRARYTRIES{javadir}jrelib{libarch}{javadir}jrelib{javadir}lib{libarch}{javadir}lib{javadir})list(APPENDJNIJAVAINCLUDETRIES{javadir}include)endforeach()
  如上图所示,变量依赖顺序如下:
  JAVAJVMLIBRARYDIRECTORIESJAVAAWTLIBRARYDIRECTORIESJNIJAVAAWTLIBRARYTRIESJAVAHOMEJNIJAVADIRECTORIESBASE
  最终发现JAVAJVMLIBRARYDIRECTORIES变量的值,是由JAVAHOME变量的值和JNIJAVADIRECTORIESBASE变量的值共同决定的。而JNIJAVADIRECTORYBASE预置了大量预定义路径:set(JNIJAVADIRECTORIESBASEusrlibjvmjavausrlibjavausrlibjvmusrlocallibjavausrlocalsharejavausrlibj2sdk1。4sunusrlibj2sdk1。5sunoptsunjdk1。5。0。04usrlibjvmjava6sunusrlibjvmjava1。5。0sunusrlibjvmjava6sun1。6。0。00canthisoneberemovedaccordingto8821?Alexusrlibjvmjava6openjdkusrlibjvmjava1。6。0openjdk1。6。0。0fedoraDebianspecificpathsfordefaultJVMusrlibjvmdefaultjavaArchLinuxspecificpathsfordefaultJVMusrlibjvmdefaultUbuntuspecificpathsfordefaultJVMusrlibjvmjava11openjdk{libarch}Ubuntu18。04LTSusrlibjvmjava8openjdk{libarch}Ubuntu15。10usrlibjvmjava7openjdk{libarch}Ubuntu15。10usrlibjvmjava6openjdk{libarch}Ubuntu15。10OpenBSDspecificpathsfordefaultJVMusrlocaljdk1。7。0usrlocaljre1。7。0usrlocaljdk1。6。0usrlocaljre1。6。0SuSEspecificpathsfordefaultJVMusrlib64jvmjavausrlib64jvmjre)
  通过以上分析可以看出,JAVAJVMLIBRARY的搜索,依赖JAVAHOME和大量预定义路径。问题二:cmake库搜索函数findlibrary会搜索LDLIBRARYPATH吗
  通过阅读DoesCMakesfindlibrarysearchLDLIBRARYPATH可以知道,findlibrary默认不搜索LDLIBRARYPATH,并且网上也找不到让cmake搜索LDLIBRARYPATH的文章。那cmake能搜索LDLIBRARYPATH吗?
  答案是可以的,通过cmake获取LDLIBRARYPATH环境变量,并转为cmake可理解的list格式,而后注入findlibrary即可,代码如下:string(REPLACE:;RUNTIMEPATHENV{LDLIBRARYPATH})findlibrary(JVMAPINAMESjvmHINTS{RUNTIMEPATH})if(JVMAPISTREQUALJVMAPINOTFOUND)message(WARNINGfoundlibjvm。soonlyin{JAVAJVMLIBRARY}butnotinLDLIBRARYPATH。environmentvariableLDLIBRARYPATHmustincludeitsdirectory。)endif()
  如果希望找不到这个库时编译失败,可以将WARNING改为fatalerror,代码如下:string(REPLACE:;RUNTIMEPATHENV{LDLIBRARYPATH})findlibrary(JVMAPINAMESjvmHINTS{RUNTIMEPATH})if(JVMAPISTREQUALJVMAPINOTFOUND)message(FATALERRORfoundlibjvm。soonlyin{JAVAJVMLIBRARY}butnotinLDLIBRARYPATH。environmentvariableLDLIBRARYPATHmustincludeitsdirectory。)endif()小结
  本文通过编译后运行找不到库文件的问题引入,首先分析了findpackage(JNI)的工作流程,而后针对cmake不搜索LDLIBRARYPATH的问题,提出了一种通用的解决办法。参考文献:
  〔1〕Cmake之深入理解findpackage()的用法:https:zhuanlan。zhihu。comp97369704?utmsourcewechatsession
  〔2〕Cmake中findpackage命令的搜索模式之模块模式(Modulemode):https:www。jianshu。compf983a90bcf91
  〔3〕DoesCMakesfindlibrarysearchLDLIBRARYPATH?:https:stackoverflow。comquestions41566316doescmakesfindlibrarysearchldlibrarypath
  点击下方,第一时间了解华为云新鲜技术
  华为云博客大数据博客AI博客云计算博客开发者中心华为云

寒假作文范文难忘的春节(15篇)难忘的春节日记1春节,是意味着新的一年的来临,春节也是我最喜欢的一个节日,春节是我最快乐的一天,因为,在春节我们可以收到很多红包,也可以和很多的小伙伴一起玩。春节的早晨,我和爸爸妈她,30岁前生活一塌糊涂,因一热爱,活成别人羡慕自己喜欢的样子怎样才能活的不累怎样的一生才算是有意义01为自己保留了一份热爱有一个女生,30岁之前,她的生活一塌糊涂。没有多少职场技能不漂亮没有高学历,普通话也不标准,妥妥的最普通的普通人。为了去泰国旅游,美女递的仙女果为何不能接?导游接了会吃亏现在我们中国的经济发展一直保持着非常高的发展速度,百姓的生活越来越好了,人们在工作之余,都愿意出门旅旅游,去看看外面的世界,尤其是出国旅游更是受青睐。(此处已添加小程序,请到今日头西方人到底多开放,地铁无裤日让人没眼看,游客辣眼睛众所周知,世界各国每个地方都有着专属当地的特色文化和习俗。(此处已添加小程序,请到今日头条客户端查看)正是由于各国之间有着不同的文化和习俗,这也使得世界更加地多姿多彩。为了体验到别Google应用中的更多AI带来什么?如果我问人们他们想要什么,他们会说更快的马。这种情绪,连同人们不知道他们想要什么,直到你向他们展示之类的衍生词,使得预测技术的未来变得困难,因为它需要一项创新才能完全改变范式。对于机器人液化越狱!中国团队实现终结者幻想,灵感竟来自海参梦晨羿阁发自凹非寺量子位公众号QbitAI终结者2中,液态金属机器人T1000变形穿过铁栅栏,追杀主角。30多年后,这一幕在实验室里成真了!只见乐高小人形状的机器人被关在监狱里,找地核反转,面对变局,分享几句大实话深夜刷文,刷到这篇地球内核发生反转热文。中国科学家研究确认目前地核自转方向与整体自转方向脱钩,开始反转。权威刊物,绝非儿戏,结论可足信。都说现在是百年大变局,地核反转足以说明变化之地震云能有效的预测地震?历史给出了答案导语世间事既是云云也是尔尔,我们总是盲目自大,自认为是主宰,可能这份自信正是来自于食物链顶端的优越感。可再强大的优越感在自然法则面前也只能偃旗息鼓,人类一直在与自然灾难斗争,正是因vivoX90Pro与iPhone14ProMax拍照对比哪个更优秀?虽然在拍摄视频方面,苹果手机独步天下,但在拍照方面,vivo的旗舰手机一直都是巅峰的存在,而且这款vivoX90Pro旗舰手机,还配备了在智能手机中有史以来最大的一英寸相机传感器,撮合风马牛不相及的植物物种杂交,成了!科技日报记者王延斌通讯员王静用牧草与小麦杂交,可培育出抗病性强的小麦新品种,用竹子和水稻杂交,可培育出品质优良的水稻新品种将看似风马牛不相及的两个物种撮合,在育种界被称为远缘杂交,Blog。Core开源完成升级。NET7。0(众里寻他千百度,)距离2022年的。Net大会已经过去两个多月了,。NET7。0也正式出来了很久了,一直想升级,一直没时间,也想着毕竟是只有18个月的标准支持版本,所以一直精力还
壮志凌云2不会在华上映!阿汤哥公然挑衅一中原则参考消息网6月6日报道英国每日电讯报网站6月4日发表题为中国在影院发起有力的爱国主义宣传的报道。报道称,随着电影壮志凌云2独行侠的上映,电影屏幕上再次充斥着咆哮的美国战斗机和勇敢又FPX官宣Gori离队并加入PSGFPX官宣了关于Gori选手的离队公告。内容如下经过与俱乐部及选手充分友好的协商沟通,FPX电子竞技俱乐部英雄联盟分部选手金泰佑(IDGori)即日起正式加盟PSG电子竞技俱乐部。做空中国?国际巨头这次栽了!行贿11国,操控油价!这才是真相?很多人不知道所谓的国际巨头是什么样的情况,今天我们就来说一说曾经做空中国的国际巨头嘉能可。国际大宗巨头嘉能可国际大宗巨头嘉能可嘉能可是名副其实的瑞士国际巨头,它成立于1974年,主2022年四川考生报考军校就看这一篇参军卫国,是很多考生的人生梦想。今年受疫情持续影响,高校研究生扩招厉害,就业竞争压力大。近几年,随着军队建设的快速发展,军人社会地位和待遇的日益提高,考军校是相当部分家长与考生理想罗建云东汽来了又走了,这对绵竹汉旺人来说犹如一场梦大炼钢铁无终自终。天池煤矿给汉旺带来新希望。川人川风一家亲。汉旺人成都人已融为一体。俗语肥肉上添膘,这句话放在汉旺这里很合适。鬼使神差,搞三线建设,哈尔滨汽轮机厂看中了山有万重水流因麻将馆收费贵,2017年四川小伙发明纸牌麻将,有人出50万买专利如果问大家中国的国粹有哪些?那大家可能会有很多答案,京剧武术书法中药等等不一而足,可有一种国粹至今还深受千家万户的喜爱,几乎是全国男女老少在过年期间必不可少的一种东西。没错,那就是众筹存款人人能科普,处处有新知本人有个想法,不知可不可行。众筹一亿元后跟银行谈更高的利息收益。启动方式是众筹一亿元,一万人即限制加入,每人一万元,全部存定期为五年(以银行的起始为准),每年明日芒种,不管多忙!芒种3宝别忘吃,顺应节气,舒舒服服过夏天芒种是夏天的第3个节气,也是仲夏的开始。芒与忙同音,杏黄麦熟忙耕种,提醒人们要忙碌起来了。因为芒种,既是北方收麦的时节,也是南方种稻的时节。江南一带更是流传着芒种插得是个宝,夏至插芒种风吹麦成浪蝉鸣夏始忙时光匆匆,节气更替,又到一年芒种时芒种,夏季的第三个节气标志仲夏正式开始月令七十二候集解五月节,谓有芒之种谷可稼种矣。农谚有云芒种芒种,连收带种这是一年中农事最中安时评弘扬正能量,以中国好评汇聚昂扬奋进时代洪流近日,以新时代新征程新青年为主题的2022好评中国网络评论大赛在湖南长沙正式启动。活动旨在进一步推动网络评论高质量发展,大力弘扬时代主旋律传播网络正能量,引领广大网民与祖国同呼吸共俄乌冲突第102天!普京罕见对乌克兰让步,25国抱团反对美国作者瞭望君俄罗斯与乌克兰的战争发生后,各种媒体就掐着算俄乌冲突第一天俄乌冲突第二天大家都在关注俄乌战争的局势,各样的信息扑面而来,难辨真假。不管真假,有一点可以说明,俄乌战争在很长
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网