2

我的项目是在 Linux 中使用 SDL 制作一个带有一些移动精灵的简单小屏幕,但我不想使用 IDE。我的目标是更好地了解 makefile 和所有这些业务;然而,我遇到了一堵我似乎无法逾越的墙。我希望有人可以解释为什么我的错误以及我可以做些什么来避免它!

因此,我的程序有多个依赖项,这些依赖项通过每个文件进行级联 - 因此,我在 makefile 中列出了所有需要的依赖项。这是我的代码...

OUT=program
CC=g++
SDL=-lSDLmain -lSDL -lSDL_image -lSDL_ttf

all: constants globals functions sprite sprite_test
    ${CC} sprite_driver.o sprite.o functions.o globals.o constants.h -o ${OUT} ${SDL}

constants:
    ${CC} -c constants.h

globals: constants
    ${CC} -c globals.cpp globals.h constants.h ${SDL}

functions: constants globals
    ${CC} -c functions.cpp globals.h globals.o constants.h ${SDL}

sprite: constants globals functions
    ${CC} -c sprite.cpp functions.o globals.o constants.h ${SDL}

sprite_test: constants globals functions sprite
    ${CC} -c sprite_driver.cpp sprite.o functions.o globals.o constants.h ${SDL}

当编译器到达函数时,它说 globals.o 没有正确链接。该文件中有许多在编译后无法识别的外部声明,因此看起来有多个相同变量的声明。这是控制台吐出的内容。

g++ -c constants.h
g++ -c globals.cpp globals.h constants.h -lSDLmain -lSDL -lSDL_image -lSDL_ttf
g++ -c functions.cpp globals.h globals.o constants.h -lSDLmain -lSDL -lSDL_image -lSDL_ttf
g++: warning: globals.o: linker input file unused because linking not done
g++ -c sprite.cpp functions.o globals.o constants.h -lSDLmain -lSDL -lSDL_image -lSDL_ttf
g++: warning: functions.o: linker input file unused because linking not done
g++: warning: globals.o: linker input file unused because linking not done
g++ -c sprite_driver.cpp sprite.o functions.o globals.o constants.h -lSDLmain -lSDL -lSDL_image -lSDL_ttf
g++: warning: sprite.o: linker input file unused because linking not done
g++: warning: functions.o: linker input file unused because linking not done
g++: warning: globals.o: linker input file unused because linking not done
g++ sprite_driver.o sprite.o functions.o globals.o constants.h -o program -lSDLmain -lSDL -lSDL_image -lSDL_ttf
sprite.o:(.bss+0x0): multiple definition of `screen'
sprite_driver.o:(.bss+0x0): first defined here
sprite.o:(.bss+0x4): multiple definition of `event'
sprite_driver.o:(.bss+0x4): first defined here
sprite.o:(.bss+0x18): multiple definition of `keystate'
sprite_driver.o:(.bss+0x18): first defined here
sprite.o:(.bss+0x1c): multiple definition of `font'
sprite_driver.o:(.bss+0x1c): first defined here
sprite.o:(.bss+0x20): multiple definition of `t_black'
sprite_driver.o:(.bss+0x20): first defined here
functions.o:(.bss+0x0): multiple definition of `screen'
sprite_driver.o:(.bss+0x0): first defined here
functions.o:(.bss+0x4): multiple definition of `event'
sprite_driver.o:(.bss+0x4): first defined here
functions.o:(.bss+0x18): multiple definition of `keystate'
sprite_driver.o:(.bss+0x18): first defined here
functions.o:(.bss+0x1c): multiple definition of `font'
sprite_driver.o:(.bss+0x1c): first defined here
functions.o:(.bss+0x20): multiple definition of `t_black'
sprite_driver.o:(.bss+0x20): first defined here
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
4

1 回答 1

3

你在这里有很多错误,我认为你可能需要获取一些介绍性材料并仔细阅读它们。SO 并不是从头开始学习这些工具的正确地方:有很多资源可供使用。

一些东西:

  • 您不编译.h(头)文件。
  • .c编译(源)文件时,不要在编译或链接命令行上列出头文件。
  • 当您将源文件编译为目标文件时,您不会.o在编译命令行上列出(目标)文件。您只需将目标文件放在链接命令行上。
  • 当您将源文件编译为目标文件时,您不会-l...在编译命令行上列出(库)文件。您只需将库文件放在链接命令行上。
  • 您的 makefile 规则必须使用您尝试创建的实际文件作为目标,而不仅仅是您选择的单词。
  • 按照长期惯例,CCmakefile 中的变量代表 C 编译器。您正在尝试编译 C++ 源代码,因此您应该使用该CXX变量。

make 程序有很多关于如何构建各种文件的内置规则,其中一个描述了如何从.cpp(C++ 源)文件构建目标文件。利用这一点,您可以非常简单地将您的 makefile 编写为:

OUT = program
CXX = g++
SDL = -lSDLmain -lSDL -lSDL_image -lSDL_ttf

OBJECTS = sprite_driver.o sprite.o functions.o globals.o

all: $(OUT)
$(OUT): $(OBJECTS)
        $(CXX) -o $@ $^ ${SDL}

$(OBJECTS): constants.h
于 2013-07-08T05:07:39.317 回答