AIX上编译tcmalloc需要专用的版本
下载地址:https://github.com/gilamn5tr/gperftools/archive/refs/heads/aix-enablement-upstream.zip
将下载的文件解压
进入目录 gperftools-aix-enablement-upstream中,执行
./autogen.sh
生成configure文件
在AIX上可以指定编译64位的库还是编译32位的库,最好是两个都进行编译。
这里需要注意的是,如果使用xlc编译,那么测试使用的二进制文件也需要是xlc编译的,xlc编译的库文件和gcc编译的二进制文件不能够组合使用。
如果使用gcc编译则都使用gcc编译,否则都使用xlc编译。
编译64位库的方法:
./configure CC=/opt/IBM/openxlC/17.1.0/bin/ibm-clang CXX=/opt/IBM/openxlC/17.1.0/bin/ibm-clang++_r CXXFLAGS=-m64 CFLAGS=-m64 AR="ar -X64" RANLIB="ranlib -X64" NM="nm -X64"
64位库编译完成后,如果要使用libtcmalloc_minimal.a作为静态库在AIX上使用MALLOCTYPE特性(MALLOCTYPE特性使用的库文件中包含的.o文件的名字必须是mem32.o或者mem64.o,否在在使用MALLOCTYPE的时候会报出MALLOCTYPE=user:libtcmalloc_minimal.a ../run_base_test_clang_default.0000/omnetpp_r_base.clang_default -c General -r 0
USER DEFINED MALLOC ERROR:
Unable to load user supplied object: "libtcmalloc_minimal.a(mem64.o)", load() errno == 8
的错误),则需要手动对libtcmalloc_minimal.a文件重新进行打包
进入到编译目录中的.libs目录下,执行如下命令重新创建libtcmalloc_minimal.a文件
cp libtcmalloc_minimal.so.4 mem64.o
ar -X32_64 -r libtcmalloc_minimal.a mem64.o
可以通过ar -v -t -X32_64来查看一个.a库文件中包含的内容:
ar -v -t -X32_64 libtcmalloc_minimal.a
如果还需要编译32为的库,可以使用如下命令:
./configure CC=/opt/IBM/openxlC/17.1.0/bin/ibm-clang CXX=/opt/IBM/openxlC/17.1.0/bin/ibm-clang++_r AR="ar" RANLIB="ranlib" NM="nm"
可以将编译好的32位库添加到上述打包的libtcmalloc_minimal.a文件中
cp libtcmalloc_minimal.so.4 mem32.o ar -X32_64 -r libtcmalloc_minimal.a mem32.o
这样在libtcmalloc_minimal.a文件中就既包含了32位的库又包含了64位的库。
编译完成后可以使用一个简单的c或者cpp文件来测试libtcmalloc_minimal.a库是否能够正确使用,
/opt/IBM/openxlC/17.1.0/bin/ibm-clang++_r -o test test.c -L. -ltcmalloc_minimal
进一步可以使用AIX上的MALLOCTYPE特性来测试是否能够指定采用tcmalloc的malloctype类型
MALLOCTYPE=user:libtcmalloc_minimal.a ./test
当然这需要提前设置LBIPATH路径为libtcmalloc_minimal.a所在的目录
export LIBPATH=/home/tcmalloc
如果不进行环境变量设置,则会报出load() errno == 2的错误表示找不到对应的库文件
USER DEFINED MALLOC ERROR:
Unable to load user supplied object: "libtcmalloc_minimal.a(mem64.o)", load() errno == 2
附录:
在执行上述操作的过程中,可能缺少一些rpm包
1. 执行autogen.sh的时候报错找不到autoreconf命令,这需要安装autoconf对应的rpm包(autoconf的rpm安装需要依赖很多其他的rpm包,这些包都需要下载安装,AIX上的rpm包下载位置可在AIX Toolbox for Open Source Software : Downloads alpha中或者Index of /download/RPMS中找到,这些包的依赖关系可以在Index of /download/rpmdb/deplists中找到),安装完成后如果还是提示找不到,则可能是环境变量路径设置的问题,通过rpm包安装的autoconf默认的二进制文件在/opt/freeware/bin/目录下,可以在当前console中设置环境变量:
export PATH=/opt/freeware/bin:$PATH
2. 执行autogen.sh的时候报出无法执行aclocal的错误
Can't exec "aclocal": No such file or directory at /opt/freeware/share/autoconf/Autom4te/FileUtils.pm line 326.
autoreconf: failed to run aclocal: No such file or directory
这个问题产生的原因是因为缺少automake包,需要安装automake的rpm包来解决,同样automake也有一些依赖的rpm包,这些rpm包都要安装上
3. 执行autogen.sh的时候报出找不到AR_PROC_LIBTOOL的错误
configure.ac:163: error: possibly undefined macro: AC_PROG_LIBTOOL
这个问题产生的原因是因为缺少了libtool包,需要安装libtool的rpm包来解决
4. 执行autogen.sh的时候报出m4的错误
/opt/freeware/share/aclocal/iconv.m4:1: warning: ill-formed serial number 'AM2', expecting a version string with only digits and dots
/opt/freeware/share/aclocal/codeset.m4:1: warning: ill-formed serial number 'AM1', expecting a version string with only digits and dots
libtoolize: error: One of these is required:
libtoolize: gm4 gnum4 m4
libtoolize: error: Please install GNU M4, or 'export M4=/path/to/gnu/m4'.
这个问题产生的原因是因为M4的环境变量没有设置
export M4=/opt/freeware/bin/m4
5. 执行.configure文件提示找不到C和C++编译器的错误,这需要在./configure执行的时候添加CC和CXX来指定对应的编译器路径
./configure CC=/opt/IBM/openxlC/17.1.0/bin/ibm-clang CXX=/opt/IBM/openxlC/17.1.0/bin/ibm-clang++_r
6. 执行make的时候报出格式错误
"(stdin)", line 7452: make: 1254-055 Dependency line needs colon or double colon operator.
"(stdin)", line 7453: make: 1254-055 Dependency line needs colon or double colon operator.
"(stdin)", line 7455: make: 1254-055 Dependency line needs colon or double colon operator.
"(stdin)", line 7457: make: 1254-055 Dependency line needs colon or double colon operator.
"(stdin)", line 7459: make: 1254-055 Dependency line needs colon or double colon operator.
make: 1254-058 Fatal errors encountered -- cannot continue.
产生这个问题的原因是因为AIX自带的make造成的,解决这个问题的办法是使用rpm包安装的make来代替系统自带的make,这样configure就能够执行成功了,当然也需要提前设置环境变量的路径
export PATH=/opt/freeware/bin/:$PATH
MALLOCTYPE的详细信息可以查看
gcc用于指定AIX是32位还是64位的参数是-maix64,不添加-maix64表示编译的是32位,在使用configure的时候可以使用CPPFLAGS=-maix64 CFLAGS=-maix64参数
openxlc用于指定AIX是32为还是64位的参数是-m64,不添加-m64表示编译的是32位,在使用configure的时候可以使用 CXXFLAGS=-m64 CFLAGS=-m64参数
用ar命令打包库文件的时候,可能会出现类似如下的错误
0654-210 .libs/libpcre_la-pcre_byte_order.o is not valid in the current object file mode. Use the -X option to specify the desired object mode.
产生这个错误的原因是因为ar打包的时候使用的库文件的位数不匹配,可以在ar命令后添加-X64或者-X32来重新执行
同理,在查看库文件的时候,如果不添加-X64,则默认只会显示库文件中包含32位的文件,添加-X64后会只显示库文件中包含的64位的文件,添加-X32_64能够显示32位和64位的文件
注意:如果使用通用的tcmalloc,在AIX上编译,如果采用gcc编译器则会报出找不到匹配函数的错误
In file included from src/debugallocation.cc:76: ./src/malloc_hook-inl.h:83:12: error: no matching function for call to 'NoBarrier_Load' return base::subtle::NoBarrier_Load(&priv_end) == 0; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./src/base/atomicops-internals-gcc.h:112:17: note: candidate function not viable: no known conversion from 'const AtomicWord *' (aka 'const long *') to 'const volatile Atomic32 *' (aka 'const volatile int *') for 1st argument inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { ^ ./src/base/atomicops-internals-gcc.h:185:17: note: candidate function not viable: no known conversion from 'const AtomicWord *' (aka 'const long *') to 'const volatile base::subtle::Atomic64 *' (aka 'const volatile long long *') for 1st argument inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { ^ In file included from src/debugallocation.cc:76: ./src/malloc_hook-inl.h:89:24: error: no matching function for call to 'NoBarrier_Load' return bit_cast<T>(base::subtle::NoBarrier_Load(place)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ ./src/base/atomicops-internals-gcc.h:112:17: note: candidate function not viable: no known conversion from 'const AtomicWord *' (aka 'const long *') to 'const volatile Atomic32 *' (aka 'const volatile int *') for 1st argument inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) { ^ ./src/base/atomicops-internals-gcc.h:185:17: note: candidate function not viable: no known conversion from 'const AtomicWord *' (aka 'const long *') to 'const volatile base::subtle::Atomic64 *' (aka 'const volatile long long *') for 1st argument inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) { ^ In file included from src/debugallocation.cc:85: In file included from ./src/tcmalloc.cc:136: ./src/thread_cache.h:286:23: error: TLS model 'initial-exec' is not yet supported on AIX CACHELINE_ALIGNED ATTR_INITIAL_EXEC; ^ ./src/base/basictypes.h:204:54: note: expanded from macro 'ATTR_INITIAL_EXEC' #define ATTR_INITIAL_EXEC __attribute__ ((tls_model ("initial-exec")))
在其他系统的机器上交叉编译的尝试也失败了。
注意:IBM的tcmalloc应该是在xlc16.1.0上进行的编译,xlc17.1.0没有看到有支持-qmaxmem=-1这个选项