【问题标题】:GCC and linking environment variables and flagsGCC 和链接环境变量和标志
【发布时间】:2013-04-09 06:28:30
【问题描述】:

GCC官方文档中的以下链接:

http://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html

解释以下环境变量:

LANG
LC_CTYPE
LC_MESSAGES
LC_ALL
TMPDIR
GCC_COMPARE_DEBUG
GCC_EXEC_PREFIX
COMPILER_PATH
LIBRARY_PATH
CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
OBJC_INCLUDE_PATH
DEPENDENCIES_OUTPUT
SUNPRO_DEPENDENCIES

但我之前也听说过/读过这些其他编译标志:

  • 用于编译 C 代码:CC, CFLAGS
  • 用于编译 C++ 代码:CXXCPPFLAGS

以及链接标志:

  • 链接阶段:LDFLAGS
  • 代码编译后:LD_LIBRARY_PATH

CCCFLAGSCXXCPPFLAGS 是什么意思?为什么它们没有包含在gcc官方环境变量列表中?

【问题讨论】:

  • 它们与 GCC 无关。它们只是 Unix 上的一种约定,因此在 Unix 系列中得到了开箱即用的支持。我猜它们成为了一种约定,因为按照约定,普通的 makefile 往往依赖于这些变量。许多构建系统(例如 Autotools)也采用了这种约定,并使用相似的变量来表示相同的事物。老实说,这些标志完全是一堆废话(可能除了LD_LIBRARY_PATH),每次遇到它们时,我都会想起60年代。如果您使用的是现代构建(您应该是)系统,您可以忘记它们。
  • LD_LIBRARY_PATH 用于指出共享库所在的目录,以便依赖这些共享库的应用程序可以正确地(动态地)链接到它们。正如您再次看到的,这与软件开发和 GCC 无关,而只是 Unix 系列如何处理动态链接、软件组件的安装路径及其执行的一个特性/概念。如果您对这些 cmets 感到满意,我可以将它们制定为答案。随时问更多。
  • 是的@Haroogan。欢迎您将其制定为答案,因为这已经提供了很多信息。不确定我是否会接受任何东西,因为我想给线程一些时间来收集答案。

标签: gcc build linker environment-variables


【解决方案1】:

首先,您提到的所有变量:CCCFLAGSCXXCXXFLAGSLDFLAGSLD_LIBRARY_PATH,都源自 Unix OS 家族。这些变量首先与 GCC 无关,这就是为什么您在手册中看不到它们的踪迹。

其中唯一有意义的变量(也与 GCC 没有直接联系)是LD_LIBRARY_PATH。您可能会发现这个变量在任何现代类 Unix 操作系统上都是开箱即用的。这是 Linux Programmer's Manual 中的LD.SO(8) 手册页,其中提到了LD_LIBRARY_PATH 及其用途。这里还有一段摘录:

LD_LIBRARY_PATH 环境变量包含一个以冒号分隔的目录列表,dynamic linker 在查找要加载的共享库时搜索这些目录。

目录按照提及的顺序进行搜索。

如果未指定,则链接器使用默认值,即/lib:/usr/lib:/usr/local/lib

如您所见,LD_LIBRARY_PATH 只是一个特定于操作系统的环境变量,用于正确加载共享库。 Windows 在这方面有类似的环境变量:PATH。 Windows 在搜索dynamic-link library(DLL,Linux 上 SO 的对应物)时也会扫描其中列出的目录。

关于其余变量(CCCFLAGSCXXCXXFLAGSLDFLAGS),由于历史原因,您经常看到它们。自 Unix 时代兴起以来,软件项目都是使用 Make 构建的(向下滚动并查看典型的 makefiles 示例)——这是开创性的构建工具之一。这些变量在makefiles 中被广泛使用,最终它们成为一种约定(例如,参见Implicit Rules)。这就是为什么您甚至可以看到它们在例如 Linux 上开箱即用地定义,并且很可能指向 GCC(因为它被认为是 Linux 的本机工具链)。

总之,重点是:不要对CCCFLAGSCXXCXXFLAGSLDFLAGS 和朋友们刮目相看,因为他们只是来自过去;)

奖金


如今,直接使用普通的旧 Make 来构建复杂的软件很快就会变得乏味且容易出错。结果,开发了许多复杂的构建系统生成器,例如 GNU AutomakeCMake。简而言之,他们的目标是提供(可以说)更易读、更易于维护和高级语法来为要构建的任意软件项目定义任意复杂的构建系统。通常,在实际构建项目之前,必须从这个高级定义使用了相应的工具集。最后,必须使用与生成的(本机)构建系统相对应的工具来构建项目(例如,在普通的旧 makefiles 的情况下使用 Make,但不一定)。

既然您提出了这些问题,我怀疑您即将开始使用 C 或 C++ 进行本机软件开发。如果是这样,我强烈建议您首先选择一个现代构建系统(CMake 是我个人的建议),使用它并好好学习它。

【讨论】:

  • 这是一个很棒的答案。谢谢@Haroogan。您对现代构建系统的回答中也有很多很棒的东西。我不敢相信它被删除了(即使我熟悉该政策)。再次感谢。这正是我要找的。​​span>
  • 不客气。我知道对于本地编程领域的初学者来说,一次性掌握所有这些是多么困难(或者说是不可能),因为周围发生的事情太多了:编译、链接、构建系统、新语言标准、旧语言标准、平台、∞... 从一开始就走错路是多么容易。不幸的是,很难找到有用和最新的材料来阅读。唯一的方法是在这里寻求一些关于 SO 的指导。祝你未来的努力好运,无论它们是什么。
  • 哇,我认为您在现代构建系统上的出色回答现在已经丢失了。看起来它不再可以从 Google 缓存中获得,也不能在 stackprinter.com... 如果我们在其他任何地方找到它,我们应该将文本添加到这个答案中。
  • 噢,这确实很不幸。无论如何,我以后可能会写一个更好的教程,并充分扩展这个主题,提供真实世界的例子。这些天我有点忙,但总有一天我会这样做的。当然,我会在这里发布一个链接。
  • 顺便说一下,很高兴看到其中一些解决方案如何与“最近”推出的(2012 年 11 月)GNU GUIX 集成:gnu.org/software/guix(很高兴了解您的关于 GNU GUIX 采取的任何方法的想法)
【解决方案2】:

简单来说,CCCFLAGSLDFLAGS 等都是 gnu Makefile 变量。如果定义,这些将被隐式规则使用,即使在命令/规则中没有实际提及

【讨论】:

  • 在您的回答中,不清楚您所说的“这些将被隐式规则使用”是什么意思 - 人们可能认为这些是 GCC 的一些隐式规则。因此,您可能想要添加 of Make 的隐式规则。意识到这一点很重要,因为如果一个人指定了他自己的规则 .c.o: 那么 CFLAGS 的值就不会被使用。如果它们是 GCC 的规则,它们就会被使用。
【解决方案3】:

您绝对可以将环境变量与 GCC 一起用于 CFLAGS 和 CC(以及其他任何东西)。您只需将变量传递到编译行,根据操作系统略有不同。

Linux 设置 CFLAGS 环境变量:

export CFLAGS="-g -Wall -std=c89 -pedantic"

使用 CFLAGS 在 Linux 上编译

gcc $CFLAGS - o progname progname.c

Windows 设置 CFLAGS 环境变量:

set CFLAGS=-g -Wall -std=c89 -pedantic

使用 CFLAGS 在 Windows 上编译

gcc %CFLAGS% - o progname progname.c

您甚至可以在变量中设置一个临时编译字符串,并在测试时调用它进行编译。

set BUILD=gcc -g -Wall -std=c89 -pedantic - o progname progname.c

并称它为...

%BUILD%

在 Linux 上设置和使用变量时要记住一件事(正如大多数程序员所知道的),变量区分大小写,因此 $cflags 将被忽略。在 Windows 上无关紧要。

在这两个系统上,上述内容仅在终端(或命令提示符)会话终止之前有效。要使它们永久化,您需要在它们各自的设置文件中设置变量。

【讨论】:

    猜你喜欢
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    • 2014-07-03
    • 2012-02-13
    • 2016-04-30
    • 2014-04-22
    相关资源
    最近更新 更多