K-Res

VS结合VisualGDB搭建OpenWrt交叉编译远程调试开发环境

由于此开发环境涉及3设备协同工作,因此先说明一下整体开发环境的配置以及每部分所负责的功能:
1.Windows PC
这里我用的是64位Win7,作为VS的安装环境Windows自然是必不可少的,本机主要用于结合VisualGDB插件完成项目创建,上传编译机编译并部署执行程序到测试机完成gdbserver远程调试(自然是背后gdb前脸VS的全图形可视化调试)
2.Linux PC
这个我这里是CentOS Linux release 7.2.1511 64bit,安装于VMWare虚拟机上(当然也可以用真机,效果更佳!),作为交叉编译OpenWrt执行程序的编译机,由VisualGDB通过ssh连接同步Win机上的项目源码,make文件等并进行编译,同时还作为gdb客户端连接OpenWrt调试服务端并由VisualGDB传递gdb调试操作间接实现Win端的VS图形化调试
3.OpenWrt Router
这个我这里使用的是联想的Y1S路由器,MT7620A mips架构,作为整个开发环境的目标平台,接收Linux编译后的执行程序,并负责启动gdbserver作为远程调试的服务端

整体环境介绍完了,首先要做的是搭建起Linux机上的OpenWrt命令行开发环境(Y1S对应的是OpenWrt-SDK-ramips-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2),并且保证可以使用原始gdb的方式成功进行命令行模式的远程调试,这个就不赘述了,网上有很多相关教程。补充一点,在gdb调试过程中可能会遇到(OpenWrt上线./gdbserver :9876 /mnt/sda1/kcamd启动调试进程):

./scripts/remote-gdb 192.168.99.1:9876 ./build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/kcam/kcamd

This GDB was configured as “–host=x86_64-linux-gnu –target=mipsel-openwrt-linux-uclibc”.

(gdb) b main
Breakpoint 1 at 0x400cac: file main.cpp, line 29.
(gdb) c
Continuing.
warning: `/usr/lib/libstdc++.so.6′: Shared library architecture unknown is not compatible with target architecture mips:isa32r2.
warning: `/lib/libgcc_s.so.1′: Shared library architecture unknown is not compatible with target architecture mips:isa32r2.
warning: Could not load shared library symbols for 5 libraries, e.g. /lib/libuci.so.
Use the “info sharedlibrary” command to see the complete listing.
Do you need “set solib-search-path” or “set sysroot”?

Breakpoint 1, (gdb) n
Remote ‘g’ packet reply is too long: 00000000f8ffffffecdee77740b4ff7701000000f46dff7ffc6dff7f2034847fec6eff7f000101819bffaaacf0ffffff00031c7fffffffff00000000c826e677da6eff7f1c094000406dff7f0098e477f8e0a0000e00000000004400dc7a430087040000900c40000000000000000000a013e877786aff7f786aff7f4c27e67713ff0001a070230029000000a0d1e17724008050ac0c4000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000
(gdb)

Continue reading…

体验了一下Visual Studio 2012和Windows Phone 8 SDK 记录一下模拟器的联网问题

qq20121104141755

VS2012直接在MS的网站上就可以下载ISO,WP8 SDK直接搜索比较容易找到的是在线安装的版本,下载速度比较慢的话可以直接这里下载ISO直装版:

中文 http://go.microsoft.com/fwlink/?LinkID=257234&clcid=0x804 英文 http://go.microsoft.com/fwlink/?LinkID=257234&clcid=0x409

整个开发环境搭建比较轻松,需要说明的一点就是虽然安装VS2012并不需要Win8,但是WP8 SDK要求系统必须为Win8而且是要64位和一个忘了叫什么名字的CPU技术,因为WP8的emulator是基于Win8的Hyper-V虚拟机的。

还有一点要注意的就是VS和WP8 SDK的语言对应问题, Continue reading…

Unity3D使用VisualStudio作为脚本编辑器以及配合NShader插件编辑Shader的方法

Unity3D自带了Mono Develop作为脚本编辑、Shader、调试用的IDE,虽然Mono Develop的功能也算强大,但是对于习惯了VS的开发人员来说,换个新IDE就得适应一套新的…额,感觉!

其实看看Unity项目文件夹内的内容可以发现Unity实际上是生成了VS用的项目文件的,sln、csproj之类的,也就是说是可以比较容易地换用VS作为项目脚本编辑IDE的,简单设置一下就可以了,Edit->Preferences…中修改External Script Editor选项,选中VS的devenv,便会被自动识别出来,如下图所示:

qq20121129103340

这样,点击脚本等的时候Unity就会弹出VS并自动打开关联的项目和要编辑的文件给你了。后来在使用时发现一个小问题,就是我的VS是带VA(大番茄VS程序员的最爱!)的,但如果用Unity启动的话VA会被自动禁用… Continue reading…

使用distcc分布式编译加速Android NDK原生项目编译生成

随着项目规模的增大,源代码文件增多,结构越来越复杂,导致项目编译链接速度变慢是一件让人非常头痛的事!

在Windows上我们用Visual Studio可以使用IncrediBuild (http://www.incredibuild.com/) 这个非常好用的分布式编译工具,配合其自带的VS Add-In可以很方便的将大型项目的编译工作负担分布到网络上的其它机器完成,极大的缩短了项目编译时间,提高工作效率!

不过遗憾的是IncrediBuild目前只支持Windows系统和VS等一些编译环境,对于Android, iOS等交叉编译的移动平台开发环境就无能为力了。

其实对于linux系OS上还是有可用的分布式编译解决方案的,就是接下来我要说的这个distcc,项目介绍请猛击这里:https://code.google.com/p/distcc/

Continue reading…

Android百度地图SDK文字覆盖物的换行和旋转中心点问题

百度地图的Android SDK中支持在地图上添加各种覆盖物,其中包括文字覆盖物TextOptions,但目前版本4.1.0中此功能不支持文字换行,且不可设置文字的中心点,导致如果想要和其它覆盖物混合使用时,如在图标上显示一些文字时,效果很不好,由于只能通过对文字覆盖物的经纬度坐标添加一定的偏移来实现,例如下面这样:

                        // 定位坐标偏移
                        point = new LatLng(lat+0.0001, lng);
                        OverlayOptions textOption = new TextOptions()
                                .bgColor(0xAAFFFF00)
                                .fontSize(24)
                                .fontColor(0xFFFF00FF)
                                .text("test "+formatter.format(date))
                                .position(point);
                        // 在地图上添加该文字对象并显示
                        mBaiduMap.addOverlay(textOption);

Continue reading…

百度鹰眼SDK Android版后台服务的重绑定问题

Android版百度鹰眼SDK(测试版本2.1.15)在开启定位追踪时会开启com.baidu.trace.LBSTraceService的服务来完成后台的定位和上传数据功能,此时如果应用主Activity退出(用户自行关闭,或者被系统kill等情况)时,则需要在重启时检测是否已经开启了追踪服务并可以正确停止服务。按照官方文档的说明,这种情况下应该先通过startTrace()重新进行后台服务的绑定,可以收到“onTraceCallback: 10006, 服务已开启”的结果回调,但我的实际测试结果则是,后台服务运行的情况下,应用重启startTrace()不会收到任何回调!同时又做了几种其它情况下的服务开启关闭测试,结果如下:
在应用不退出重启的情况下,不管是用同样的Trace对象,还是每次都创建同样参数的新Trace对象,都可以顺利连续开启、关闭追踪服务。而在重启应用的状态下,检测到服务正在运行后,用新创建的同样参数的Trace对象尝试startTrace时会出现收不到任何回调的情况,而如果先在应用管理器中手动停止后台服务再startTrace就没问题。
在应用重启的情况下,重新new一样参数的Trace对象,然后调用stopTrace,这样得到的回调结果是“onStopTraceFailed: 11002, 服务未开启”,但此时getRunningServices确实能够查到正在运行的后台服务。又试了通过stopService的方式直接请求停止com.baidu.trace.LBSTraceService服务,此时返回的是true,但getRunningServices依然可以检测到服务正在运行。
附上测试用的检测后台服务运行状态的方法:

    public boolean isTraceServiceRunning() {
        ActivityManager manager = (ActivityManager) getActivity().getSystemService(ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if ("com.baidu.trace.LBSTraceService".equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

最后,在联系了官方后,得到了问题的解决方法:
Continue reading…

内网Visual Studio Code通过XDebug远程调试linux服务器PHP脚本

开发环境是这样:一台位于内网环境下的Windows机器使用VSCode作为IDE编写PHP脚本项目,一台位于公网的linux服务器运行lighttpd、fastcgi PHP用于部署调试。开发机所在网络环境不允许或不方便进行端口映射来打开XDebug所需的本地调试监听端口(默认9000),同时也不想安装本机PHP服务器来调试,于是采用本机编写PHP,然后上传linux服务器直接远程调试,记录环境搭建过程如下:
首先配置好开发机的IDE环境,我用的是VSCode 1.6.1,然后安装PHP Debug扩展,完成后选择一个指定文件夹作为项目根目录并在调试页中新建PHP调试配置,这时会在项目文件夹中生成.vscode/launch.json配置文件,按照PHP Debug的说明,加入serverSourceRoot与localSourceRoot,参考如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "serverSourceRoot": "/var/www/lighttpd/phpproj",
            "localSourceRoot": "${workspaceRoot}"
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9000,
            "serverSourceRoot": "/var/www/lighttpd/phpproj",
            "localSourceRoot": "${workspaceRoot}"
        }
    ]
}

其中serverSourceRoot为项目位于服务器端的存储位置完整路径,localSourceRoot为本地项目存储位置完整路径,一般用环境变量${workspaceRoot}即可表示项目根目录。
Continue reading…

Xcode升级后导致原Qt项目构建失败的问题

原有使用Qt Creator 4.0.2创建的跨平台GUI项目,在近日Xcode升级至8.0后,出现了构建失败的问题,错误信息如下:

clang: warning: no such sysroot directory: ‘/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk’
In file included from ../FbxVertexMerger/main.cpp:1:
In file included from ../FbxVertexMerger/mainwindow.h:4:
In file included from ../../../../Qt5.7.0/5.7/clang_64/lib/QtWidgets.framework/Headers/QMainWindow:1:
In file included from ../../../../Qt5.7.0/5.7/clang_64/lib/QtWidgets.framework/Headers/qmainwindow.h:43:
In file included from /Users/wzkres/Qt5.7.0/5.7/clang_64/lib/QtWidgets.framework/Headers/qwidget.h:43:
In file included from /Users/wzkres/Qt5.7.0/5.7/clang_64/lib/QtGui.framework/Headers/qwindowdefs.h:43:
In file included from /Users/wzkres/Qt5.7.0/5.7/clang_64/lib/QtCore.framework/Headers/qglobal.h:81:
/Users/wzkres/Qt5.7.0/5.7/clang_64/lib/QtCore.framework/Headers/qsystemdetection.h:95:12: fatal error: ‘TargetConditionals.h’ file not found
# include <TargetConditionals.h>

显然,问题出在MacOSX10.11.sdk这个位置,升级后的MacOSX SDK变为了MacOSX10.12.sdk,那么如何让Qt使用新版本的SDK呢?很简单,修改Qt项目的.pro文件,加入 Continue reading…

VC++项目中第三方库代码生成std::string对象的析构崩溃问题

在使用预编译好的第三方库时,一定要注意生成库时的Runtime Library运行时库是否与引用库项目所使用的一致,一般提供prebuilt库方都会按照这些规则给库文件命名,如mt、mt-d等。
这次在测试一个别人提供好的mongo库时,就遇到了由于运行时库不一致导致的莫名其妙崩溃问题,崩溃代码如下:

mongo::BSONObjBuilder builder;
builder.append("type", 2)
mongo::BSONObj obj = builder.obj();
obj.jsonString();

在jsonString()这一步,任何BSONObj的转std::string方法,如toString()等,构造出的std::string在析构时会导致崩溃,大致看了下是标准库中的析构函数内执行此处时触发的:

__CLR_OR_THIS_CALL ~basic_string()
    {   // destroy the string
    _Tidy(true);
    }

放开运行的话会提示堆已被破坏,修改了一些调用代码方式,无果,最后发现自行创建的std::string析构时执行同样逻辑没有问题,最终发现是由于dll库使用的是debug版运行时库,而主程序使用的是非debug运行时库所致,在VS中Configuration properties->C/C++->Code Generation->Runtime Library,选择一致的debug版运行时库后,问题解决。