欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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.

重点是这几句:

  1. profmancompat.cpp.o:1:3: invalid character
  2. profmancompat.cpp.o:1:3: syntax error, unexpected $end
  3. 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 就能做一些内联优化,从而减少最终生成物体积。

Android NDK 报错:undefined reference to ‘main‘(invalid character)解决办法

那有没有可能是 -flto 优化过程中生成的信息导致了这个问题呢?

试着删除这个信息后,居然真的编译通过了!

这个问题耗费了些时间,虽然具体原因还不清楚,但希望遇到同样问题的同学,可以多一个尝试选择。