linux环境下同时使用静态库、动态库编译程序

2024-05-09 02:18

本文主要是介绍linux环境下同时使用静态库、动态库编译程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 应用场景

因某些原因,需要同时使用静态库及动态库编译代码。
在这里我需要静态链接的是zbarlib,动态链接的是opencv库。
经过一个下午的艰苦奋斗,分享一下网上的解决方法以及最终导致不成功的原因所在。


2.Makfile实例

CXX=g++CFLAGS += -I${PWD}/../zbar/include
CFLAGS += -I${PWD}/../opencv/includeLDFLAGS += -Wl,-Bstatic -lzbar -L${PWD}/../zbar/lib 
LDFLAGS += -Wl,-Bdynamic -lpthread -lrt -lopencv_core  -lopencv_highgui  -lopencv_imgproc  -lopencv_ml  -lopencv_video -L${PWD}/../opencv/lib
LDFLAGS += -Wl,--as-neededobjects = main.o
target = mainall:${target}${target}:$(objects)$(CXX) $^ -o $@ ${LDFLAGS}%.o:%.cpp$(CXX) -c ${CFLAGS} $^ -o $@.PHONY:clean
clean:@rm -f  ${target}@rm -f  *.o

3.实例分析

可以看到makefile中编译参数使用的是
-Wl,-Bstatic
-Wl,-Bdynamic
-Wl,–as-needed
以上这三个参数。查看一下参数定义,可以看到

 -Wl,optionPass option as an option to the linker.  If option contains commas, it is split into multiple options at the commas.  You can use this syntax to pass an argument to the option.  For example, -Wl,-Map,output.map passes -Map output.map to the linker.  When using the GNU linker, you can also get the same effect with -Wl,-Map=output.map.  

NOTE: In Ubuntu 8.10 and later versions, for LDFLAGS, the option -Wl,-z,relro is used. To disable, use -Wl,-z,norelro.

主要功能就是向链接器传递参数,好像不加这个也可以编译通过。

   -Bdynamic-dy-call_sharedLink against dynamic libraries.  This is only meaningful on platforms for which shared libraries are supported.  This option is normally the default on such platforms.  The different variants of this option are for compatibility with various systems.  You may use this option multiple times on the command line: it affects library searching for -l options which follow it.-Bstatic-dn-non_shared-staticDo not link against shared libraries.  This is only meaningful on platforms for which shared libraries are supported.  The different variants of this option are for compatibility with various systems.  You may use this option multiple times on the command line:it affects library searching for -l options which follow it.  This option also implies --unresolved-symbols=report-all.  This option can be used with -shared.  Doing so means that a shared library is being created but that all of the library's external references must be   resolved by pulling in entries from static libraries.

-Bstatic 告诉链接器,链接静态库
-Bdynamic 告诉链接器,链接动态库

 --as-needed--no-as-neededThis option affects ELF DT_NEEDED tags for dynamic libraries mentioned on the command line after the --as-needed option.   Normally the linker will add a DT_NEEDED tag for each dynamic library mentioned on the command line, regardless of whether the library is actually needed or not.  --as-needed causes a DT_NEEDED tag to only be emitted for a library that at that point in the link satisfies a non-weak undefined symbol reference from a regular object file or, if the library is not found in the DT_NEEDED lists of other libraries, a non-weak undefined symbol reference from another dynamic library.  Object files or libraries appearing on the command line after the library in question do not affect whether the library is seen as needed.  This is similar to the rules for extraction of object files from archives.  --no-as-needed restores the default behaviour.

–as-needed 只给用到的动态库设置DT_NEEDED。


4. 错误

经过一个下午的折腾,发现仅仅是编译语句写得有问题,真是冤啊。

编译出错情况:

${target}:$(objects)$(CXX) ${LDFLAGS} $^ -o $@

其中 ${LDFLAGS} 参数放在 $^ -o $@前面,就会出现找不到静态库函数的错误,这里没有时间具体分析,后面有空研究研究。


5. 参考网站

http://blog.csdn.net/wangxvfeng101/article/details/15336955
http://blog.csdn.net/nodeathphoenix/article/details/9058531
http://www.cnblogs.com/little-ant/p/3398885.html

这篇关于linux环境下同时使用静态库、动态库编译程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972112

相关文章

Java设计模式之代理模式2-动态代理(jdk实现)

这篇是接着上一篇继续介绍java设计模式之代理模式。下面讲解的是jdk实现动态代理。 1.)首先我们要声明一个动态代理类,实现InvocationHandler接口 package com.zhong.pattern.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/*** 演

java设计模式之代理模式1--静态代理

Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术。生活中的方方面面都可以虚拟到代码中。代理模式所讲的就是现实生活中的这么一个概念:助手。 代理模式的定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。 1.)首先新建一个表演的接口 package com.zhong.pattern.proxy;/*** 表演接口* @author admin*

使用Array实现Java堆栈

本教程给出了使用Array 实现Stack数据结构的示例。堆栈提供将新对象放在堆栈上(方法push())并从堆栈中获取对象(方法pop())。堆栈根据后进先出(LIFO)返回对象。请注意,JDK提供了一个默认的Java堆栈实现作为类java.util.Stack。 适用于所有堆栈实现的两个强制操作是: push():数据项放置在堆栈指针指向的位置。pop():从堆栈指针指向的位置删除并返回数据

Spring Boot - 使用类类型信息获取所有已加载的bean

Spring启动会在内部加载大量bean,以最少的配置运行您的应用程序。在这个例子中,我们将学习如何找出所有那些Spring boot加载的bean及其类类型信息。 使用ApplicationContext获取所有已加载的bean 要自动执行方法,当应用程序完全加载时,我正在使用CommandLineRunner接口。CommandLineRunner用于指示bean 在Spring应用程序中

使用ThreadPoolExecutor创建线程池有哪些关键参数

1、ThreadPoolExecutor类的全参数构造方法: /*** Creates a new {@code ThreadPoolExecutor} with the given initial* parameters.** @param corePoolSize the number of threads to keep in the pool, even* if they

Linux命令学习之二

每日一结 ​               命令置换:是将一个命令的输出作为另一个命令的参数,命令格式如下: commond1 `command2` 其中,命令command2的输出将作为命令command1的参数,需要注意的是, 命令置换的单引号为ESC键下方的 ` 其意思就是说,先运行单引号内的命令,再将其命令作为

Linux命令学习之一

每日一结                                                                                        注:当用户不确定一个软件包的类型时, 可使用file命令查看文件类型

Linux文件I/O之一

每日一结(标准I/O)   一  库    本质 :一组实现函数接口 [printf,scanf,strcpy,strlen]   使用标准库好处:屏蔽底层细节,向上层提供统一的接口,提高程序的可移植性   windows 库 : *.dll  linux   库 : *.so    二 系统调用接口    本

Linux网络编程之五

每日一结 组播: ​ 网络地址: 一些特殊的组播地址:   一 组播包收和发 1.发送方 (1)创建用户数据报套接字 (2)填充组播地址和端口  (3)发送数据到组播地址 2.接收方  (1)创建用户数据报套接字 (2)加入组播组  struct ip_mreq mreq; mreq.imr_m

Linux网络编程之四

每日一结 一 UDP并发  核心思想:父进程接收到客户端的数据,就创建子进程,在子进程中创建一个新的套接字  和客户端交互  int do_client(接受客户端地址,数据,数据长度) { 1.创建用户数据报套接字  2.自动分配地址  3.处理数据[例如:输出数据内容] 4.通过新创建的套接字将数据回发给客户端  w