Android makefile 链接两次

Android makefile links twice

本文关键字:两次 makefile 链接 Android      更新时间:2023-10-16

我已经在 SDL 中为我的游戏设置了一个生成文件。SDL 中包含的 Application.mk 文件的模板具有三种体系结构:

APP_ABI := armeabi armeabi-v7a x86

对于armeabi来说,一切都编译得很好,但对于armeabi-v7a来说,它失败了。对我来说,看起来编译完成,但链接器两次拥有两个特定文件夹的所有obj文件。虽然这不会发生在armeabi.链接器(ld(给了我这样的错误:

/path/to/bin/ld: error: /path/to/myObjFile.obj: multiple definition of 'foo(int, int)'
/path/to/bin/ld: /path/to/myObjFile.obj: previous definition here

路径完全相同,因此这让我假设链接器使用每个文件两次。此处是此类错误的完整示例:

/Users/martijncourteaux/Development/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: /Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Box2D/Collision/b2Distance.o: multiple definition of 'b2Distance(b2DistanceOutput*, b2SimplexCache*, b2DistanceInput const*)'
/Users/martijncourteaux/Development/android-ndk-r10c/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: /Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Box2D/Collision/b2Distance.o: previous definition here

但是,当我启动 ndk-build 时,链接双精度的对象文件也会生成此警告:

/Users/martijncourteaux/Development/android-ndk-r10c/build/core/build-binary.mk:449: warning: ignoring old commands for target `/Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Collision/b2Distance.o'
/Users/martijncourteaux/Development/android-ndk-r10c/build/core/build-binary.mk:449: warning: overriding commands for target `/Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/obj/local/armeabi-v7a/objs/main//Volumes/Stuff/Projects/GameDev/Gump/GumpAndroid/jni/src/__/ThirdParty/Collision/b2Distance.o'

请注意,我的印象是,所有这些obj具有这些multiple definition错误生成的文件也会生成此警告。

这是我的Application.mk

APP_STL := gnustl_static
APP_ABI := armeabi armeabi-v7a x86
NDK_TOOLCHAIN_VERSION := clang
APP_CPPFLAGS += -std=c++11
APP_PLATFORM := android-10

这是我的Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := main
SDL_PATH := ../SDL
THIRD_PARTY_FOLDER := $(LOCAL_PATH)/../ThirdParty
LOCAL_CPPFLAGS += -frtti
LOCAL_CPPFLAGS += -fexceptions
LOCAL_CPPFLAGS += -funwind-tables
PCH_FILE := $(LOCAL_PATH)/Gump/Gump-Prefix.pch
#PCH_FILE := Gump/Gump-Prefix.pch
LOCAL_CPPFLAGS += -include $(PCH_FILE) 
#LOCAL_PCH := $(PCH_FILE)
#LOCAL_CPPFLAGS += -DPCH
LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include 
                    $(LOCAL_PATH)/$(SDL_PATH)_mixer/ 
                    $(LOCAL_PATH)/$(SDL_PATH)_image/ 
                    $(LOCAL_PATH)/$(SDL_PATH)_net/ 
                    $(LOCAL_PATH)/../ThirdParty/ 
                    $(LOCAL_PATH)/Gump/
# Add your application source files here...
GUMP_SRC_FILES := $(wildcard $(LOCAL_PATH)/Gump/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/tinyxml2/tinyxml2.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/Box2D/*/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/Box2D/*/*/*.cpp)
THIRD_PARTY_SRC_FILES += $(wildcard $(THIRD_PARTY_FOLDER)/poly2tri/**/*.cc)
LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.c $(THIRD_PARTY_SRC_FILES) $(GUMP_SRC_FILES)
LOCAL_SHARED_LIBRARIES := SDL2_image SDL2_mixer SDL2_net SDL2 
LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -llog
include $(BUILD_SHARED_LIBRARY)

我的猜测(结果是错误的(:

在写完这个问题并仔细观察以尽可能向你们提供有关我的问题的最准确信息之后,我注意到给出错误的 obj 文件是我在文件夹级别也使用了通配符的文件。例如:$(ROOT)/*/*.cpp。虽然这些通配符没有问题:$(ROOT)/Gump/*.cpp.我不确定,但我想通配符在链接这些不同架构时的工作方式不同......

更新:

我已经再次测试了它,没有对文件夹使用通配符,并且出现了关于多个定义的相同错误。

每次构建新的 ABI 时都会附加文件列表。 LOCAL_SRC_FILES通过include $(CLEAR_VARS)被擦除; 每次都会重新定义GUMP_SRC_FILES。但THIRD_PARTY_SRC_FILES只会越来越长。正如您所注意到的,这与通配符无关。只需添加行

THIRD_PARTY_SRC_FILES :=

include $(CLEAR_VARS)后,您的构建将没问题。

运行ndk-build V=1显示在此过程中执行的生成命令。在那里,我可以看到.o文件被链接了两次。我不确定这是什么原因。我想这可能是由于 src/ 文件夹中的 android makefile 使用了他父目录中的来源:../ThirdParty/[morehere] .

我通过为这些第三方库创建额外的 makefile 来修复它,所以现在每个库都在 .so 文件中创建一个共享库。在编译时链接。我认为这更整洁,因为更改生成文件只需要重新编译该子项目。