【发布时间】:2014-05-27 07:05:49
【问题描述】:
我有一个 makefile,它应该将大量源文件编译成单独的目标文件,然后将它们链接到共享库中。
源文件列表存储在变量 SOURCES 中。在编译目标文件的 $(OBJECTS) 目标期间,make 运行命令 $(CC) $(CFLAGS) -c $
这使得命令对每个目标文件使用相同的源文件,给我一堆由 Time.cpp 制作的目标文件,并导致链接器给我一堆已经在每个其他对象中定义的函数错误文件。我怎样才能让这个 makefile 工作?
# Variable setup
# BUILD - Either Debug or Release, specify when running make
# ARCH - Either 32 or 64, specify when running make
# CC - The compiler
# INC - The include directories
# CFLAGS - Compiler flags to use
# LDFLAGS - Linker flags to use
# OBJDIR - Directory for .o files
# BINARY - Output file path
# SOURCES - Path to each individual source file
# OBJECTS - Object files
ifeq ($(and $(ARCH),$(BUILD)),)
$(error You have either not defined an architecture or build or both, please run "make BUILD=(DEBUG/RELEASE) ARCH=(32/64)")
endif
CC = g++
INC = -I../../include -I../../extlibs/headers -I../../extlibs/headers/libfreetype/linux
LDFLAGS = -lX11 -lGL -lGLEW -lfreetype -ljpeg -lopenal -lsndfile
CFLAGS = $(INC) -std=c++0x -fPIC -pthread -m$(ARCH)
OBJDIR = ./obj/$(BUILD)/$(ARCH)-bit
BINPATH = ./bin/$(BUILD)/$(ARCH)-bit
BINARY = $(BINPATH)/libTyrant$(ARCH).so
SRCPATH = ../../src/
SOURCES = System/Time.cpp System/Mutex.cpp System/Log.cpp System/Clock.cpp System/Sleep.cpp System/Unix/ClockImpl.cpp System/Unix/MutexImpl.cpp System/Unix/SleepImpl.cpp System/Unix/ThreadImpl.cpp System/Unix/ThreadLocalImpl.cpp System/Lock.cpp System/String.cpp System/ThreadLocal.cpp System/Thread.cpp Audio/SoundRecorder.cpp Audio/SoundBuffer.cpp Audio/SoundSource.cpp Audio/AudioDevice.cpp Audio/ALCheck.cpp Audio/Sound.cpp Audio/Music.cpp Audio/SoundFile.cpp Audio/SoundStream.cpp Audio/SoundBufferRecorder.cpp Audio/Listener.cpp Graphics/RectangleShape.cpp Graphics/VertexArray.cpp Graphics/Shader.cpp Graphics/ConvexShape.cpp Graphics/ImageLoader.cpp Graphics/Sprite.cpp Graphics/RenderTexture.cpp Graphics/BlendMode.cpp Graphics/Shape.cpp Graphics/CircleShape.cpp Graphics/TextureSaver.cpp Graphics/Vertex.cpp Graphics/RenderTextureImpl.cpp Graphics/Texture.cpp Graphics/Text.cpp Graphics/GLExtensions.cpp Graphics/Image.cpp Graphics/RenderTextureImplFBO.cpp Graphics/GLCheck.cpp Graphics/RenderTextureImplDefault.cpp Graphics/Color.cpp Graphics/Transformable.cpp Graphics/RenderTarget.cpp Graphics/Transform.cpp Graphics/View.cpp Graphics/RenderStates.cpp Graphics/RenderWindow.cpp Graphics/Font.cpp Window/JoystickManager.cpp Window/Joystick.cpp Window/Window.cpp Window/Keyboard.cpp Window/GlResource.cpp Window/Unix/JoystickImpl.cpp Window/Unix/WindowImplX11.cpp Window/Unix/GlxContext.cpp Window/Unix/Display.cpp Window/Unix/VideoModeImpl.cpp Window/Unix/InputImpl.cpp Window/VideoMode.cpp Window/Mouse.cpp Window/GlContext.cpp Window/Context.cpp Window/WindowImpl.cpp Network/Ftp.cpp Network/TcpListener.cpp Network/Packet.cpp Network/IpAddress.cpp Network/TcpSocket.cpp Network/Socket.cpp Network/Unix/SocketImpl.cpp Network/UdpSocket.cpp Network/SocketSelector.cpp Network/Http.cpp
OBJECTS = $(addprefix $(OBJDIR)/,$(SOURCES:.cpp=.o))
ifeq ($(BUILD),DEBUG)
CFLAGS := $(CFLAGS) -g -pg -Og
endif
ifeq ($(BUILD),RELEASE)
CFLAGS := $(CFLAGS) -s -O3
endif
all: clean $(addprefix $(SRCPATH),$(SOURCES)) $(BINARY)
$(BINARY): $(OBJECTS) $(BINPATH)
$(CC) $(LDFLAGS) $(OBJECTS) -shared -o $@
$(OBJECTS): $(addprefix $(SRCPATH),$(SOURCES)) $(OBJDIR)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR):
mkdir ./obj
mkdir ./obj/$(BUILD)
mkdir $@
mkdir $@/Audio
mkdir $@/Graphics
mkdir $@/Network
mkdir $@/Network/Unix
mkdir $@/System
mkdir $@/System/Unix
mkdir $@/Window
mkdir $@/Window/Unix
$(BINPATH):
mkdir ./bin
mkdir ./bin/$(BUILD)
mkdir $@
clean:
rm -rf bin
rm -rf obj
【问题讨论】:
-
我觉得根据你的条件改变你的目标是更好的做法——这样每个目标都有一个无条件的方式来构建自己。此外,正如 Beta 所说,
make不太擅长跨目录处理 - 通常的做法是将构建步骤的所有源和目标放在同一个目录中,并有一个单独的install步骤来拉结果一起进入最终目的地。因此,这些mkdir命令不是执行此操作的习惯方式——相反,通常会在不同的子目录中创建针对不同架构的构建。