Makefile 中的自动依赖关系生成:对“main”的未定义引用(混合 conda 通道)

Auto-dependency generation in Makefile: undefined reference to `main' (mixing conda channels)

提问人:unvarnished 提问时间:7/15/2021 最后编辑:unvarnished 更新时间:7/15/2021 访问量:117

问:

我想将依赖项添加到我的一个中,以便每次修改标题时,都会重新编译相应的翻译单元。目前只考虑对源文件的更改。我非常密切地遵循了这个例子Makefile

您可以在下面找到一个 MWE,它输出 .一旦从编译步骤中删除变量,代码就会成功编译。undefined reference to `main'DEPFILES

Makefile:

CC = g++
EXEC = v1_beam.exe
RM = rm -f

BASEDIR := $(shell pwd)
SRCDIR  := src
INCDIR  := include
DEPDIR  := .deps

DEPFLAGS = -M -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d
DEBUG_LEVEL := -g -fdiagnostics-color=always
EXTRA_CCFLAGS := -Wall -std=c++17 -O -pedantic -pedantic-errors
CXXFLAGS        = $(DEBUG_LEVEL) $(EXTRA_CCFLAGS)
CCFLAGS         = $(CXXFLAGS)

SRCS := $(wildcard *.cc) \
    $(wildcard $(SRCDIR)/*.cc)

OBJS := $(patsubst %.cc, %.o, $(SRCS))

DEPFILES := $(patsubst %.cc, $(DEPDIR)/%.d, $(notdir $(SRCS)))

.PHONY: all clean
.DEFAULT_GOAL = all

all: $(DEPDIR) $(EXEC)

$(EXEC): $(OBJS)
    @echo 3
    @echo Dependencies: $(wildcard $(DEPFILES))
    $(CC) $(CCFLAGS) $^ -o $@
    @echo Executable $(EXEC) created.

%.o: %.cc
%.o: %.cc Makefile
    @echo 1 
    $(CC) $(DEPFLAGS) $(CCFLAGS) -c $< -I$(BASEDIR) -o $@

$(SRCDIR)/%.o: $(SRCDIR)/%.cc $(DEPDIR)/%.d | $(DEPDIR)
    @echo 2
    $(CC) $(DEPFLAGS) $(CCFLAGS) -c $< -I$(BASEDIR) -o $@

$(DEPDIR):
    mkdir -p $@

$(DEPFILES):

clean:
    $(RM) $(OBJS) $(EXEC)

include $(wildcard $(DEPFILES))

main.cc:

#include <iostream>
#include "include/dummy.h"

int main() {
  MyClass obj;
  obj.print();
  return 0;
}

include/dummy.h:

#ifndef DUMMY
#define DUMMY

#include <iostream>

class MyClass {
  MyClass() { std::cout << "constructor" << std::endl; }
  void print();
};

#endif 

src/dummy.cc:

#include "include/dummy.h"

void MyClass::print()  {
  std::cout << "print" << std::endl;
}

编辑:

问题似乎不在于(尽管应该使用以避免干净编译中的潜在问题,其中依赖项仍然不存在),而在于我正在使用的环境。来自 和 通道的多个包正在混合。要找到其中一些包并验证它们来自不同的渠道,我运行:Makefile-includecondadefaultconda-forgeconda

conda list | grep gcc
conda list | grep compiler

要解决此问题,请执行以下操作:

conda upgrade -c conda-forge --all

从而确保所有正在使用的包都来自通道。conda-forge

C++ 生成文件 未定义引用 conda-forge

评论


答:

1赞 Joseph Larson 7/15/2021 #1

我这样做:

ifneq (,$(wildcard ${DEPDIR}/*}
include ${DEPDIR}/*
endif

并使用以下命令进行编译:

DEPFLAGS = -MT $@ -MMD -MP -MF ${DEPDIR}/$*.Td

我认为你的方法会有问题。我不知道干净编译会发生什么,但您的 DEPFILES 还不存在。

评论

2赞 HolyBlackCat 7/15/2021
要执行可选的包含,您可以简单地使用 .-include
0赞 unvarnished 7/15/2021
@HolyBlackCat 谢谢你的提示。事实证明,这基本上是正确的,导致问题的是我正在使用的安装。具体来说,一些包来自通道,而其他包则使用 .很抱歉没有在原始问题中指定这一点,因为我没有怀疑这可能是问题所在(而且我仍然缺少为什么这与 中的依赖项有关)。我会将答案标记为正确并更新原始问题。谢谢。Makefileconda*cxx*default*gcc*conda-forgeMakefile