设置库包括 C++ 中的路径

Posted

技术标签:

【中文标题】设置库包括 C++ 中的路径【英文标题】:setting library include paths in c++ 【发布时间】:2010-03-23 01:25:45 【问题描述】:

我刚刚使用 mac 端口(sudo install gd2)安装了 gd2,它在以下位置安装了库:

/opt/local/include/gd.h
/opt/local/lib/libgd.dylib (link)
/opt/local/lib/libgd.la
/opt/local/lib/libgd.a

这也是我的制作文件:

dev: main.o
    g++ -L/opt/local/lib -I/opt/local/include -lgd -lpng -lz -ljpeg -lfreetype -lm main.o -o heatmap

main.o: main.cpp
    g++ -c main.cpp

所以当我创建我的 c++ 应用程序时,我添加了 '#include "gd.h"',它会抛出:

main.cpp:4:16: error: gd.h: No such file or directory

如果我将 gd.h 设置为绝对路径(如上)(不是解决方案,但很好奇),我会被抛出:

g++ -L/opt/local/include -L/opt/local/lib main.o -o heatmap
Undefined symbols:
  "_gdImagePng", referenced from:
      _main in main.o
  "_gdImageLine", referenced from:
      _main in main.o
  "_gdImageColorAllocate", referenced from:
      _main in main.o
      _main in main.o
  "_gdImageDestroy", referenced from:
      _main in main.o
  "_gdImageCreate", referenced from:
      _main in main.o
  "_gdImageJpeg", referenced from:
      _main in main.o
ld: symbol(s) not found

所以,我理解这意味着 ld 找不到它需要的库(因此试图用“-L”值给它提示)。因此,在 #include 中为 g++ 提供 -L 提示和绝对路径后,我可以让它工作,但我认为我不必这样做,我怎样才能让 g++/ld 搜索 int eh 库的正确位置?

德鲁·J·索恩。

PS。使用: - OSX 10.6.2 - gcc 版本 4.2.1(Apple Inc. build 5646)(点 1)

编辑: 好的,所以在考虑到 stfanB 和 Michael 的回答之后,我将 gd 重新编译到本地目录(libraries),因此,我将 Makefile 的第一行(我将检查 cmake)更改为 @987654326 @ 但我仍然收到main.cpp:3:16: error: gd.h: No such file or directory

编辑: 感谢大家的回答,这是我的最终(工作)makefile,供其他许多想要答案的人使用:

dev: main.o
    g++ -I./libraries/include -L./libraries/lib -lgd -lpng -lz -ljpeg -lfreetype -lm main.o -o heatmap

main.o: main.cpp
    g++ -I./libraries/include -c main.cpp

【问题讨论】:

【参考方案1】:

我强烈建议您不要直接调用 g++,而是使用CMake(如果您想了解更多信息,请观看CMake Google Techtalk),因为它可以让您的生活更轻松,并大大简化对各种类型的定位和链接的图书馆。也就是说,我认为您调用的问题在于您没有指定库,您将使用-lgd 来执行此操作。你的-L/opt/local/lib 正确地告诉 g++ 去查看/opt/local/lib,但你从来没有告诉它要找什么。至于寻找合适的header,可以使用-I/opt/local/include/opt/local/include放到编译器的include搜索路径中。

如果您听从我使用 CMake 的建议,这样做如下所示:

FIND_PACKAGE(需要 GD2) INCLUDE_DIRECTORIES($GD2_INCLUDE_DIRS) LINK_DIRECTORIES($GD2_LIBRARY_DIRS) ADD_EXECUTABLE(热图主Heatmap_Map Heatmap_Point) TARGET_LINK_LIBRARIES(热图 $GD2_LIBRARIES)

如果您有兴趣了解有关 CMake 的更多信息,您可能需要查看使用 CMake 构建系统的 C++ Application Project Template 和 C++ Library Project Template。 CMake 可通过 MacPorts 通过命令“sudo port install cmake”获得。

如果您对安装 CMake 不感兴趣,我还应该指出,您可能有兴趣了解一些环境变量以使您的生活更轻松,即:

CPATH LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH

CPATH 环境变量很像 PATH 环境变量(它是一个冒号分隔的目录列表),除了该变量中的目录将被 gcc 和 g++ 自动使用,就好像它们是在命令行中指定的一样-I 标志(即,将在这些路径中搜索标头)。 LIBRARY_PATH 是等价的,只是它好像文件夹是用-L 给出的(即,将自动在该路径中搜索库)。 DYLD_FALLBACK_LIBRARY_PATH 将被动态链接器使用(因此您可能应该将来自 LIBRARY_PATH 的路径包含到此变量中)。

您可以在链接中阅读有关environment variables affecting gcc 的更多信息。

【讨论】:

我最近一直在使用 JamPlus,非常喜欢它。【参考方案2】:

答案相当复杂。

简短的回答是,当您编译自己的库/工具时,将它们放置在某些 local 目录中,例如您在上面使用的或 /usr/local/lib/usr/local/include 甚至 ~/local/lib~/local/include 并始终将它们添加到你的编译器/链接器。

更长的答案 - 阅读适用于 Linux 的 Programming Library HOWTO,它解释了所涉及的每个工具从编译器/链接器到执行的所有内容,并查看标准的 directory structure of Linux system,它当然没有约束力,但很高兴知道。

我假设您对每个项目都有一个简单的 Makefile 设置,因此您不必费心输入所有这些命令。如果您不这样做,我强烈建议您设置一个简单的 Makefile 模板,您可以将其重用于您的项目。

编辑

在您编辑的答案中,您的路径可能不正确。

路径中的../libraries 指定当前目录,这意味着它将查看当前目录中的libraries 目录。如果您在根目录中添加了libraries 目录,则删除. 所以它应该是这样的-L/libraries/lib-I/libraries/... 类似

【讨论】:

@Michael 似乎他也从其他答案中学到了一些东西,所以其他答案可能并不像您想象的那样完全不相关。 @Michael,你知道了,但 stefanB 是对的,我也从其他答案中得到了更多。 ;-) @stefanB,是的,我把它放在我的项目目录中。 我很高兴我们都能够帮助你......这些点并不重要【参考方案3】:

头包含目录需要用 -I 选项指定(之后只需要相对路径),链接器包含目录用 -L (这里也是相对路径)。

对于库,您也可以设置 LD_LIBRARY_PATH 但 -L 方法更安全。

【讨论】:

@Sameer,他正确使用了 -L 标志,但忘记使用 -l 指定库。【参考方案4】:

我认为您的问题可能是您的 -I 参数也需要传递到编译阶段。也许是这样的?

dev: main.o
    g++ -L/opt/local/lib -lgd -lpng -lz -ljpeg -lfreetype -lm main.o -o heatmap

main.o: main.cpp
    g++ -I/opt/local/include -c main.cpp

不确定 - 我已经 20 年没有使用过 makefile(但正如我在另一篇文章的评论中提到的,我发现 JamPlus 的功能非常出色)。

无论如何——通常你的编译器和链接器标志将被放入变量中,然后在命令行中展开,但我不确定它的 make 语法。也许很简单:

CFLAGS=-I/opt/local/include
LINKFLAGS=-L/opt/local/lib -lgd -lpng -lz -ljpeg -lfreetype -lm 

dev: main.o
    g++ $(LINKFLAGS) main.o -o heatmap

main.o: main.cpp
    g++ $(CFLAGS) -c main.cpp

【讨论】:

@dash-tom-bang,仅供参考,CXXFLAGS 通常用于 C++ 设置,而 LDFLAGS 用于链接器标志。您应该使用预定义变量 $(CXX) 作为 C++ 编译器,而不是在 g++ 中硬编码。此外, main.o : main.cpp 是自动定义的。将 main.o 指定为依赖项足以让 Make 使用默认 C++ 编译器并使用 CXXFLAGS 中指定的任何设置自动编译 main.cpp。【参考方案5】:

使用#include "gd.h" 时需要使用-iquote,参见gcc directory options documentation。

另外,在链接阶段指定包含目录是没有意义的。

【讨论】:

以上是关于设置库包括 C++ 中的路径的主要内容,如果未能解决你的问题,请参考以下文章

通过编译器环境变量或 C 和 C++ 中的命令行标志指定库路径?

如何使用自动工具设置包含路径

Python中的交互库-os库

使用文件路径 c++ Linux OS 访问 Armadillo 库

线和多边形裁剪使用 Clipper 库 (c++) 返回空路径

对外部库的编译器依赖路径的组织