Android NDK 报错:undefined reference to ‘main‘(invalid character)解决办法
程序员文章站
2022-07-14 23:34:40
...
好久没写博客了,现在更习惯用脑图记录知识点,记一些关键字即可,快速又成体系。
不过分享的初心还是要保持,不能总是索取而不贡献,现在雷同的内容太多了,还是需要一些较为稀缺的信息。在通过其他前辈分享的文章学习知识、解决问题后,这种想法就更加强烈。
今天遇到一个奇怪的问题,报错如下:
* What went wrong:
Execution failed for task ':profmancompat:externalNativeBuildRelease'.
> Build command failed.
Error while executing process /Users/simon/Library/Android/sdk/cmake/3.10.2.4988404/bin/ninja with arguments {-C /Users/simon/AndroidStudioProjects/profmancompat/profmancompat/.cxx/cmake/release/armeabi-v7a profmancompat-lib}
ninja: Entering directory `/Users/simon/AndroidStudioProjects/profmancompat/profmancompat/.cxx/cmake/release/armeabi-v7a'
[1/2] Building CXX object CMakeFiles/profmancompat-lib.dir/profmancompat.cpp.o
[2/2] Linking CXX executable profmancompat-lib
FAILED: profmancompat-lib
: && /Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++ --target=armv7-none-linux-androideabi16 --gcc-toolchain=/Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64 --sysroot=/Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/sysroot -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security -std=c++11 -g -Oz -DNDEBUG -Wl,--exclude-libs,libgcc_real.a -Wl,--exclude-libs,libatomic.a -static-libstdc++ -Wl,--build-id -Wl,--fatal-warnings -Wl,--exclude-libs,libunwind.a -Wl,--no-undefined -Qunused-arguments -Wl,--gc-sections CMakeFiles/profmancompat-lib.dir/profmancompat.cpp.o -o profmancompat-lib -L/Users/simon/AndroidStudioProjects/profmancompat/profmancompat/src/main/cpp/../jniLibs/armeabi-v7a -lprofman-slib -lprofman-29 -llog -latomic -lm && :
/Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: CMakeFiles/profmancompat-lib.dir/profmancompat.cpp.o:1:3: invalid character
/Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: CMakeFiles/profmancompat-lib.dir/profmancompat.cpp.o:1:3: syntax error, unexpected $end
/Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/../../../../arm-linux-androideabi/bin/ld: error: CMakeFiles/profmancompat-lib.dir/profmancompat.cpp.o: not an object or archive
/Users/simon/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib/arm-linux-androideabi/16/crtbegin_dynamic.o:crtbegin.c:function _start_main: error: undefined reference to 'main'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
重点是这几句:
- profmancompat.cpp.o:1:3: invalid character
- profmancompat.cpp.o:1:3: syntax error, unexpected $end
- crtbegin_dynamic.o:crtbegin.c:function _start_main: error: undefined reference to ‘main’
搜了下关键字,回答基本上是 main 定义的问题,和我实际情况不符。
在尝试把代码里无关的字符删除后,还是不行,那报错信息里的字符究竟是哪儿来的呢?
后来盯着 CMakeList,看到这些编译、link 优化项,心想也没有可能是这些的配置导致的:
add_compile_options(-Oz -flto -ffunction-sections -fdata-sections -fexceptions -frtti)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -O3 -flto -Wl,--exclude-libs,ALL -Wl,--gc-sections -Wl,--no-fatal-warnings")
从 https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 里查到,-flto
大概的作用就是:在编译时,会在生成的目标文件里,插入一个特殊的格式信息(GIMPLE 格式)。然后在链接时,读取多个目标文件里的 GIMPLE 信息,合并成一个。这样 gcc 就能做一些内联优化,从而减少最终生成物体积。
那有没有可能是 -flto
优化过程中生成的信息导致了这个问题呢?
试着删除这个信息后,居然真的编译通过了!
这个问题耗费了些时间,虽然具体原因还不清楚,但希望遇到同样问题的同学,可以多一个尝试选择。