【问题标题】:Trouble compiling/linking C and C++ files编译/链接 C 和 C++ 文件时遇到问题
【发布时间】:2014-12-04 17:00:21
【问题描述】:

我尝试在 SO 上搜索其他问题,但仍然无法将我新创建的 C++ 和 .h 正确链接到我的主 C 文件。我的loader.cpploader.h 的实现基于this SO question

我的 loader.cpp 没有 main 函数,因为我只想在那里使用 C++ 函数。我的shift.c 文件是我的int main() 所在的位置。这是我的loader.cpp 文件的基本结构。

loader.cpp

#include "loader.h"
...
// Class Declaration
...
// Class implementation

我一直在尝试使用以下内容进行编译。

g++ loader.cpp -o obj -lGLU -lGL -lglut

我在这里遇到的错误是......

(.text+0x20): undefined reference `to main'

所以我的两个问题是,如何让我的 cpp 文件正确编译,然后我需要添加什么到我的 Makefile 才能正确链接它们?

Makefile(供参考)

CC = gcc
CXX = g++

EXE = shift gears

# Main target
all: $(EXE)

CFLG=-O3 -Wall
LIBS=-lglut -lGLU -lGL -lm

CLEAN=rm -f $(EXE) *.o *.a


# Dependencies
gears.o: gears.c
shift.o: shift.c CSCIx229.h
fatal.o: fatal.c CSCIx229.h
loadtexbmp.o: loadtexbmp.c CSCIx229.h
print.o: print.c CSCIx229.h
project.o: project.c CSCIx229.h
errcheck.o: errcheck.c CSCIx229.h
object.o: object.c CSCIx229.h

#  Create archive
CSCIx229.a:fatal.o loadtexbmp.o print.o project.o errcheck.o object.o
    ar -rcs $@ $^

# Compile rules
.c.o:
    gcc -c $(CFLG) $<
.cpp.o:
    g++ -c $(CFLG) $<

#  Link
shift:shift.o CSCIx229.a
    gcc -O3 -o $@ $^   $(LIBS)

gears:gears.o
    gcc -O3 -o $@ $^   $(LIBS)

#  Clean
clean:
    $(CLEAN)

【问题讨论】:

  • 哪个文件包含您的main 函数?该错误是因为您试图创建一个没有main 的可执行文件。
  • 我的c文件,名为shift.c
  • 您需要将shift.o 文件添加到链接器命令行。
  • 您在 makefile 中的 .cpp.o 规则有您缺少的关键位。你写的那条g++ 不是手工写的吗? make loader.o 现在可以使用吗?
  • @ThomasMatthews 我不相信 OP 正在尝试在那里创建 exe。我相信他们正在尝试创建loader.o(尽管我不确定为什么将其称为obj)。

标签: c++ c makefile linker


【解决方案1】:

如果您希望g++ 编译一个对象模块而不将其链接到一个完整的程序中,那么您必须给它-c 选项:

g++ -c loader.cpp -o loader.o

请注意,该编译命令还为生成的目标文件分配了一个常规名称,并且如果您没有将其链接到可执行文件中,那么您无需指定将其链接到的库。您的 Makefile 已为此设置。

如果您将loader.o 添加到CSCIx229.a 的依赖项中,那么这足以说服makeloader.cpp 构建它并将目标文件包含在您的库中(这将使其可用于链接到您的可执行文件中)。您可能还需要将部分或全部 -lGLU -lGL -lglut 添加到您的 LIBS 变量中。如果loader.o 的依赖项不仅仅包含loader.cpp 本身(例如,如果它们包含CSCIx229.h),那么将loader.o 的依赖项添加到makefile 中也是合适的。

【讨论】:

  • 对。这里的 tl;dr 版本是“对待 loader.o 的方式就像对待你在该库中使用的其他 .o 文件一样,它应该可以正常工作”。
【解决方案2】:

添加 -c 选项以仅编译。当您准备好链接最终应用程序时,请包含所有目标文件和库列表。

g++ -c loader.cpp -o loader.o
g++ loader.o (and the rest of your object files)  -lGLU -lGL -lglut

尝试将其添加到您的 makefile 中:

shift:shift.o CSCIx229.a loader.o
    gcc -O3 -o $@ $^   $(LIBS)

【讨论】:

    猜你喜欢
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2015-10-10
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2016-05-04
    相关资源
    最近更新 更多