是否可以识别对应于某些头文件的库?
Is it possible to identify the library that correspond to certain header files?
假设我们在同一个目录下有几个头文件和库文件。如果我不知道应该 link 反对哪个库,我能否以编程方式确定必须使用哪个库。
假设我尝试编译我的代码,linker 抱怨未解析的外部符号,知道正确的库存在于同一目录中,我能做些什么吗?
"Can I programmatically determine which library must be used."
不在同一个program/codebase内。 "programmatic"(比如 template
技巧等)能力一直保留到编译阶段。一旦 linking 开始(截至今天),控制就消失了。
"Is there anything I can do, knowing that the correct library exists in the same directory?"
同样没有。我无意打消你的积极性,但你所问的无论如何都无济于事。假设,您以某种方式设法找到一种方法来了解该库是否存在于同一目录中。它有什么作用?因为实际上库可以驻留在任何路径中。只需在 MSVC 中设置路径变量或在 gcc 中设置 -L
选项。因此,将库放在同一目录中的问题没有实际意义。
可能您可能想问,如何知道该库是否存在于您的系统中以及位置。
好吧,这当然不可能在同一代码库中以编程方式实现。因为您必须 运行 该代码库才能查找该库是否存在于您系统中的某个位置。要 运行 该代码库,您必须 link 它。先有鸡还是先有蛋的问题。
您可以手动检查或编写自己的单独 script/code 来完成此任务。
也许使用dll更好
GetProcAddress function in C++
或者,如果您自己编写 lib,则可以像这样在 header 中添加代码:
'#'pragma 注释( lib, "libname.lib" )
希望对你有帮助
我认为这个问题的答案可能对您有很大帮助:Tools for inspecting .lib files?。
你可以写一个简单的脚本,循环遍历目录下的所有lib文件,然后调用dumpbin将所有lib的符号转储到一个以lib名称开头的文件中,这样以后你就可以在生成的文件中搜索您需要的符号以获取正确的库。
最近学习C++比较多,遇到了类似的问题。大多数图书馆和 header 似乎至少共享一个相似的名称,但 "libm" 和 "math.h" 之间的差异真的让我想知道如何更系统地确定这一点。
对于静态库和动态库,我发现有用的工具是 readelf
,我喜欢的命令是:
readelf --symbols <elf_file> | sed -ne '/FUNC/p'
所以对于我的激励示例:
$ readelf --symbols /lib/libm.so.5 | sed -ne '/FUNC/p'
2: 0000000000000000 476 FUNC WEAK DEFAULT UND __cxa_finalize@FBSD_1.0 (8)
4: 0000000000000000 62 FUNC GLOBAL DEFAULT UND __isinf@FBSD_1.0 (8)
5: 0000000000000000 310 FUNC GLOBAL DEFAULT UND ldexp@FBSD_1.0 (8)
6: 0000000000000000 41 FUNC GLOBAL DEFAULT UND __isinff@FBSD_1.0 (8)
9: 0000000000000000 8 FUNC GLOBAL DEFAULT UND __tls_get_addr@FBSD_1.0 (8)
11: 0000000000000000 16 FUNC GLOBAL DEFAULT UND __stack_chk_fail@FBSD_1.0 (8)
12: 0000000000000000 53 FUNC GLOBAL DEFAULT UND __isinfl@FBSD_1.0 (8)
14: 0000000000000000 84 FUNC GLOBAL DEFAULT UND memset@FBSD_1.0 (8)
16: 0000000000004ed0 6 FUNC GLOBAL DEFAULT 12 lrintf@@FBSD_1.0
17: 0000000000019930 405 FUNC GLOBAL DEFAULT 12 log10l@@FBSD_1.3
18: 0000000000016590 600 FUNC GLOBAL DEFAULT 12 floorl@@FBSD_1.0
...
此命令也适用于 ar
存档文件,例如 libcurl.a。
所以在这里你可以看到库中定义的函数。从那里,我直观地比较了最后一列中的名称,如 "log10l" 和 header 文件 /usr/include/math.h 中的名称,发现高度对应。基于此编写程序对我来说似乎是可行的。解析上面 readelf 命令的最后一列,并对 /usr/include 中的所有 .h
个文件执行 grep。不过,我并没有走那么远。
在做了一些与我的答案相关的实验之后,我发现 sed
命令可能也可以根据您的需要进行更多改进。当我在 libcurl.a 上使用 readelf
时,non-global 函数(因此,不需要包含在 header 文件中的函数)也被输出。
假设我们在同一个目录下有几个头文件和库文件。如果我不知道应该 link 反对哪个库,我能否以编程方式确定必须使用哪个库。
假设我尝试编译我的代码,linker 抱怨未解析的外部符号,知道正确的库存在于同一目录中,我能做些什么吗?
"Can I programmatically determine which library must be used."
不在同一个program/codebase内。 "programmatic"(比如 template
技巧等)能力一直保留到编译阶段。一旦 linking 开始(截至今天),控制就消失了。
"Is there anything I can do, knowing that the correct library exists in the same directory?"
同样没有。我无意打消你的积极性,但你所问的无论如何都无济于事。假设,您以某种方式设法找到一种方法来了解该库是否存在于同一目录中。它有什么作用?因为实际上库可以驻留在任何路径中。只需在 MSVC 中设置路径变量或在 gcc 中设置 -L
选项。因此,将库放在同一目录中的问题没有实际意义。
可能您可能想问,如何知道该库是否存在于您的系统中以及位置。
好吧,这当然不可能在同一代码库中以编程方式实现。因为您必须 运行 该代码库才能查找该库是否存在于您系统中的某个位置。要 运行 该代码库,您必须 link 它。先有鸡还是先有蛋的问题。
您可以手动检查或编写自己的单独 script/code 来完成此任务。
也许使用dll更好 GetProcAddress function in C++ 或者,如果您自己编写 lib,则可以像这样在 header 中添加代码: '#'pragma 注释( lib, "libname.lib" ) 希望对你有帮助
我认为这个问题的答案可能对您有很大帮助:Tools for inspecting .lib files?。
你可以写一个简单的脚本,循环遍历目录下的所有lib文件,然后调用dumpbin将所有lib的符号转储到一个以lib名称开头的文件中,这样以后你就可以在生成的文件中搜索您需要的符号以获取正确的库。
最近学习C++比较多,遇到了类似的问题。大多数图书馆和 header 似乎至少共享一个相似的名称,但 "libm" 和 "math.h" 之间的差异真的让我想知道如何更系统地确定这一点。
对于静态库和动态库,我发现有用的工具是 readelf
,我喜欢的命令是:
readelf --symbols <elf_file> | sed -ne '/FUNC/p'
所以对于我的激励示例:
$ readelf --symbols /lib/libm.so.5 | sed -ne '/FUNC/p'
2: 0000000000000000 476 FUNC WEAK DEFAULT UND __cxa_finalize@FBSD_1.0 (8)
4: 0000000000000000 62 FUNC GLOBAL DEFAULT UND __isinf@FBSD_1.0 (8)
5: 0000000000000000 310 FUNC GLOBAL DEFAULT UND ldexp@FBSD_1.0 (8)
6: 0000000000000000 41 FUNC GLOBAL DEFAULT UND __isinff@FBSD_1.0 (8)
9: 0000000000000000 8 FUNC GLOBAL DEFAULT UND __tls_get_addr@FBSD_1.0 (8)
11: 0000000000000000 16 FUNC GLOBAL DEFAULT UND __stack_chk_fail@FBSD_1.0 (8)
12: 0000000000000000 53 FUNC GLOBAL DEFAULT UND __isinfl@FBSD_1.0 (8)
14: 0000000000000000 84 FUNC GLOBAL DEFAULT UND memset@FBSD_1.0 (8)
16: 0000000000004ed0 6 FUNC GLOBAL DEFAULT 12 lrintf@@FBSD_1.0
17: 0000000000019930 405 FUNC GLOBAL DEFAULT 12 log10l@@FBSD_1.3
18: 0000000000016590 600 FUNC GLOBAL DEFAULT 12 floorl@@FBSD_1.0
...
此命令也适用于 ar
存档文件,例如 libcurl.a。
所以在这里你可以看到库中定义的函数。从那里,我直观地比较了最后一列中的名称,如 "log10l" 和 header 文件 /usr/include/math.h 中的名称,发现高度对应。基于此编写程序对我来说似乎是可行的。解析上面 readelf 命令的最后一列,并对 /usr/include 中的所有 .h
个文件执行 grep。不过,我并没有走那么远。
在做了一些与我的答案相关的实验之后,我发现 sed
命令可能也可以根据您的需要进行更多改进。当我在 libcurl.a 上使用 readelf
时,non-global 函数(因此,不需要包含在 header 文件中的函数)也被输出。