1.5.6 库文件和搜索目录 .a .so

本文详细解释了在Makefile中如何使用-l参数指定链接库,包括静态库和共享库的搜索路径及规则,并介绍了变量.LIBPATTERNS的作用。


Makefile中程式链接的静态库、共享库同样也能有目录搜索得到。这一特性需要我们在书规则的依赖是指定一个类似“-lNNAM”的依赖文件名(一个奇怪的依赖文件名!一般依赖文件名应该是个普通文件的名字。库文件的命名也应该是“libNAME.a”而不是所写的“-lNAME”。这是为什么,熟悉GNU ld的话我想这就不难理解了,“-lNAME”的表示方式和ld的对库的引用方式完全相同,只是我们在书写Makefile的规则时使用了这种书写方式。因此你不应该感到奇怪)。下边我们就来看看这种奇怪的依赖文件到底是什么。
当规则中依赖文件列表中存在一个“-lNAME”形式的文件时。make将根据“NAME”首先搜索当前系统可提供的共享库,如果当前系统不能提供这个共享库,则搜索他的静态库(当然你能在命令行中指定编译或连接选项来指定动态连接还是静态连接,这里我们不讨论)。来看一下周详的过程。1. make在执行规则时会在当前目录下搜索一个名字为“libNAME.so”的文件;2. 如果当前工作目录下不存在这样一个文件,则make程式会继续搜索使用“VPATH”或“vpath”指定的搜索目录。3. 还是不存在,make程式将搜索系统默认目录,顺序是:“/lib”、“/usr/lib”和“PREFIX/lib”(在Linux系统中为“/usr/local/lib”,其他的系统可能不同)。
如果“libNAME.so”通过以上的途径最后还是没有找到的话,那么make程式将会按照以上的搜索顺序查找名字为“libNAME.a”的文件。
假设你的系统中存在“/usr/lib/libcurses.a”(不存在“/usr/lib/libcurses.so”)这个库文件。看一个例子:

foo : foo.c -lcurses
cc $^ -o $@

上例中,如果文件“foo.c”被修改或“/usr/lib/libcurses.a”被更新,执行规则时将使用命令“cc foo.c /usr/lib/libcurses.a -o foo”来完成目标文件的重建。需要注意的是:如果“/usr/lib/libcurses.a”需要在执行make的时生成,那么就不能这样写,因为“-lNAME”只是告诉了链接器在生成目标时需要链接那个库文件。上例的中的“-lcurses”并没有告诉make程式其依赖的库文件应该怎么重建。当搜索的所有目录中不存在库“libcurses”时。Make将提示“没有规则能创建目标“foo”需要的目标“-lcurses”。如果在执行make时,出现这样的提示信息,你应该明确发生了什么错误,而不要因为错误而不知所措。
当规则的依赖列表中出现了“-lNAME”格式的依赖,默认搜索的文件名为“libNAME.so”和“libNAME.a”,这是由变量“.LIBPATTERNS”来指定的。“.LIBPATTERNS”的值一般是多个包含模式字符(%)的字(一个不包含空格的字符串),多个字之间使用空格分开。在规则中出现“-lNAME”格式的的依赖时,首先使用这里的“NAME”代替变量“.LIBPATTERNS”的第一个字的模式字符(%)而得到第一个库文件名,根据这个文件名在搜索目录下查找,如果能够找到、就是用这个文件,否则使用“NAME”代替第二个字的模式字符,进行同样的查找。默认情况时,“.LIBPATTERNS”的值为:“lib%.so lib%.a”。这也是默认情况下在规则存在“-lNAME”格式的依赖时,链接生成目标时使用“libNAME.so”和“libNAME.a”的原因。
变量“.LIBPATTERNS”就是告诉链接器在执行链接过程中对于出现“-LNAME”的文件怎么展开。当然我们也能将此变量制空,取消链接器对“-lNAME”格式进行展开。

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2025-11-12 08:41:44.339 ERROR 7 --- [ main] o.s.boot.SpringApplication : Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'initServer': Invocation of init method failed; nested exception is java.lang.UnsatisfiedLinkError: no jniavdevice in java.library.path at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:929) ~[spring-context-5.3.31.jar!/:5.3.31] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591) ~[spring-context-5.3.31.jar!/:5.3.31] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.18.jar!/:2.7.18] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:732) [spring-boot-2.7.18.jar!/:2.7.18] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:409) [spring-boot-2.7.18.jar!/:2.7.18] at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-2.7.18.jar!/:2.7.18] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) [spring-boot-2.7.18.jar!/:2.7.18] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289) [spring-boot-2.7.18.jar!/:2.7.18] at com.hohht.video.HohhotVideoBackendApplication.main(HohhotVideoBackendApplication.java:16) [classes!/:0.0.1-SNAPSHOT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_412] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_412] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_412] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_412] at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [Hohhot-video-backend-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) [Hohhot-video-backend-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [Hohhot-video-backend-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) [Hohhot-video-backend-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] Caused by: java.lang.UnsatisfiedLinkError: no jniavdevice in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1860) ~[na:1.8.0_412] at java.lang.Runtime.loadLibrary0(Runtime.java:843) ~[na:1.8.0_412] at java.lang.System.loadLibrary(System.java:1136) ~[na:1.8.0_412] at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1738) ~[javacpp-1.5.6.jar!/:1.5.6] at org.bytedeco.javacpp.Loader.load(Loader.java:1345) ~[javacpp-1.5.6.jar!/:1.5.6] at org.bytedeco.javacpp.Loader.load(Loader.java:1157) ~[javacpp-1.5.6.jar!/:1.5.6] at org.bytedeco.javacpp.Loader.load(Loader.java:1133) ~[javacpp-1.5.6.jar!/:1.5.6] at org.bytedeco.ffmpeg.global.avdevice.<clinit>(avdevice.java:28) ~[ffmpeg-4.4-1.5.6.jar!/:4.4-1.5.6] at java.lang.Class.forName0(Native Method) ~[na:1.8.0_412] at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_412] at org.bytedeco.javacpp.Loader.load(Loader.java:1212) ~[javacpp-1.5.6.jar!/:1.5.6] at org.bytedeco.javacpp.Loader.load(Loader.java:1157) ~[javacpp-1.5.6.jar!/:1.5.6] at org.bytedeco.javacpp.Loader.load(Loader.java:1149) ~[javacpp-1.5.6.jar!/:1.5.6] at com.hohht.video.a24.init.InitServer.loadFFmpeg(InitServer.java:58) ~[classes!/:0.0.1-SNAPSHOT] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_412] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_412] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_412] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_412] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) ~[spring-beans-5.3.31.jar!/:5.3.31] at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) ~[spring-beans-5.3.31.jar!/:5.3.31] ... 26 common frames omitted Caused by: java.lang.UnsatisfiedLinkError: /root/.javacpp/cache/ffmpeg-4.4-1.5.6-linux-x86_64.jar/org/bytedeco/ffmpeg/linux-x86_64/libjniavdevice.so: libxcb.so.1: cannot open shared object file: No such file or directory at java.lang.ClassLoader$NativeLibrary.load(Native Method) ~[na:1.8.0_412] at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1934) ~[na:1.8.0_412] at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1817) ~[na:1.8.0_412] at java.lang.Runtime.load0(Runtime.java:782) ~[na:1.8.0_412] at java.lang.System.load(System.java:1100) ~[na:1.8.0_412] at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:1685) ~[javacpp-1.5.6.jar!/:1.5.6] ... 43 common frames omitted
11-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值