我读了一些不鼓励使用DYLD_LIBRARY_PATH的文章,因为动态库的路径应该使用-install_name,@ aptath和@loader_path来修复.
在制作在Linux和Mac OS X上运行的程序方面,Mac OS X的DYLD_LIBRARY_PATH正好与Linux的LD_LIBRARY_PATH完全相同.而且,我们可以(几乎)共享同一个没有-install_name和@rpath的make文件.
我有一个与另一个(第三方)共享库链接的共享库.然后在我的应用程序中使用dlopen加载我的共享库.所有这一切都很好(假设文件在正确的路径等).
现在,问题是当我链接我的库时,我甚至不需要指定链接第三方共享库.GCC接受它而不报告有关未定义引用的错误.那么,问题; 我如何强制GCC通知我未定义的引用?
如果我将库更改为(临时)可执行文件,则会获得未定义的引用(当不向链接器提供库时).(如果我指定它,工作正常.)
即,完成以下操作:
g++ -fPIC -shared -o libb.so b.o
g++ -fPIC -shared -o liba.so a.o
g++ -o a.exe a.cpp
Run Code Online (Sandbox Code Playgroud)
第二行没有给出错误,第三行抱怨未定义的引用.
示例代码:
啊:
class a
{
public:
void foobar();
};
Run Code Online (Sandbox Code Playgroud)
a.cpp:
#include "a.h"
#include "b.h"
void a::foobar()
{
b myB;
myB.foobar();
}
int main()
{
a myA; myA.foobar();
}
Run Code Online (Sandbox Code Playgroud)
BH:
class b
{
public:
void foobar();
};
Run Code Online (Sandbox Code Playgroud)
b.cpp:
#include "b.h"
void b::foobar()
{
}
Run Code Online (Sandbox Code Playgroud) 我链接两个不同的共享库.两个库都定义了一些共享名称但具有不同实现的符号.我不能让每个库使用自己的实现而不是另一个.
例如,两个库都定义了一个bar()内部调用的全局函数.库1调用它foo1(),库2调用它foo2().
Lib1.so:
T bar
T foo1() // calls bar()
Run Code Online (Sandbox Code Playgroud)
Lib2.so:
T bar
T foo2() // calls bar()
Run Code Online (Sandbox Code Playgroud)
如果我将我的应用程序链接到Lib1.so然后链接到Lib2.so即使在调用时也会调用Lib1.so中的bar实现foo2().另一方面,如果我将我的应用程序链接到Lib2.so然后链接到Lib1.so,则始终从Lib2.so调用bar.
有没有办法让库总是更喜欢自己的实现高于任何其他库?
我正在尝试编写一个简单的共享库,它可以将malloc调用记录到stderr(如果你愿意,可以使用某种'mtrace').
但是,这不起作用.这是我做的:
/* mtrace.c */
#include <dlfcn.h>
#include <stdio.h>
static void* (*real_malloc)(size_t);
void *malloc(size_t size)
{
void *p = NULL;
fprintf(stderr, "malloc(%d) = ", size);
p = real_malloc(size);
fprintf(stderr, "%p\n", p);
return p;
}
static void __mtrace_init(void) __attribute__((constructor));
static void __mtrace_init(void)
{
void *handle = NULL;
handle = dlopen("libc.so.6", RTLD_LAZY);
if (NULL == handle) {
fprintf(stderr, "Error in `dlopen`: %s\n", dlerror());
return;
}
real_malloc = dlsym(handle, "malloc");
if (NULL == real_malloc) {
fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
return;
} …Run Code Online (Sandbox Code Playgroud) 这可能听起来像一个愚蠢的问题,但如果你有一个thirdParty.framework文件,你能告诉它是静态的还是动态的?我的意思是,如果你看里面,他们看起来不一样吗?
我有几个小组件,我正在构建为我的主应用程序的共享库.允许使用的一个例子liba和libb.每个都在它们自己的子目录中构建,如下所示:
add_library(liba SHARED a.cpp)
Run Code Online (Sandbox Code Playgroud)
然后,在根项目文件夹中,我需要将我的主应用程序链接到两者.
include_directories(a)
include_directories(b)
add_executable(dummy dummy.cpp)
target_link_libraries(dummy a b)
Run Code Online (Sandbox Code Playgroud)
CMake运行正常,我的应用程序编译但无法链接.问题是b引用了a.如果我在链接时提供库的顺序
target_link_libraries(dummy b a)
Run Code Online (Sandbox Code Playgroud)
该程序编译和链接就好了
当这种系统开始涉及更复杂的库之间的依赖关系时,即使依赖关系是非循环的,它也开始变得不可能.如何在此管理链接步骤?在CMake中订购库以进行链接是否有诀窍?
我正在寻找一种直接从内存加载生成的目标代码的方法.
我知道如果我将它写入文件,我可以调用dlopen动态加载其符号并链接它们.然而,考虑到它从内存开始,写入磁盘,然后由dlopen重新加载到内存中,这似乎有点迂回.我想知道是否有某种方法来动态链接存在于内存中的目标代码.据我所知,可能有几种不同的方法来做到这一点:
尽管它永远不会留下记忆,但我还是认为你的记忆位置是一个文件.
找一些其他的系统调用来完成我正在寻找的东西(我认为这不存在).
找到一些动态链接库,它可以直接在内存中链接代码.显然,这个有点难以谷歌,因为"动态链接库"会显示有关如何动态链接库的信息,而不是关于执行动态链接任务的库的信息.
从链接器中提取一些API并在其代码库中创建一个新库.(显然这对我来说是最不可取的选择).
那么这些可能是哪些?可行?你能指出我假设存在的任何事情吗?还有另一种我甚至没想过的方法吗?
这个页面 - http://labs.qt.nokia.com/2011/10/28/rpath-and-runpath/ - 说明了ld.so中的库搜索顺序:
Unless loading object has RUNPATH:
RPATH of the loading object,
then the RPATH of its loader (unless it has a RUNPATH), ...,
until the end of the chain, which is either the executable
or an object loaded by dlopen
Unless executable has RUNPATH:
RPATH of the executable
LD_LIBRARY_PATH
RUNPATH of the loading object
ld.so.cache
default dirs
Run Code Online (Sandbox Code Playgroud)
然后建议:
当您发送二进制文件时,要么使用RPATH而不是RUNPATH,要么确保在运行之前设置LD_LIBRARY_PATH.
因此,使用RPATHwith RUNPATH是不好的,因为RUNPATH取消了类似的RPATH间接动态加载不能按预期工作?但为什么然后RPATH被弃用RUNPATH呢?
有人可以解释一下情况吗?
我想从一个简单的链接用法开始解释我的问题.让我们假设有一个库z可以编译为共享库libz.dll(D:/libs/z/shared/libz.dll)或静态库libz.a(D:/ libs/z/static/libz.一个).
让我想链接它,然后我这样做:
gcc -o main.exe main.o -LD:/libs/z/static -lz
Run Code Online (Sandbox Code Playgroud)
根据这个文档,gcc将搜索libz.a,即
归档文件,其成员是目标文件
我也可以做以下事情:
gcc -o main.exe main.o -LD:/libs/z/shared -lz
Run Code Online (Sandbox Code Playgroud)
在上面的文档中没有提到-l标志将搜索lib<name>.so.
如果我libz.a和libz.dll将在同一目录中会发生什么?图书馆如何与计划挂钩?为什么我需要标志-Wl,-Bstatic,-Wl,-Bdynamic如果-l搜索共享和静态库?
如果我编译共享库分发,为什么有些开发人员为.a文件提供相同模块的.dll文件?
例如,Qt在bin目录中提供.dll文件,其中包含lib目录中的.a文件.它是同一个库,但分别构建为共享和静态?或.a文件是某种虚拟库,提供与共享库的链接,其中有真正的库实现?
另一个例子是Windows上的OpenGL库.为什么每个编译器都必须在MingW中提供类似libopengl32.a的静态OpenGL库?
什么是.dll.a和.la扩展名用于的文件?
PS这里有很多问题,但我认为每个问题都取决于前一个问题,没有必要将它们分成几个问题.
我正在使用Django,当我运行时python manage.py runserver收到以下错误:
ImproperlyConfigured: Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-packages/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
Referenced from: /Library/Python/2.7/site-packages/_mysql.so
Reason: unsafe use of relative rpath libmysqlclient.18.dylib in /Library/Python/2.7/site-packages/_mysql.so with restricted binary
Run Code Online (Sandbox Code Playgroud)
我不完全确定如何解决这个问题.我已经通过pip安装了MySQL-python.然后我提前做了这一步.
我还想指出这是与El Capitan Beta 3.