使用 MingW 和 makefile 时如何 link 针对库

How to link against libraries when using MingW and makefiles

我使用 MingW 和 cmake 下载并构建了 FLTK (v. 1.3.4.1),效果非常好。 但是,我在正确链接 FLTK 时遇到问题,导致链接期间出现大量未定义的引用。 我没有为 Windows 安装 MSYS 或任何其他 shell,这意味着不能使用 'fltk-config' 脚本。

我对 makefile 的了解很少,以下是使用官方文档和各种 Internet 资源构建的。

CC=g++
FLTK_INC=C:/frameworks/fltk-1.3.4-1
FLTK_BIN=C:/frameworks/fltk-1.3.4-1/bin
CFLAGS=-std=c++11 -Wall -I$(FLTK_INC) -v
LDFLAGS=-L$(FLTK_BIN)/lib
LDLIBS=-lfltk
EXT=cc
SOURCES=$(wildcard src/*.$(EXT))
OBJECTS=$(SOURCES:.$(EXT)=.o)
EXECUTABLE=hello

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.$(EXT).o:
    $(CC) $(CFLAGS) $< -o $@

这个 makefile 是否有明显的错误,或者错误出在其他地方?

Is there something obviously wrong with this makefile or does the error lie somwehere else?

这个 makefile 有两处错误。

事情 1

LDFLAGS=-L$(FLTK_BIN)/lib
LDLIBS=-lfltk

您有 linkage 选项的常规 GNU Make 设置:

LDFLAGS=-L$(FLTK_BIN)/lib

$(LDFLAGS) 应该出现在您 link 年龄的适当位置 告诉 linker 它应该在目录中搜索的方法 $(FLTK_BIN)/lib 对于使用 -l 选项指定的任何库(之前 在其默认目录中搜索)。

LDLIBS=-lfltk

$(LDLIBS) 应该出现在您 link 年龄的适当位置 告诉 linker 它应该 link 共享库 libfltk.so 的方法 否则,静态库 libfltk.a。 (在 Windows,其他分机 被接受)。

你的link年龄秘诀:

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

在适当的位置有$(LDFLAGS)但没有$(LDLIBS) 任何地方。因此 linker 不会尝试 link libfltk。 这很可能解释了您提到的未定义参考错误, 虽然我不能完全确定,因为你还没有透露它们是什么。

link年龄配方应该是:

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LDLIBS)

或更常规:

$(EXECUTABLE): $(OBJECTS)
    $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS)

事情 2

你的编译方法:

.$(EXT).o:
    $(CC) $(CFLAGS) $< -o $@

实际上不是编译配方。这是一个 compile-and-link 食谱。 gcc/g++ 将始终尝试执行 linkage 除非命令行选项 包括 -c(= 仅编译)。由于食谱(正确地)不包括 任何必要的 link 年龄选项 - $(LDFLAGS)$(LDLIBS) - 过早的尝试 linkage 失败并且构建没有进一步进行。这 您记录为产生 linkage 错误的命令行:

g++ -std=c++14 -Wall -IC:/frameworks/fltk-1.3.4-1 -v src/hw.cc -o src/hw.o

是您的"compile"食谱的替代实例:

$(CC) $(CFLAGS) $< -o $@

而不是你的link年龄食谱:

$(CC) $(LDFLAGS) $(OBJECTS) -o $@

要更正编译配方,请将其设为:

$(CC) $(CFLAGS) $< -c -o $@

The GNU Make documentation 很好