我能否获得构建我的 C++ 时链接的所有库的报告?可执行文件(gcc)? (包括静态链接)

发布于 2024-10-16 13:46:12 字数 1249 浏览 5 评论 0原文

我继承了一个 C++ 应用程序,其中包括:

  • 我的主应用程序
  • 几个特定于应用程序的库(libapp1、libapp2 等...)
  • 几个“第三方”库(大多数“第三方只是公司中的其他团队” )从主应用程序、特定于应用程序的 libappX 库以及其他第三部分库(例如 libext1、libext2 等)链接...

换句话说,我的代码如下所示:

// main.C
#include <app1/a1l1.H>
#include <app2/a2l1.H>
#include <ext1/e1l1.H>

// app1/a1l1.H
#include <app1/a1l2.H>
#include <ext2/e2l1.H>

// app2/a2l1.H
#include <ext2/e2l2.H>

// ext1/e1l1.H
#include <ext3/e3l1.H>

// ext3/e3l1.H
#include <ext4/e4l1.H>

问题:

1) 我如何知道哪些库已链接到最终的可执行文件中? 这必须包括静态链接的

换句话说,我想要一个“app1,app2,ext1,ext2,ext3,ext4”的答案,

理想情况下,答案可以从可执行文件本身获得(我有一个它内置的调试版本,以防它变得更加可能)。如果这是不可能的,我想知道是否有一个简单的代码分析工具(即 gcc 本身内的东西)来提供该分析。

请注意,外部库的目标文件已经构建,因此查看构建日志以查看链接的内容,我担心“ext4”不会显示在日志中,因为我们不会构建“ext3” “ 已经预先构建的库。

注意:运行“nmake”并将 DEPS 设置为 yes 来重建所有内容不是一个选项。但我确实可以访问外部库的完整源代码。

2)一个稍微独立且不太重要的问题,我如何说出我正在构建的整个源代码树中使用的所有包含文件的列表。同样,理想情况下是已经构建的可执行文件,我有一个调试版本。

=================

更新:为了澄清,我们的库是静态链接的,因此 ldd (列出同步依赖项)不起作用。

此外,答案可以是 Solaris 或 Linux - 没关系。

我尝试使用 nm 但没有列出库

I have a C++ application that I inherited, which consists of:

  • My main app
  • Several app-specific libraries (libapp1, libapp2, etc...)
  • Several "third party" libraries (most "third partis are just other teams in the company") linked from both the main app, from the app-specific libappX libraries, and from other 3rd part libraries - e.g. libext1, libext2, etc...

In other words, my code looks like this:

// main.C
#include <app1/a1l1.H>
#include <app2/a2l1.H>
#include <ext1/e1l1.H>

// app1/a1l1.H
#include <app1/a1l2.H>
#include <ext2/e2l1.H>

// app2/a2l1.H
#include <ext2/e2l2.H>

// ext1/e1l1.H
#include <ext3/e3l1.H>

// ext3/e3l1.H
#include <ext4/e4l1.H>

QUESTIONs:

1) How can I tell which libraries have been linked into the final executable? This must include statically linked ones

In other words, I want an answer of "app1, app2, ext1, ext2, ext3, ext4"

Ideally, the answer would be available from the executable itself (I have a debug version of it built in case it makes it more possible). If that's impossible, i'd like to know if there's a simple code analysis tool (iedeally something within gcc itself) to provide that analysis.

Please note that the object files for external libraries are already built, so looking at the build logs to see what was linked, I'm worried that "ext4" won't show up in the log since we won't be building "ext3" library that is already pre-built.

NOTE: running "nmake" with DEPS set to yes to rebuild all the is NOT an option. But i DO have access to the full source code for external libraries.

2) A slightly separate and less important question, how can i tell a list of all the include files used in the entire source tree I'm building. Again, ideally frm already-built executable, which i have a debug version of.

=================

UPDATE: Just to clarify, our libraries are linked statically, so ldd (List Synamic Dependencies) does not work.

Also, the answer can be either for Solaris or Linux - doesn't matter.

I tried using nm but that doesn't list the libraries

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

维持三分热 2024-10-23 13:46:12

我遇到了类似的问题并找到了解决方案:链接时添加 -Wl,--verbose 选项。它将链接器切换到详细模式:

gcc -o test main.o -ltest -L. -Wl,--verbose

这是示例输出:

GNU ld (GNU Binutils) 2.23.52.20130604
  Supported emulations:
   i386pep
   i386pe
using internal linker script:
==================================================
/* Default linker script, for normal executables */
[many lines here]
==================================================
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o
attempt to open main.o succeeded
main.o
attempt to open ./libtest.dll.a failed
attempt to open ./test.dll.a failed
attempt to open ./libtest.a succeeded
(./libtest.a)test.o
[more lines here]
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o

更新: 您还可以使用 -Wl,--trace 选项代替 -Wl,--verbose。它还将为您提供库列表,但不太详细。

更新2: -Wl,--trace 不显示间接包含的库。示例:您与 libA 链接,而 libA 与 libB 链接。如果您想看到 libB 也需要,则必须使用 -Wl,--verbose。

I had similar problem and found solution: add -Wl,--verbose option when linking. It will switch linker to verbose mode:

gcc -o test main.o -ltest -L. -Wl,--verbose

Here is example output:

GNU ld (GNU Binutils) 2.23.52.20130604
  Supported emulations:
   i386pep
   i386pe
using internal linker script:
==================================================
/* Default linker script, for normal executables */
[many lines here]
==================================================
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/../../../../lib/crt0.o
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtbegin.o
attempt to open main.o succeeded
main.o
attempt to open ./libtest.dll.a failed
attempt to open ./test.dll.a failed
attempt to open ./libtest.a succeeded
(./libtest.a)test.o
[more lines here]
attempt to open /usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o succeeded
/usr/lib/gcc/x86_64-pc-cygwin/4.8.2/crtend.o

Update: You can also use -Wl,--trace option instead of -Wl,--verbose. It will also give you list of libraries, but is less verbose.

Update 2: -Wl,--trace does not display libraries included indirectly. Example: you link with libA, and libA was linked with libB. If you want to see that libB is needed too, you must use -Wl,--verbose.

一袭白衣梦中忆 2024-10-23 13:46:12

对于直接依赖;

ldd <app>

间接/所有依赖项;

ldd -r <app>

For direct dependencies;

ldd <app>

Indirect/All dependencies;

ldd -r <app>
吻安 2024-10-23 13:46:12

据我所知,链接时并没有保留太多有关静态库的信息(因为链接器只是将该库视为 *.o 对象的集合)。

如果您找到链接最终可执行文件的 make 命令并添加 -v 标志,g++ 将准确显示它如何调用 ld 命令。这应该包括所有必需的静态库,包括其他库使用的库,否则链接步骤将失败。但它也可能包含实际未使用的额外库。

另一个可能有用的事情是,至少在 Linux 上,对象和可执行文件通常存储创建它们的源代码文件的名称。 (只有文件名,没有路径。)尝试

objdump -t executable | grep '*ABS*'

As far as I know, not much information about static libraries is preserved when linking (since the linker just sees that library as a collection of *.o objects anyway).

If you find the make command that links the final executable and add a -v flag, g++ will show you exactly how it calls the ld command. This should include all necessary static libraries, including libraries used by other libraries, or otherwise the link step would fail. But it might also include extra libraries that aren't actually used.

Another possibly useful thing is that, at least on Linux, objects and executables usually store names of the source code files from which they were created. (Filename only, no path.) Try

objdump -t executable | grep '*ABS*'
秋日私语 2024-10-23 13:46:12

尝试使用 ldd + 你的文件名,这将列出库。

Try to use ldd + your filename, this will list the libs.

倾城°AllureLove 2024-10-23 13:46:12

我先回答你的第二个问题。您只需使用 -H-M 标志即可查看编译中处理的所有(包括系统)标头。 gcc -H main.c 应该可以解决问题。查看哪些标头
包含实际上会让您走上正确的道路,找到链接的静态库。

您可以在最终对象上使用 objdump(或在最终二进制文件上使用 readelf)获取其中所有函数的名称。然后你必须找到从中提取函数的库,但这有点麻烦。您肯定需要编写一个脚本来最大程度地减少痛苦。

其他人提到使用 gcc; -Wl,-verbose 只是将 -verbose 标志传递给链接器。这是获取共享库(.so 文件)列表的完美方法,但您说您的共享库是静态的,因此在这种情况下这不是可行的方法。

祝你好运!

I'll answer your second question first. You can simply use the -H or -M flag to see all (including system) headers processed in the compilation. gcc -H main.c should do the trick. Seeing which headers
are included will actually get you on the right track to finding which static libraries were linked in.

You could use objdump on your final object (or readelf on your final binary) to get the names of all the functions in there. You'd then have to go find the libraries from which the functions were pulled in, but that's a bit cumbersome. You'd definitely have to make a script to minimize the pain.

Someone else mentioned using gcc <stuff> -Wl,-verbose which simply passes the -verbose flag to the linker. That's a perfect way to get a list of shared libraries (.so files), but you said yours are static, so that isn't the way to go in this case.

Good luck!

清风无影 2024-10-23 13:46:12

这是我用来生成链接时依赖项的内容:

-include .deps/TARGET.d

$(TARGET): $(OBJECTS)
    @echo " LINK $(TARGET)"
    @echo '$(TARGET): \' > .deps/TARGET.d
    @$(CXX) -o $(TARGET) $(OBJECTS) $(LDLIBS) -Wl,--trace | sed -r -e "s#.*\(($(MY_LIB_DIR)).*)\).*#\t\\1 \\\\#p;d" | sort | uniq >> .deps/TARGET.d

它生成一个 .deps/TARGET.d 文件,如下所示:

$(TARGET): \
    /home/user/project/lib/lib1.a \
    /home/user/project/lib/lib2.a \
    /home/user/project2/bin/lib3.so \

Here's what I use to generate link-time dependencies:

-include .deps/TARGET.d

$(TARGET): $(OBJECTS)
    @echo " LINK $(TARGET)"
    @echo '$(TARGET): \' > .deps/TARGET.d
    @$(CXX) -o $(TARGET) $(OBJECTS) $(LDLIBS) -Wl,--trace | sed -r -e "s#.*\(($(MY_LIB_DIR)).*)\).*#\t\\1 \\\\#p;d" | sort | uniq >> .deps/TARGET.d

it generates a .deps/TARGET.d file that looks like this:

$(TARGET): \
    /home/user/project/lib/lib1.a \
    /home/user/project/lib/lib2.a \
    /home/user/project2/bin/lib3.so \

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文