【发布时间】:2021-12-07 08:08:10
【问题描述】:
我无法显示任何代码,但让我解释一下发生了什么:
我正在尝试用 g++ 编译一些软件;我有我的 Makefile 设置。有一个主文件调用必要的函数来使该软件正常工作。我的所有依赖项都包括在内,即所有头文件、所有 .cpp 源等。
我的问题是,有几个文件需要我定义一个名为 OPTLEVEL 的命名空间,否则会出现 g++ 错误。
当我这样做时,例如:-DOPTELEVEL=GENERIC,这些文件将不再出错,因为我现在定义了 OPTLEVEL;但是,由于我定义了 OPTLEVEL,其他几个 .cpp 文件现在出错了。这是一个难题,我不知道该怎么办。
这是一个 Makefile 示例,说明了我如何分别编译源文件;如果我将它们与定义组合在一起,它会给我一个错误。这给了我未定义的引用,如下所述:
HEADERS_DEFINE_NEEDED = /Header/Needed/Path
HEADERS_NO_DEFINE = /Header/No/Define/Path
SOURCES_DEFINE_NEEDED = define1.cpp define2.cpp
SOURCES_NO_DEFINE = noDefine1.cpp noDefine2.cpp
DEFINITIONS = -DOPTLEVEL=GENERIC
all:
g++ -c -I$(HEADERS_DEFINE_NEEDED) $(DEFINITIONS) $(SOURCES_DEFINE_NEEDED)
g++ -c -I$(HEADERS_NO_DEFINE) $(SOURCES_NO_DEFINE)
g++ *.o -o out
我尝试将需要单独定义的 .cpp 文件编译到它们的目标文件中。然后我将不需要定义的 .cpp 文件编译到它们自己单独的目标文件中,但是将它们全部链接在一起会产生未定义的引用,这是可以理解的。
由于需要定义的文件现在的名称空间看起来像 GENERIC::FUNCTION_NAME 而没有定义的文件看起来像 OPTLEVEL:FUNCTION_NAME,因此未定义的引用特别出现.
我会接受任何建议。
如果这没有意义,请告诉我,我会尝试澄清。
谢谢!
编辑: 这是我正在查看的示例: 定义1.cpp
#ifndef OPTLEVEL
#error "Did not define OPTLEVEL
#endif
namespace OPTLEVEL {
class SampleClass : public InheritedClass {
<Code.....>
}
}
【问题讨论】:
-
我不是反对者,但宏没有命名空间(至少没有您可以显示的实际代码)。你做的事情太奇怪了,对我来说这是XY problem。通过在构建过程中定义的宏来更改命名空间名称的基本原理是什么?
-
这是我得到的软件,我正在尝试编译它并将其集成到我自己的软件中;在他们的源代码中,它们具有如下所示的标头保护:#ifndef #error "没有定义 OPTLEVEL #endif 然后在其他文件中它们具有相反的含义。我理解您所说的这是一个 XY 问题,我感谢您指出这一点。这比我希望的要复杂一些。
-
这里有一个问题要问大家:有没有办法在编译时为某些源文件定义,但为其他源文件取消定义?我知道你可以做 -DOPTLEVEL=GENERIC *.cpp -UOPTLEVEL,但是当我尝试这个时它不起作用。有什么建议?如果我能正常工作,它可能会解决我的问题。
-
当您花时间将问题提炼成一个简洁的问题时,StackOverflow 的效果最好。如果为了清晰起见需要代码,则包含最少的通用案例代码。说“我将无法显示任何代码”会减损并且无益。同样,“我会接受任何建议”表明您正在四处寻找其他人来解决您的问题,而不是提出有针对性的问题。最后,StackOverflow 不是一个论坛,所以在评论中添加一个新问题同样没有帮助——要么搜索该问题的答案,要么将其表述为一个新问题。写得很好的问题
-
肯定有一些特定的目的,代码的某些部分要求在编译时指定命名空间。我有一些猜测,但您应该阅读项目文档以获取相关信息。我强烈怀疑某些部分要求在外部定义宏(尽管不一定通过命令行参数),而其他部分要求不定义它是绝对故意的。我也认为,对于前一组来源,
-DOPTLEVEL=GENERIC可能是非常错误的,即使编译器接受它。
标签: c++ makefile g++ undefined-reference