C++ 和 Gtkmm 的 Makefile 问题

Makefile Issues with C++ & Gtkmm

我熟悉 Gtkmm 和 C++,但对 Makefile 不熟悉,并且在让我的文件实际生成可执行文件时遇到问题。我知道一个完整的 Makefile 对于我的项目当前的简单性来说是过分的,但我正在尝试将一个基本模板放在一起以用于更大的项目。我在 Ubuntu 17.10 和 运行 我的 "build" 文件夹中的 make 命令。任何帮助将不胜感激!

终端输出

pearscol@UBUNTU-1710:~/projects/testprogram/build$ make
g++ -o testprogram  `pkg-config --libs gtkmm-3.0`
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In 
function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:19: recipe for target 'testprogram' failed
make: *** [testprogram] Error 1

源文件结构

 - /build
    - /build/Makefile
 - /src
    - /src/main.cpp

/build/Makefile

CXX = g++
CXXFLAGS = `pkg-config gtkmm-3.0 --cflags` -std=c++14 -g -Wall
INCLUDES = -I../include
SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)
PROGRAM = testprogram
DEPDIR = ../src/
LIBS = `pkg-config --libs gtkmm-3.0`

all: $(PROGRAM)

-include $(OBJS:%.o=$(DEPDIR)/%.Po)

%.o: %.cpp
    $(CXX) -MT $@ -MD -MP -MF $*.Tpo -c -o $@ $(CXXFLAGS) $<

$(PROGRAM): $(OBJS)
    $(CXX) -o $(PROGRAM) $(OBJS) $(LIBS)

# DO NOT DELETE THIS LINE -- make depend needs it

/src/main.cpp

#include <gtkmm.h>

int main(int argc, char *argv[]) {
    Glib::RefPtr<Gtk::Application> app =
      Gtk::Application::create(argc, argv, "testprogram");
    Gtk::Window window;
    window.set_default_size(400, 200);
    window.set_title("Tutorial");
    return app->run(window);
}

据我所知,

$(CXX) -o $(PROGRAM) $(OBJS) $(LIBS)

结果

g++ -o testprogram  `pkg-config --libs gtkmm-3.0`

因为 $(OBJS) 是空的,因为 $(SRCS) 是空的,因为 *.cpp 没有文件匹配,因为你的 build 目录不包含 .cpp 文件。

如果您想使用 $(wildcard ...) 函数指定源文件, 然后替换:

SRCS = $(wildcard *.cpp)

与:

SRCS = $(wildcard src/*.cpp)

因为 src*.cpp 文件所在的位置,相对于构建目录。

要将目标文件放在构建目录中,然后替换:

OBJS = $(SRCS:.cpp=.o)

与:

$(notdir $(SRCS:.cpp=.o))

最后执行以下操作之一:

要么替换模式规则:

%.o: %.cpp

与:

%.o: src/%.cpp

或者,保持模式规则不变并添加:

VPATH := src

到您的 makefile 顶部的变量设置。看 VPATH.

旁白

你的默认目标 all 是一个 phony 目标:你永远不会 一个名为 all 的文件,并且您假设这样的文件永远不存在。最好将其指定为 .PHONY 目标。

对于 defining variables,使用简单的扩展 - VAR := val - 而不是 递归扩展 - VAR = val - 除非需要递归扩展,它不在你的 makefile 中。

您的 makefile 缺少 clean 目标 删除所有制作产品并将构建目录恢复到原始状态 状态。提供这个假目标是标准的。