关于这两天在折腾的cmake动态库与静态库
作者:互联网
先提出一个问题:有两个C项目,一个叫demo,一个叫test,demo项目里面有一个函数,然后demo会编译出一个静态库或者动态库,然后把这个库文件导入到test项目,test项目中也有一个函数,它会调用demo库中的函数,然后也把test项目编译出一个静态库或者动态库,然后再把库文件移到其他项目中(C项目或者JNI项目)使用。这很有用,因为可能我的JNI项目就是写一个jni函数去调用库文件里面封装的函数,我必须得理解动态库静态库的区别。
先谈一下Linux下的情况:
demo项目分次编译出libdemo.so和libdemo.a,拷贝出来。然后创建test项目,链接libdemo.a,生成libtest.so,使用ldd -r可以看到libtest.so不依赖任何so库文件;链接libdemo.so,生成libtest.so,使用ldd -r可以看到libtest.so依赖libdemo.so。
如果demo项目编译出静态库文件,test链接静态库文件生成动态库文件,动态库文件导入新项目就可以通过test动态库调用demo的函数;如果demo项目编译出的是动态库文件,test链接这个动态库之后,如果要使用test的动态库,那么test是依赖demo的,也就是说两个动态库要么放到一起,要么demo放到系统的环境变量中,前者是整合,后者分开。
在Windows下遇到十分诡异的事情,两件吧,第一件是Windows下编译产生的是so文件,而且cmake中要链接的动态库也是so文件,可能是因为用msys2的原因,不过这个so文件改成dll在正常的Windows环境下是可以正常使用的,ida识别也是Windows库文件。第二件是Windows下产生的动态库文件,放到其他项目中不能使用,主要表现在编译时说不通过,说找不到库文件,但是命名那个库文件是在那里的,经过反复测试,发现第一个项目编译的时候add_library指定的那个库名,第二个项目链接那个库名编译能通过,但是如果第一个项目的库名改了,编译出来的库放到原来的位置,第二个项目都编译不通过,项目原封不动copy到Linux,把build删了,重新编译,编译通过,再搬回Windows,把build删了,重新编译,编译不通过。(你敢信我居然为了一个玄学的命名一直测试命名测了两个小时?)
之后测试了一下,因为在项目中lib目录下放了静态库文件,导致cmakelist链接到的是同名静态库而非动态库文件,删了静态库文件后就无法编译了,这倒也挺诡异的,是为什么会这样?我又试了一下,发现cmake是有一个find_library的函数,可以指定一个特定的so库,然后用target_link_libraries可以链接到动态库,编译成功。
总结一下就是,两种系统,静态链接库不管哪种方式都可以;在Linux下可以link_directories,然后target_link_libraries链接动态库,也可以find_library直接指定在哪个目录下找特定的动态库文件,再用target_link_libraries链接动态库,但是Windows下只能后者。当然这么说也不是绝对的,至少在我的系统中是这样的。
其实吧,大学学个C,学个C++都只教语法,感觉不太行,很多人一个ide集成环境装上去直接就用,配环境的确很煎熬,但是只有在运行的时候遇到了问题并且解决了问题,那才是真的学到东西了。
标签:文件,cmake,静态,demo,编译,折腾,test,so,动态 来源: https://www.cnblogs.com/thankvincisdaily/p/16177150.html