作者: 默默
Android下NDK开发的动态库(.so,shared library)增加版本号信息
在Android下面开发,免不了要涉及到C/C++层的开发,这就会涉及到崩溃异常的处理问题。
随着程序的不断升级,更新,会出现多个版本的动态库同时在线上共存的问题,一旦出现崩溃日志,往往不能方便的知道到底是哪个版本出现的崩溃。
传统的Linux,可以通过编译时候指定版本号来处理,最后生成如“libc.so.6”这种形式的文件名,我们可以根据文件名来获得相应的版本信息。遗憾的是,这种命名方式,在Android上面是不支持的。
目前的需求主要有三点:
-
不依赖文件名,查询到版本号
版本号写在文件名中,是一个比较方便的方式,但是带来的问题却是,靠不住!文件名可以随意更改,往往传来传去,文件名中的信息就改得面目全非了。
-
logcat的崩溃日志中能得到版本号
系统自带的logcat会在进程崩溃的时候,打印出崩溃栈,但是信息非常的精简,只有当前的线程回退栈帧信息(backtrace)以及几个关键寄存器信息,往往不能准确提供有足够的信息。而如果想在客户的设备上面,拿到完整的core-dump信息,只能是呵呵一下了!
-
C/C++层的版本号变动,不要改动JAVA层的代码
一方面,如果我们把版本号写在动态库的名字里面,这样会造成每次动态库的升级,JAVA的调用代码都需要变动,小团队还好,大团队,完全不可想象。另一方面,如果是系统框架层的开发,更加悲催,一个文件名的改动,影响到一片,当然,软链接也是个不错的选择,但是这样,常用的APK开发又要折腾一番,免不了一堆的抱怨。
针对上面的需求,我们逐个来提供解决方案:
-
不依赖文件名,查询到版本号
在任意的C/C++文件中增加如下代码
const static __attribute__((unused,section(".SO_VERSION"))) char Version[] = VERSION;
在Android.mk文件中增加
LOCAL_CFLAGS += -DVERSION='"1.0.3"'
编译生成的".so"文件使用如下命令即可查询版本号信息:
$readelf --string-dump=".SO_VERSION" libSo.so String dump of section '.SO_VERSION': [ 0] 1.0.3
解释:
上面的代码的目的,是要求GCC在一个名为".SO_VERSION"的段内,记录我们的版本号信息。“unused”属性用于告诉GCC,不要在编译的时候警告这个变量没有被任何代码引用过。
注意事项:
在定义变量"Version"的时候,不要使用"volatile"来修饰。这个关键字影响到了最后生成的段的"PROGBITS"标记位置,这个标记表明了最后加载到内存中的数据是否可修改(我们当然希望这个位置不可修改,如果可写,可能由于越界导致版本号的不准确)。
没有使用"volatile"修饰
$ readelf -S libSo.so | grep .SO_VERSION [12] .SO_VERSION PROGBITS 0003f520 03f520 000008 00 A 0 0 8
使用"volatile"修饰
$ readelf -S libSo.so | grep .SO_VERSION [12] .SO_VERSION PROGBITS 0003f520 03f520 000008 00 WA 0 0 8
注意两者的不同,一个属性是"A",一个属性是"WA"。
-
logcat的崩溃日志中能得到版本号,并且C/C++层的版本号变动,不要改动JAVA层的代码
目前对于这个问题的解决方法,是设置代理So。具体操作方式如下(假定我们生成的".so"项目LOCAL_MODULE:=So):
1.修改原来项目中的"JNI_OnLoad","JNI_OnUnLoad"函数,重新命名为 "So_JNI_OnLoad","So_JNI_OnUnLoad" 其他代码不变,并且在"So-jni.h"中对这两个函数进行声明。
2.所有的JNI方法都通过 "JavaVM->RegisterNatives" 方法进行动态注册。
3.建立SoStub-jni.cpp,代码如下:
#include "So-jni.h" extern "C" JNIEXPORT int JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { return So_JNI_OnLoad(vm,reserved); } extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) { return So_JNI_OnUnload(vm,reserved); }
4.原工程的"LOCAL_MODULE"修改为"LOCAL_MODULE:=So_1_0_3"(版本号根据实际情况调整即可)
5.修改Android.mk,增加如下内容
include $(CLEAR_VARS) LOCAL_MODULE := SoStub LOCAL_SRC_FILES := SoStub-jni.cpp LOCAL_SHARED_LIBRARIES += So_1_0_3 include $(BUILD_SHARED_LIBRARY)
6.修改JAVA层的调用代码
static { System.loadLibrary("So"); }
为:
static { System.loadLibrary("SoStub"); }
解释:
由于logcat打印的崩溃栈,信息极少,因此我们只能采取这种折中的办法,这样设置之后,崩溃栈中会打印出"libSo_1_0_3.so"这样的字样,我们就可以知道版本号了。
Android Studio(JAVA) 编译警告:使用了未经检查或不安全的操作
在编译Android Studio(JAVA)程序时发生了如下的警告:
使用了未经检查或不安全的操作
要了解详细信息,请使用 "-Xlint:unchecked" 重新编译。
- 如何设置Android Stuido开启 "-Xlint:unchecked"
修改build.gradle
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "com.a.b.c" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { minifyEnabled false } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1' }
增加
tasks.withType(JavaCompile) { options.compilerArgs << "-Xlint:unchecked" }
修改后的如下:
apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "com.a.b.c" minSdkVersion 15 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug { minifyEnabled false } } tasks.withType(JavaCompile) { options.compilerArgs << "-Xlint:unchecked" } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1' }
- 警告信息的处理例子
包含-Xlint:unchecked警告的代码
final LinkedHashMap<WeakReference<Object>,WeakReference<Object>> aWeakArray = new LinkedHashMap<>(); for (Iterator iter = aWeakArray.entrySet().iterator(); iter.hasNext(); ) { LinkedHashMap.Entry element = (LinkedHashMap.Entry)iter.next(); WeakReference<Object> aWeakObj = (WeakReference<Object>)element.getKey(); WeakReference<Object> aWeakTag = (WeakReference<Object>)element.getValue(); }
消除警告后的代码如下:
final LinkedHashMap<WeakReference<Object>,WeakReference<Object>> aWeakArray = new LinkedHashMap<>(); for (Iterator<LinkedHashMap.Entry<WeakReference<Object>,WeakReference<Object>> > iter = aWeakArray.entrySet().iterator(); iter.hasNext(); ) { LinkedHashMap.Entry<WeakReference<Object>,WeakReference<Object>> element = iter.next(); WeakReference<Object> aWeakObj = element.getKey(); WeakReference<Object> aWeakTag = element.getValue(); }
同样的方法适用于"-Xlint:deprecation"。
svnrdump dump 实现 SVN 库的远程导出
svnrdump dump 命令必须 在 SVN 1.7版本以上提供的用于远程dump SVN库的命令.
以导出libyuv的svn库为例:
svnrdump dump http://libyuv.googlecode.com/svn/ > libyuv.dump
可以在这里下载已经DUMP完成之后的版本。目前的版本号是1444。
恢复DUMP文件到Subversion工程,请参考 Could not open the requested SVN filesystem
Debian和OpenMediaVault在命令行下设置更新源
很多时候我们比较纠结的问题是,“该把哪个Debian镜像发布站点加入source.list文件?”。
Ubuntu的图形界面中有一个测试工具,命令行下面的Debian也有一个现成的程序:netselect。
安装netselect
$ sudo apt-get install netselect
不带参数运行它时会显示它的帮助信息。运行它时加上以空格分隔的镜像主机列表,它会返回一个分值和列表中的一个主机名。这个分值通过评估ping time和hopsnumber(一个网络请求报文到达目标主机所经过的转发主机的个数)得出,它与镜像站点预计下载速度成反比(数值越小越好)。返回的主机名是主机列表中得分最低的那个(查看列表中所以主机的得分情况可使用-vv选项)。看出下的例子:
$ netselect http://mirrors.aliyun.com/debian/ http://mirrors.163.com/debian/ 5 http://mirrors.163.com/debian/
它表示,在netselect后列出的所有主机中,http://mirrors.163.com/debian/是下载速度最快的主机,其得分为5。
注意,最近163的服务器不知道发生了何种故障,导致各种更新失败,尽管测试的结果是163更快,但是我们建议还是使用阿里云的服务器。
把netselect找到的连接速度最快的镜像站点手工加入/etc/apt/sources.list文件.
最新版本的netselect软件包包含了netselect-apt脚本,它使上述操作自动完成。只需将发布目录树做为参数(默认为stable)输入,sources.list文件就会生成速度最快的main和non-US镜像站点列表,并保存在当前目录下。
$ sudo apt-get install netselect-apt $ netselect-apt stable $ sudo mv /etc/apt/sources.list /etc/apt/sources.list.old $ sudo mv sources.list /etc/apt/sources.list $ sudo apt-get update
对于OpenMediaVault用户还是手工修改配置文件好了,主要是上面的工具生成的比较简略
# # deb cdrom:[Debian GNU/Linux 7.0.0 _Wheezy_ - Official Snapshot amd64 LIVE/INSTALL Binary 20150108-14:12]/ wheezy contrib main non-free #deb cdrom:[Debian GNU/Linux 7.0.0 _Wheezy_ - Official Snapshot amd64 LIVE/INSTALL Binary 20150108-14:12]/ wheezy contrib main non-free deb http://mirrors.aliyun.com/debian/ wheezy main deb-src http://mirrors.aliyun.com/debian/ wheezy main deb http://security.debian.org/ wheezy/updates main contrib non-free deb-src http://security.debian.org/ wheezy/updates main contrib non-free # wheezy-updates, previously known as 'volatile' deb http://mirrors.aliyun.com/debian/ wheezy-updates main contrib non-free deb-src http://mirrors.aliyun.com/debian/ wheezy-updates main contrib non-free
Ubuntu 12.04 + Apache2.2.22搭建SPDY服务器
SPDY是Google开发的基于传输控制协议(TCP)的应用层协议,该协议规定在一个SPDY连接内可以有无限个并行请求,服务器可以主动向客户端发起通信向客户端推送数据,通过请求优化、预加载、压缩HTTP 来达到加速的目的。
对用记而言,SPDY是基于SSL加密,它可以让网络访问更安全,用户隐私更加得到保护。对站长而言,SPDY在降低连接数目的同时,还使服务器上每个客户端占用的资源减少,从释放出更多内存和CPU ,让网站的浏览速度提升不少。
SPDY协议已经被Chrome、Firefox、Opera、IE 11以上支持,用户在访问使用SPDY协议加载的网站几乎感觉不到与普通的Https页面访问有何不同,而SPDY带来的页面加载速度提升和服务器性能优化确是有十分重要意义的。
具体的操作步骤如下:
- 启用Apache2的HTTPS支持
参考 UBUNTU 12.04 下 APACHE 2.2.22 开启 HTTPS
- 下载Apache2的mod_spdy模块
官网:https://developers.google.com/speed/spdy/mod_spdy/
由于众所周知的原因,本站提供下载(2015-11-6版本)
mod_spdy 64-bit .deb (Debian/Ubuntu)
mod_spdy 32-bit .deb (Debian/Ubuntu)
- 安装mod_spdy模块(本站是64位系统)
$sudo dpkg -i mod-spdy-*.deb $sudo apt-get -f install
- 重启Apache2
$sudo service apache2 restart
- 验证
目前验证貌似没有起作用啊!目前最新的chrome已经没办法进行验证了,主要是由于HTTP/2已经发布,Google放弃了spdy,转而支持HTTP/2,还是静待新版本的HTTP/2吧。
- 卸载
$sudo dpkg -r mod-spdy-beta $sudo dpkg -P mod-spdy-beta
- 参考链接
Linux Mint + Apache2.2搭建SSL/HTTPS/SPDY服务器
https://developers.google.com/speed/spdy/mod_spdy/
Ubuntu 12.04安装PHP5的php-curl扩展
在使用WP-Statistics统计插件的时候,提示GeoIP需要 php-curl扩展。搜索了一下,安装方式如下:
$ sudo apt-get install php5-curl
安装完成后,需要重启Apache2
$ sudo service apache2 restart
WordPress使用WP-PostViews实现网站上显示文章的浏览量
WordPress的使用很方便,但是文章的点击浏览量默认是没有的,本文介绍用WP-PostViews实现网站上显示文章的浏览量的功能。效果如下图所示:
- 安装WP-PostViews插件
在插件界面中安装WP-PostViews插件,并且启用插件。
- 修改主题文件(Twenty Fourteen)
修改content.php,找到如下代码:
<div class="entry-meta"> <?php if ( 'post' == get_post_type() ) twentyfourteen_posted_on(); if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) : ?> <span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'twentyfourteen' ), __( '1 Comment', 'twentyfourteen' ), __( '% Comments', 'twentyfourteen' ) ); ?></span> <?php endif; edit_post_link( __( 'Edit', 'twentyfourteen' ), '<span class="edit-link">', '</span>' ); ?> </div><!-- .entry-meta -->
在后面添加:
<?php /*View Counter for wp-postviews*/ if(function_exists('the_views')) { the_views(); } ?>
修改后的结果如下:
<div class="entry-meta"> <?php if ( 'post' == get_post_type() ) twentyfourteen_posted_on(); if ( ! post_password_required() && ( comments_open() || get_comments_number() ) ) : ?> <span class="comments-link"><?php comments_popup_link( __( 'Leave a comment', 'twentyfourteen' ), __( '1 Comment', 'twentyfourteen' ), __( '% Comments', 'twentyfourteen' ) ); ?></span> <?php endif; edit_post_link( __( 'Edit', 'twentyfourteen' ), '<span class="edit-link">', '</span>' ); ?> <?php /*View Counter for wp-postviews*/ if(function_exists('the_views')) { the_views(); } ?> </div><!-- .entry-meta -->
- 修改主题文件(Twenty Fifteen)
修改content.php,找到如下代码:
<footer class="entry-footer"> <?php twentyfifteen_entry_meta(); ?> <?php edit_post_link( __( 'Edit', 'twentyfifteen' ), '<span class="edit-link">', '</span>' ); ?> </footer><!-- .entry-footer -->
在后面添加:
<?php /*View Counter for wp-postviews*/ if(function_exists('the_views')) { the_views(); } ?>
修改后的结果如下:
<footer class="entry-footer"> <?php twentyfifteen_entry_meta(); ?> <?php edit_post_link( __( 'Edit', 'twentyfifteen' ), '<span class="edit-link">', '</span>' ); ?> <?php /*View Counter for wp-postviews*/ if(function_exists('the_views')) { the_views(); } ?> </footer><!-- .entry-footer -->
LMbench 3.0移植到Android并测试内存带宽
LMbench是个可移植的,用于评价系统综合性能的多平台开源benchmark,能够测试包括文档读写、内存操作、进程创建销毁开销、网络等性能。通过以下步骤操作,即可将LMbench移植到Android上。
- 下载LMbench源码
下载地址http://sourceforge.net/projects/lmbench/
也可在本站下载
- 修改LMbench代码
1.解压缩到指定的目录,保证最终的目录如下:
├── lmbench3/
│ ├── jni/
│ ├── doc/
│ ├── result/
│ ├── scripts/
│ ├── src/
│ ├── ACKNOWLEDGEMENTS
│ ├── CHANGES
│ ├── COPYING
│ ├── COPYING-2
│ ├── hbench-REBUTTAL
│ ├── Makefile
│ ├── README
2.修改“src/bench.h”的38行,40行,注释掉“#include <rpc/rpc.h>”,“#include <rpc/types.h>”,然后添加如下定义
#ifndef S_IREAD #define S_IREAD S_IRUSR #endif #ifndef S_IWRITE #define S_IWRITE S_IWUSR #endif
3.添加根目录下面Android.mk,jni/目录下面内容如下:
# Copyright (C) 2008 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. BUILD_LMBENCH := true include $(call all-subdir-makefiles)
4.添加根目录下面Android.mk,jni/src目录下面内容如下:
# Copyright (C) 2008 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ifeq ($(BUILD_LMBENCH),true) LOCAL_PATH := $(call my-dir) COMMON_CFLAGS := -DANDROID -DHAVE_uint COMMON_LIBS := lmbench_lib ANDROID_LMBENCH := true # Build lmbench_lib include $(CLEAR_VARS) LOCAL_SRC_FILES := lib_unix.c lib_timing.c \ lib_mem.c lib_stats.c lib_debug.c getopt.c lib_sched.c ifneq ($(ANDROID_LMBENCH),true) LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) lib_tcp.c lib_udp.c endif LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lmbench_lib include $(BUILD_STATIC_LIBRARY) # # Build mhz on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= mhz.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := mhz include $(BUILD_EXECUTABLE) # # Build bw_file_rd on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= bw_file_rd.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := bw_file_rd include $(BUILD_EXECUTABLE) # # Build bw_mem on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= bw_mem.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := bw_mem include $(BUILD_EXECUTABLE) # # Build bw_mmap_rd on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= bw_mmap_rd.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := bw_mmap_rd include $(BUILD_EXECUTABLE) # # Build bw_pipe on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= bw_pipe.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := bw_pipe include $(BUILD_EXECUTABLE) ifneq ($(ANDROID_LMBENCH),true) # # Build bw_tcp on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= bw_tcp.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := bw_tcp include $(BUILD_EXECUTABLE) endif # # Build bw_unix on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= bw_unix.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := bw_unix include $(BUILD_EXECUTABLE) # # Build lat_cmd on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_cmd.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_cmd include $(BUILD_EXECUTABLE) ifneq ($(ANDROID_LMBENCH),true) # # Build lat_connect on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_connect.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_connect include $(BUILD_EXECUTABLE) endif # # Build lat_ctx on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_ctx.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_ctx include $(BUILD_EXECUTABLE) # # Build lat_fcntl on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_fcntl.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_fcntl include $(BUILD_EXECUTABLE) # # Build lat_fs on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_fs.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_fs include $(BUILD_EXECUTABLE) # # Build lat_mem_rd on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_mem_rd.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_mem_rd include $(BUILD_EXECUTABLE) # # Build lat_mmap on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_mmap.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_mmap include $(BUILD_EXECUTABLE) # # Build lat_ops on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_ops.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_ops include $(BUILD_EXECUTABLE) # # Build lat_pipe on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_pipe.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_pipe include $(BUILD_EXECUTABLE) # # Build lat_pagefault on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_pagefault.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_pagefault include $(BUILD_EXECUTABLE) # # Build lat_proc on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_proc.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_proc include $(BUILD_EXECUTABLE) # # Build lat_rand on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_rand.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_rand include $(BUILD_EXECUTABLE) ifneq ($(ANDROID_LMBENCH),true) # # Build lat_tcp on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_tcp.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_tcp include $(BUILD_EXECUTABLE) endif ifneq ($(ANDROID_LMBENCH),true) # # Build lat_sem on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_sem.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_sem include $(BUILD_EXECUTABLE) endif # # Build lat_sig on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_sig.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_sig include $(BUILD_EXECUTABLE) # # Build lat_syscall on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_syscall.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_syscall include $(BUILD_EXECUTABLE) ifneq ($(ANDROID_LMBENCH),true) # # Build lat_udp on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_udp.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_udp include $(BUILD_EXECUTABLE) endif # # Build lat_unix on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_unix.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_unix include $(BUILD_EXECUTABLE) # # Build lat_usleep on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_usleep.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) -DTRUE=1 -DFALSE=0 LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_usleep include $(BUILD_EXECUTABLE) # # Build cache on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= cache.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := cache include $(BUILD_EXECUTABLE) # # Build line on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= line.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := line include $(BUILD_EXECUTABLE) # # Build lmdd on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lmdd.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lmdd include $(BUILD_EXECUTABLE) # # Build tlb on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= tlb.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := tlb include $(BUILD_EXECUTABLE) # # Build stream on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= stream.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lmstream include $(BUILD_EXECUTABLE) # # Build memsize on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= memsize.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := memsize include $(BUILD_EXECUTABLE) ifneq ($(ANDROID_LMBENCH),true) # # Build lat_select on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_select.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_select include $(BUILD_EXECUTABLE) endif # # Build lat_unix_connect on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_unix_connect.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_unix_connect include $(BUILD_EXECUTABLE) # # Build lat_fifo on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_fifo.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_fifo include $(BUILD_EXECUTABLE) ifneq ($(ANDROID_LMBENCH),true) # # Build lat_http on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= lat_http.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := lat_http include $(BUILD_EXECUTABLE) endif # # Build par_mem on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= par_mem.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := par_mem include $(BUILD_EXECUTABLE) # # Build par_ops on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= par_ops.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := par_ops include $(BUILD_EXECUTABLE) # # Build enough on target # include $(CLEAR_VARS) LOCAL_SRC_FILES:= enough.c LOCAL_STATIC_LIBRARIES := $(COMMON_LIBS) LOCAL_C_INCLUDES := $(common_target_c_includes) LOCAL_CFLAGS := $(COMMON_CFLAGS) $(common_target_cflags) LOCAL_MODULE_TAGS := eng LOCAL_MODULE := enough include $(BUILD_EXECUTABLE) endif
- 编译LMbench代码
ndk-build NDK_PROJECT_PATH=/lmbench3
编译完成后的文件存放在“lmbench3\libs\armeabi”目录下面。
- 测试内存带宽
./bw_mem 16M rdwr
更详细的命令参数,参考bw_mem
- 参考链接
Windows下VirtualBox直接使用物理硬盘作虚拟机磁盘
目前VirtualBox只能用命令行来建立磁盘才可以使用物理硬盘。
我们假定VirtualBox安装在“D:\Program Files\Oracle\VirtualBox”这个目录下面,要在“D:\Users\VirtualBox VMs\Ubuntu\”目录下面生成文件,则执行如下命令:
"D:\Program Files\Oracle\VirtualBox\VBoxManage.exe" internalcommands createrawvmdk -filename "D:\Users\VirtualBox VMs\Ubuntu\Ubuntu.vmdk" -rawdisk \\.\PhysicalDrive1
\\.\PhysicalDrive1 表示机器上的第二块硬盘,\\.\PhysicalDrive0是第一块,\\.\PhysicalDrive2是第三块,以此类推。
在Windows 的磁盘管理中能看到硬盘的分区路径。如下图所示:
然后新建虚拟机,选择"使用已有的虚拟硬盘文件",找到刚刚创建的 Ubuntu.vmdk 即可。
对于Windows 8.1/10系统,以上的命令需要以管理员启动命令行的方式下启动并执行,否则会报告找不到磁盘。另外启动Virtual Box的时候,同样需要以管理员的身份运行,否则会出现VERR_ACCESS_DENIED
错误,如下图所示: