【问题标题】:Using a class from another project in C++在 C++ 中使用来自另一个项目的类
【发布时间】:2011-06-08 23:23:18
【问题描述】:

我可以访问一个大型 C++ 项目,其中包含大量文件和一个非常复杂的 makefile,由 automake 和朋友提供

这是目录结构的一个想法。

otherproject/
  folder1/
    some_headers.h
    some_files.cpp
  ...
  folderN/
    more_headers.h
    more_files.cpp

  build/
    lots_of things here
    objs/
      lots_of_stuff.o
      an_executable_I_dont_need.exe

my_stuff/
   my_program.cpp

我想使用大项目中的一个类,声明为“some_header.h”

/* my_program.cpp */
#include "some_header.h"

int main()
{
    ThatClass x;
    x.frobnicate();
}

我通过煞费苦心地将大量“-I”选项传递给 gcc 来编译我的文件,以便它可以找到所有头文件

g++ my_program.cpp -c -o myprog.o -I../other/folder1 ... -I../other/folderN

在编译时,我必须手动包含他所有的“.o”,这可能是矫枉过正

g++ -o my_executable myprog.o ../other/build/objs/*.o 

但是,我不仅需要手动从列表中删除他的“main.o”,而且这还不够,因为我忘记了还链接到他碰巧使用的所有库。

otherproject/build/objs/StreamBuffer.h:50: undefined reference to `gzread'

此时我开始觉得我可能做错了什么。 我应该如何进行?解决此类问题的常用方法和最佳方法是什么?


如果需要执行特定于平台的操作,我需要它在 Linux 上工作。

【问题讨论】:

  • ThatClass x(); 是最令人头疼的解析的经典案例。你的意思可能是ThatClass x;

标签: c++ compilation autotools automake


【解决方案1】:

通常,项目的.o 文件应该组合到一个库中(在 Linux 上,.a 文件如果是静态库,.so 如果它是动态库),然后使用-L 选项指定位置,-l 选项指定库名称。

例如,如果库文件位于 /path/to/big_project/libbig_project.a,您可以将选项 -L /path/to/big_project -l big_project 添加到 gcc 命令行。

如果项目没有有一个可以链接到的库文件(例如,它不是一个库而是一个可执行程序,而你只需要一些可执行程序使用的代码),您可能想尝试让项目的作者创建这样一个库文件(如果他/她熟悉“automake and friends”,这对他来说应该不会太麻烦),或者尝试自己这样做。

EDIT 另一个建议:您说该项目带有一个makefile。尝试使用 makefile makeing 它,看看它的编译器命令行是什么样子的。它是否也有许多包含和单独的目标文件?

【讨论】:

  • 我没有找到任何 .a.so 文件。我可以自己做一个吗?
  • 你可以。我不知道用自动工具来做,但你应该可以用ar手动做。
  • 可能类似于ar rcs libbig_project.a build/objs/*.o
  • @Danton:不幸的是,这并没有解决链接其他项目使用的库的问题:(我现在正在尝试查看 autotools 是否为我做这种事情。
【解决方案2】:

将未开发为库的应用程序视为库是不可能的。举个简单的例子,省略main 可能最终会删除你想要的类所依赖的初始化代码。

这里要做的负责任的事情是阅读代码,理解它,并将您想要的功能转化为适当的库。用调试符号构建“你不需要的exe”,并在类的构造函数和方法中设置断点。深入了解它们,以便您了解功能以及程序的哪些部分与您的需求相关和不相关。

希望代码处于某种支持分支的版本控制系统(例如 Git)下。如果没有,请创建自己的存储库。编辑这些文件,直到您将它们组织到一个库和使用该库的代码中。确保它在原始程序的上下文中正常工作。然后转身在自己的程序中使用这个库。

如果您做得很好,您也许可以说服原作者接受分离回到他们的原始代码库。如果没有,至少版本控制会为您提供支持,这样您就可以管理未来更改的集成。

【讨论】:

  • 好点。幸运的是,在我的情况下,他的主要工作就是读取输入文件等。默认情况下,仅编译库不存在,因为大多数用户不想打扰 C++ API。或者我只是在构建的时候没有使用正确的参数,呵呵。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-29
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
相关资源
最近更新 更多