arm 交叉编译找不到so_交叉编译v8时,提示找不到libstdc++.so.6里面GLIBCXX_3.4.20版本的某个符号...

host:ubuntu12.04,gcc4.6,glibc2.15

target: x86, ia32,gcc4.9, glibc2.20

编译v8的时候,先编译host程序,然后用host程序产生一些文件,最后再编译target程序。

这里提示运行host程序mksnapshot时,找不到libstdc++.so.6里面GLIBCXX_3.4.20版本的某个符号:

CXX(target) /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.target/v8_nosnapshot/src/snapshot/snapshot-empty.o

AR(host) /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/tools/gyp/libv8_nosnapshot.a

CXX(host) /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/mksnapshot/src/snapshot/mksnapshot.o

AR(target) /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.target/tools/gyp/libv8_nosnapshot.a

AR(host) /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/testing/libgtest.a

LINK(host) /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/mksnapshot

ACTION tools_gyp_v8_gyp_v8_snapshot_target_run_mksnapshot /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.target/v8_snapshot/geni/snapshot.cc

ACTION tools_gyp_v8_gyp_v8_snapshot_host_run_mksnapshot /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/v8_snapshot/geni/snapshot.cc

/disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/mksnapshot: /usr/lib/i386-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/mksnapshot)

/disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/mksnapshot: /usr/lib/i386-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/mksnapshot)

make[2]: *** [/disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.target/v8_snapshot/geni/snapshot.cc] Error 1

make[2]: *** Waiting for unfinished jobs....

先看看mksnapshot到底缺少哪一个符号,使用objdump -C -T out/ia32.release/mksnapshot  | grep GLIBCXX_3.4.20:

shuyin.wsy@localhost:/disk7/shuyin.wsy/codebase_host/vm/v8$ objdump -C -T out/ia32.release/mksnapshot | grep GLIBCXX_3.4.20

00000000 DF *UND* 00000000 GLIBCXX_3.4.20 std::__throw_out_of_range_fmt(char const*, ...)

-C是将c++的符号解码为用户可以看明白的符号;-T显示dynamic-syms,nm --dynamic也可以显示动态符号,但是objdump -T的带有符号版本,更方便。

编译的时候没问题,也连接成功了,但是运行时出现了问题,可能是host程序链接了target的动态库,验证一下:

shuyin.wsy@localhost:/disk7/shuyin.wsy/codebase_host/vm/v8$ objdump -C -T /lib/i386-linux-gnu/libc.so.6 | grep GLIBCXX_3.4.20

shuyin.wsy@localhost:/disk7/shuyin.wsy/codebase_host/vm/v8$ objdump -C -T /disk7/shuyin.wsy/codebase_host/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/sysroot/usr/lib/libstdc++.so.6 | grep GLIBCXX_3.4.20

000a3490 g DF .text 000000d0 GLIBCXX_3.4.20 std::__throw_out_of_range_fmt(char const*, ...)

0004a390 g DF .text 00000012 GLIBCXX_3.4.20 std::get_new_handler()

000a4780 g DF .text 000000e9 GLIBCXX_3.4.20 std::regex_error::regex_error(std::regex_constants::error_type)

00000000 g DO *ABS* 00000000 GLIBCXX_3.4.20 GLIBCXX_3.4.20

00049b10 g DF .text 00000014 GLIBCXX_3.4.20 std::get_terminate()

00049b90 g DF .text 00000014 GLIBCXX_3.4.20 std::get_unexpected()

确认是链接了target的动态库,可能是使用ld时指定了错误的参数(-Lsome_target_libdir);可能是环境变量里面有问题(比如LIBRARY_PATH=some_target_libdir:${LIBRARY_PATH});也可能是使用了target的i686-linux-gnu-g++(i686-linux-gnu-g++设置LIBRARY_PATH环境变量,包含了target动态库的路径,然后调用collect程序,collect程序再去调用ld)。

经过分析,排出前两种可能,给build/gyp/pylib/gyp/generator/make.py打如下patch,可以在连接mksnapshot的时候报错,把命令打出来:

diff --git a/build/gyp/pylib/gyp/generator/make.py b/build/gyp/pylib/gyp/generator/ma

index 786b4e0..fd3bf65 100644

--- a/build/gyp/pylib/gyp/generator/make.py

+++ b/build/gyp/pylib/gyp/generator/make.py

@@ -142,7 +142,7 @@ cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.

# special "figure out circular dependencies" flags around the entire

# input list during linking.

quiet_cmd_link = LINK($(TOOLSET)) $@

-cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start

+cmd_link = $(error $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl

# We support two kinds of shared objects (.so):

# 1) shared_library, which is just bundling together many dependent libraries连接mksnapshot的命令为:

/disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-g++ -B/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/binutils/Linux_x64/Release/bin -pthread -fuse-ld=gold -B/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/binutils/Linux_x64/Release/bin -fuse-ld=gold -B/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/binutils/Linux_x64/Release/bin -m32 -m32 -L/disk7/shuyin.wsy/codebase_host/out/platforms/tablet.cht.intel.eng.x86/host/lib -o /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/mksnapshot -Wl,--start-group /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/mksnapshot/src/snapshot/mksnapshot.o /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/tools/gyp/libv8_base.a /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/tools/gyp/libv8_nosnapshot.a /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/tools/gyp/libv8_libplatform.a /disk7/shuyin.wsy/codebase_host/vm/v8/out/ia32.release/obj.host/tools/gyp/libv8_libbase.a -Wl,--end-group -ldl -lrt -licui18n -licuuc -licudata.确实是使用了target的i686-linux-gnu-g++。

由于v8使用gyp编译,先要熟悉一下编译流程,首先分析出build/gyp/pylib/gyp/generator/make.py文件的GenerateOutput函数是产生Makefile文件的,在里面raise,看看python是怎么调用的:

Traceback (most recent call last):

File "build/gyp/gyp_main.py", line 16, in

sys.exit(gyp.script_main())

File "build/gyp/pylib/gyp/__init__.py", line 545, in script_main

return main(sys.argv[1:])

File "build/gyp/pylib/gyp/__init__.py", line 538, in main

return gyp_main(args)

File "build/gyp/pylib/gyp/__init__.py", line 523, in gyp_main

generator.GenerateOutput(flat_list, targets, data, params)

File "build/gyp/pylib/gyp/generator/make.py", line 2074, in GenerateOutput

raise()然后gyp的工作流程就是:

1、Makefile里面调用build/gyp/gyp:

build/gyp/gyp --generator-output="$(OUTDIR)" build/all.gyp \

-Ibuild/standalone.gypi --depth=. \

-Dv8_target_arch=$(V8_TARGET_ARCH) \

$(if $(findstring $(CXX_TARGET_ARCH),$(V8_TARGET_ARCH)), \

-Dtarget_arch=$(V8_TARGET_ARCH),) \

$(if $(findstring optdebug,$@),-Dv8_optimized_debug=1,) \

-S$(suffix $(basename $@))$(suffix $@) $(GYPFLAGS)2、build/gyp/gyp里面执行了build/gyp/gyp_main.py,将所有参数传递过去了:

#!/bin/sh

set -e

base=$(dirname "$0")

exec python "${base}/gyp_main.py" "$@"

3、build/gyp/gyp_main.py调用了build/gyp/pylib/gyp/__init__.py的函数:

if __name__ == '__main__':

sys.exit(gyp.script_main())4、build/gyp/pylib/gyp/__init__.py中执行gyp_main函数,使用parser处理build/gyp/gyp的输入参数,从build/standalone.gypi的json数据里面获得CC,CXX,CC.host,CXX.host的默认值:

['clang==1 and ((OS!="mac" and OS!="ios") or clang_xcode==0) '

'and OS!="win" and "

'make_global_settings': [

['CC', '

['CXX', '

['CC.host', '$(CC)'],

['CXX.host', '$(CXX)'],

],

}],

也就是make.py里面的data[build_file]的数据,在make.py中打印make_global_settings_array:

[['CC', '/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang'], ['CXX', '/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang++'], ['CC.host', '$(CC)'], ['CXX.host', '$(CXX)']]

经过make.py中如下代码的处理:

for key, value in make_global_settings_array:

if re.match('.*_wrapper', key):

continue

if value[0] != '$':

value = '$(abspath %s)' % value

wrapper = wrappers.get(key)

if wrapper:

value = '%s %s' % (wrapper, value)

del wrappers[key]

if key in ('CC', 'CC.host', 'CXX', 'CXX.host'):

make_global_settings += (

'ifneq (,$(filter $(origin %s), undefined default))\n' % key)

# Let gyp-time envvars win over global settings.

env_key = key.replace('.', '_') # CC.host -> CC_host

if env_key in os.environ:

value = os.environ[env_key]

make_global_settings += ' %s = %s\n' % (key, value)

make_global_settings += 'endif\n'

else:

make_global_settings += '%s ?= %s\n' % (key, value)

环境变量里有CC和CXX,分别为/disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-gcc,/disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-g++;环境变量里没有CC_host, CXX_host,所以生成的部分Makefile为:

ifneq (,$(filter $(origin CC), undefined default))

CC = /disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-gcc

endif

ifneq (,$(filter $(origin CXX), undefined default))

CXX = /disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-g++

endif

ifneq (,$(filter $(origin CC.host), undefined default))

CC.host = $(CC)

endif

ifneq (,$(filter $(origin CXX.host), undefined default))

CXX.host = $(CXX)

endif这四个if都是满足条件的,所以:

CC.host = CC = /disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-gcc

CXX.host = CXX = /disk7/shuyin.wsy/codebase_host/xmake/prebuilts/gcc/linux-x86/x86/i686-linux-gnu-4.9-glibc-2.20/bin/i686-linux-gnu-g++在编译v8之前,指定环境变量CC_host和CXX_host即可:

CC_host="$${YUNOS_ROOT}/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang"

CXX_host="$${YUNOS_ROOT}/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang++"

另外,在target为arm的一个分支上:

build/standalone.gypi得到的数据为:

['clang!=1 and host_clang==1 and target_arch!="ia32" and target_arch!="x64"', {

'make_global_settings': [

['CC.host', '

['CXX.host', '

],

}],

make.py中make_global_settings_array为:

[['CC.host', '/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang'], ['CXX.host', '/disk7/shuyin.wsy/codebase_host/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang++']]输出的部分Makefile为:

ifneq (,$(filter $(origin CC.host), undefined default))

CC.host = $(abspath /disk7/shuyin.wsy/codebase_host/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang)

endif

ifneq (,$(filter $(origin CXX.host), undefined default))

CXX.host = $(abspath /disk7/shuyin.wsy/codebase_host/vm/v8/third_party/llvm-build/Release+Asserts/bin/clang++)

endif

你可能感兴趣的:(arm,交叉编译找不到so)