Auto-dependency Makefile 中的生成:对“main”的未定义引用(混合 conda 通道)
Auto-dependency generation in Makefile: undefined reference to `main' (mixing conda channels)
我想将依赖项添加到我的 Makefile
中,以便每次修改 header 时都会重新编译对应的翻译单元。目前只考虑对源文件的更改。我非常关注this example。
您可以在下面找到一个 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
(尽管应该使用 -include
以避免干净编译中的潜在问题,其中依赖项仍然不存在),但在 conda
我使用的环境。来自 default
和 conda-forge
频道的多个包正在混合。为了找到其中一些包并验证它们来自不同的 conda
渠道,我 运行:
conda list | grep gcc
conda list | grep compiler
解决问题:
conda upgrade -c conda-forge --all
从而确保所有使用的包都来自 conda-forge
渠道。
我这样做:
ifneq (,$(wildcard ${DEPDIR}/*}
include ${DEPDIR}/*
endif
并编译:
DEPFLAGS = -MT $@ -MMD -MP -MF ${DEPDIR}/$*.Td
我觉得你的方法会有问题。我不知道干净编译会发生什么,但你的 DEPFILES 还不存在。
我想将依赖项添加到我的 Makefile
中,以便每次修改 header 时都会重新编译对应的翻译单元。目前只考虑对源文件的更改。我非常关注this example。
您可以在下面找到一个 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
(尽管应该使用 -include
以避免干净编译中的潜在问题,其中依赖项仍然不存在),但在 conda
我使用的环境。来自 default
和 conda-forge
频道的多个包正在混合。为了找到其中一些包并验证它们来自不同的 conda
渠道,我 运行:
conda list | grep gcc
conda list | grep compiler
解决问题:
conda upgrade -c conda-forge --all
从而确保所有使用的包都来自 conda-forge
渠道。
我这样做:
ifneq (,$(wildcard ${DEPDIR}/*}
include ${DEPDIR}/*
endif
并编译:
DEPFLAGS = -MT $@ -MMD -MP -MF ${DEPDIR}/$*.Td
我觉得你的方法会有问题。我不知道干净编译会发生什么,但你的 DEPFILES 还不存在。