gcc 7.5 libopenal.so
- debug 13.98M
- release 1.2M
- minsizerel:0.9M
安装gcc
sudo apt install gcc-4.8 g++-4.8
查看当前电脑已经安装的gcc
ubuntu@tk5:~/proj/openal-soft$ ll /usr/bin/gcc* lrwxrwxrwx 1 root root 5 May 20 2019 /usr/bin/gcc -> gcc-7* # 可以看到gcc默认指向的地方 -rwxr-xr-x 1 root root 772280 Mar 19 2018 /usr/bin/gcc-4.8* lrwxrwxrwx 1 root root 22 Dec 4 2019 /usr/bin/gcc-7 -> x86_64-linux-gnu-gcc-7* lrwxrwxrwx 1 root root 8 May 20 2019 /usr/bin/gcc-ar -> gcc-ar-7* -rwxr-xr-x 1 root root 27088 Mar 19 2018 /usr/bin/gcc-ar-4.8* lrwxrwxrwx 1 root root 25 Dec 4 2019 /usr/bin/gcc-ar-7 -> x86_64-linux-gnu-gcc-ar-7* lrwxrwxrwx 1 root root 8 May 20 2019 /usr/bin/gcc-nm -> gcc-nm-7* -rwxr-xr-x 1 root root 27088 Mar 19 2018 /usr/bin/gcc-nm-4.8* lrwxrwxrwx 1 root root 25 Dec 4 2019 /usr/bin/gcc-nm-7 -> x86_64-linux-gnu-gcc-nm-7* lrwxrwxrwx 1 root root 12 May 20 2019 /usr/bin/gcc-ranlib -> gcc-ranlib-7* -rwxr-xr-x 1 root root 27088 Mar 19 2018 /usr/bin/gcc-ranlib-4.8* lrwxrwxrwx 1 root root 29 Dec 4 2019 /usr/bin/gcc-ranlib-7 -> x86_64-linux-gnu-gcc-ranlib-7*
切换gcc版本
使用vscode的cmake插件即可切gcc版本,config之后发现报错:
[proc] The command: gcc-4 -v failed with error: Error: spawn gcc-4 ENOENT [proc] The command: g++-4 -v failed with error: Error: spawn g++-4 ENOENT
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
# --install 生成软链接 sudo update-alternatives --install <link> <name> <path> <priority>
这个命令更像之前我写的cc-editor的group的概念,打个组,起个别名,然后选择性的配置后,再更新具体的实体。
ndkr14b/build/cmkae/android.toolchain.cmake
/home/ubuntu/proj/openal-soft/android-ndk-r14b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
The C compiler is not able to compile a simple test program.
cmake会编译try_compile一段测试代码,用来校验编译器是否能够正常工作,如果编译发生异常,就会抛出这个错误
if(NOT CMAKE_C_COMPILER_WORKS) PrintTestCompilerStatus("C" "") file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c "#ifdef __cplusplus\n" "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n" "#endif\n" "#if defined(__CLASSIC_C__)\n" "int main(argc, argv)\n" " int argc;\n" " char* argv[];\n" "#else\n" "int main(int argc, char* argv[])\n" "#endif\n" "{ (void)argv; return argc-1;}\n") try_compile(CMAKE_C_COMPILER_WORKS ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c OUTPUT_VARIABLE __CMAKE_C_COMPILER_OUTPUT) # Move result from cache to normal variable. set(CMAKE_C_COMPILER_WORKS ${CMAKE_C_COMPILER_WORKS}) unset(CMAKE_C_COMPILER_WORKS CACHE) set(C_TEST_WAS_RUN 1) endif()
解决办法:跳过CMakeTestCCompiler.cmake的检查,但是可能会导致其他的问题
SET (CMAKE_C_COMPILER_WORKS 1) SET (CMAKE_CXX_COMPILER_WORKS 1)
接着看后续的错误
arm-linux-androideabi/bin/ld: error: cannot open crtbegin_dynamic.o: No such file or directory
按照网上的解释,是缺少sysroot导致的,那么这个crtbegin_dynamic.o
,而且它还是个o文件,然后你会在ndk里面找到这个文件,好吧,它是Android NDK预编译好的一个文件,问题出在找不到它。
我尝试着在PATH环境变量中增加了sysroot的相关目录,仍旧报这个错误:
ndk_dir=$(pwd)/android-ndk-r14b sysroot=$ndk_dir/sysroot platform=$ndk_dir/platforms/android-9/arch-arm/ PATH=$PATH:$sysroot:$platform cmake
查阅资料发现CMKAE也有sysroot的变量,我尝试着在XCompile-Android.txt
中设置了CMAKE_SYSROOT,发现竟然可以了!
set(CMAKE_SYSROOT ${CMAKE_CURRENT_LIST_DIR}/android-ndk-r14b/platforms/android-9/arch-arm/)
LOCAL_SRC_FILES should point to a file ending with ".so"
安卓限制了必须是*.so
结尾
*.so、*.so.1、*.so.1.19.1 之间的关系
当openal编译完成后,会生成如下三个文件:
vscode也标注了,前2个文件是软链接,最后的一个文件才是实体,为啥要这样呢?
好处是可以动态升级so库,不用重新编译应用程序,也就是so库的热更新
ld: error:/armeabi-v7a/libopenal.so:1: unexpected EOF
当时尝试着将以上三个文件放到Android时,*.so.1链接出现了问题 ,这是linux的典型风格
undefined reference to
我使用的是ndkr20b出现的这个问题,改成ndkr22b就没有这个问题了
/home/ubuntu/proj/openal-soft/android-ndk-r20b/toolchains/llvm/prebuilt/linux-x86_64/lib/gcc/aarch64-linux-android/4.9.x/../../../../aarch64-linux-android/bin/ld: warning: libc++_shared.so, needed by libopenal.so, not found (try using -rpath or -rpath-link) libopenal.so: undefined reference to `vtable for __cxxabiv1::__si_class_type_info' libopenal.so: undefined reference to `vtable for std::length_error' libopenal.so: undefined reference to `vtable for __cxxabiv1::__class_type_info' libopenal.so: undefined reference to `__cxa_throw' libopenal.so: undefined reference to `std::__ndk1::mutex::unlock()'
- NDK的libc++的C++11命名空间为std::__ndk1
- NDK的gnustl的C++11命名空间为std
- 安卓系统的libc++的C++11命名空间为std::__1
ndk | openal | arch | debug | release | minsizerel |
r22b | v1.22.0 | arm64v8-a | 12.17 | 10.94 | 10.37 |
armeabi-v7a | 11.21 | 9.02 | 9.30 |
交叉编译的CMAKE变量
- CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
- CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
- CMAKE_FIND_ROOT_PATH_MODE_INCLUDE
控制
find_file
和find_path
是否使用CMAKE_FIND_ROOT_PATH
和CMAKE_SYSROOT
指定在交叉编译环境下查找头文件时的查找策略,在交叉编译环境中,通常需要使用交叉编译工具链来编译项目。由于交叉编译环境和本地开发环境存在差异,因此在编译过程中需要指定一些特定的参数和路径,以确保编译器能够正确地查找到所需的库和头文件。
CMAKE_FIND_ROOT_PATH_MODE_XXX
有三种不同的取值:
NEVER
:从不在包含目录中查找根路径。
ONLY
:只在包含目录中查找根路径。
BOTH
:先在系统目录中查找,如果没有找到再在包含目录中查找根路径。
通过设置这个变量,可以根据具体情况灵活地调整头文件的查找策略,以便正确地编译项目。
The value of CMAKE_SYSROOT: xxx does not match any of the forms:
这个错误报到了cmake内部:/usr/share/cmake-3.10/Modules/Platform/Android-Determine.cmake
本质上还是我们的CMAKE_SYSROOT变量设置的有问题导致的,我们可以写个测试例:
set(url "/home/ubuntu/proj/openal-soft/android-ndk-r14b/platforms/android-21/arch-arm") # 多了一个/结尾,就引发了这个错误 set(url "/home/ubuntu/proj/openal-soft/android-ndk-r14b/platforms/android-21/arch-arm/") if(url MATCHES "^([^\\\n]*)/platforms/android-([0-9]+)/arch-([a-z0-9_]+)$") message("match") message(${CMAKE_MATCH_1}) message(${CMAKE_MATCH_2}) message(${CMAKE_MATCH_3}) else() message("don't match") endif()
编译arm64-v8a已经设置了SYSROOT,但是linking的时候提示找不到libm.so liblog.so libOpenSLES.so
android-ndk-r14b/platforms/android-21/arch-arm64/usr/lib/libm.so
so文件是有的,但是link时找不到,但是build目录的确是编译出来了libopenal.so,并且测试发现这个so是可以用的,cmake提示的错误target是alrecord
CMakeFiles/alrecord.dir/build.make:96: recipe for target 'alrecord' failed