12/25/2016

Install the latest cmake to Ubuntu

Step 1 : Download the latest and stable cmake from https://cmake.org/download/

I download the source of cmake with v3.7.1 to my Ubuntu 14.04.

Step2 : Extract the compressed file and build it

$ cd cmake-3.7.1
$ ./bootstrap --prefix=/usr
$ make
$ sudo make install

Step3 : Check it

$ cmake --version

Expected output:  cmake version 3.7.1

12/07/2016

Make python program executable and compile for Windows exe on Linux

  This week, I spend some time to make one of my repositories, LablelImg,  on Github become an executable file. The LablelImg is implemented  in Python, and it has some dependencies like lxml and pyQt. In order to let other people use the tool easier without installing python and their dependencies, I decide to make it a standalone executable. I described as below about how I have done to compile it for Window exe and Linux binary on Ubuntu. In Python, there are some packages which can let python files become an executable file, e.g pyexe, pyinstaller, and so on.
Then, I decide to pick pyinstaller because its document and relevant reference are concise.

Environment : 

OS: Ubuntu 14.04
Necessary packages and tools :
  1.   wine (1.6.2)
  2.   pyinstaller (2.1)
  3.   virtual-wine (0.1)
  4.   python-2.7.8.msi
  5.   pywin32-218.win32-py2.7.exe 
  6.   PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe
  7.   lxml-2.3.win32-py2.7.exe
The steps to install or download them:
wine : $ apt-get install wine
pyinstaller : $ git clone https://github.com/pyinstaller/pyinstaller
virtual-wine : $ git clone https://github.com/htgoebel/virtual-wine.git
python-2.7.8 : Download from https://www.python.org/ftp/python/2.7.8/python-2.7.8.msi
pywin32-218.win32-py2.7 : Download from http://nchc.dl.sourceforge.net/project/pywin32/pywin32/Build%20218/pywin32-218.win32-py2.7.exe
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe: https://www.riverbankcomputing.com/software/pyqt/download
lxml-2.3.win32-py2.7.exe : Download from  https://pypi.python.org/pypi/lxml/2.3/

Install packages to virtual env

Create a virtual wine environments using virtual-wine:
$ apt-get install scons
$ ./virtual-wine/vwine-setup venv_wine

Active virutal env:
$ . venv_wine/bin/activate

Use wine to install python packages to your virtual env: 
$ wine msiexec -i python-2.7.8.msi
$ wine pywin32-218.win32-py2.7.exe
$ wine PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe
$ wine lxml-2.3.win32-py2.7.exe

Build your python files using pyinstall under virtual environment

$ wine c:/Python27/python.exe pyinstaller/pyinstaller.py -D -F -n AppName -c "main.py" 
The exe file will be located under dist directory

Check out my scripts, you will be more clear

Check out my script to setup the environment and make pyQt executable.
https://github.com/tzutalin/labelImg/tree/master/build-tools

11/27/2016

Record Android touch event or other events

  Recently, I met a problem which I cannot use Android-unit-test to do some of the test cases. I browse through some of apps or tools, but they are not handy for me. So I wrote a simple python tool to record my Android events like touching, gyro, and so on. Then, I can use my tools on my PC to playback the events I recorded. It's very convenient for me to reproduce some issues.

https://github.com/tzutalin/adb-event-record


11/02/2016

[Ubuntu Network] Share internet connection from mobile phone to PC via USB


Mobile

Go to Setting -> Network share -> Turn on USB network share

PC

Configuring the PC that will connect to the network which is provided by Mobile phone. Open your Network Manager via the Network Icon on the Unity Panel.


10/26/2016

Setup ssh connection on Ubuntu

Install necessary packages:



Host:
sudo apt-get update
sudo apt-get install openssh-server
sudo ufw allow 22
Client:
sudo apt-get install openssh-client


Connect usage:

ssh username@host

Advanced:

On the client side, create the host alias for ssh. Edit ~/.ssh/config, then copy the below pattern to the config file
Host workstation
HostName 10.70.70.44
User darrenl
Port 22
Then, we can simply the usage to connect to host
ssh workstation
Copy the public key to remote host using ssh-copy-id, thus, we didn't need to type password every time

ssh-copy-id -i ~/.ssh/id_rsa.pub remote-host


-

8/18/2016

Generate javadoc using gradle

In your build.gradle file, adding the below snipet of code can generate the java doc of your module

configurations {
    javadocDeps
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:support-annotations:${rootProject.ext.androidSupportSdkVersion}"    javadocDeps "com.android.support:support-annotations:${rootProject.ext.androidSupportSdkVersion}"}

task generateJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath()
            .join(File.pathSeparator))

    classpath += configurations.javadocDeps    failOnError false    destinationDir = file("../javaDoc/")
    exclude {
        it.file.path.contains('aidl')
    }
}


8/02/2016

Auto-generating enum/constants for different languages like c++, java, python, and so on

  In the past, speaking of cross-language tools to serialize and auto-generate structured data, you might use Protobuf to do that, Recently, I start to use flatbuffers to serialize/deserialize and auto-generate my data structure. There are a lot of comparisons on Protobuf, json, and flatbuffers, you can refer to the below links:
Why consider flatbuffer over json
How much is flatbuffer faster protobuf
Primay differences between protbuf and flatbuffers

Today, I am going to demonstrate how to use flatbuffers to auto-generate enum/constants for different languages like c++, java, python, and so on.

Clone flatbuffers
git clone https://github.com/google/flatbuffers
cd flatbuffers
Depending on your platform, use one of e.g.
$ cmake -G "Unix Makefiles"
$ cmake -G "Visual Studio 10"
$ cmake -G "Xcode"
Start to build
$ make
After making it, there is one of executable files, called flatc. Now, we can use flatc to genereate different source files for different language using flatbuffers's interface definition language(IDL).

Create an IDL file
vi resultcode.fbs
namespace tzutalin.common;
enum ResultCode { SUCCESS = 0, TIME_OUT, UNKNOWN_ERROR }
Use the below command to generate its c++ header, python, and Java file.
$ ./flatc --cpp --python --java -b resultcode.fbs

After generating, it creates ./resultcode_generated.h, ./tzutalin/common/ResultCode.py, and ./tzutalin/common/ResultCode.java.

resultcode_generated.h:
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_RESULTCODE_TZUTALIN_COMMON_H_
#define FLATBUFFERS_GENERATED_RESULTCODE_TZUTALIN_COMMON_H_
#include "flatbuffers/flatbuffers.h"
namespace tzutalin {
namespace common {
enum ResultCode {
  ResultCode_SUCCESS = 0,
  ResultCode_TIME_OUT = 1,
  ResultCode_UNKNOWN_ERROR = 2,
  ResultCode_MIN = ResultCode_SUCCESS,
  ResultCode_MAX = ResultCode_UNKNOWN_ERROR
};
inline const char **EnumNamesResultCode() {
  static const char *names[] = { "SUCCESS", "TIME_OUT", "UNKNOWN_ERROR", nullptr };
  return names;
}
inline const char *EnumNameResultCode(ResultCode e) { return EnumNamesResultCode()[static_cast<int>(e)]; }
}  // namespace common
}  // namespace tzutalin
#endif  // FLATBUFFERS_GENERATED_RESULTCODE_TZUTALIN_COMMON_H_
ResultCode.py
# automatically generated by the FlatBuffers compiler, do not modify
# namespace: common
class ResultCode(object):
    SUCCESS = 0
    TIME_OUT = 1
    UNKNOWN_ERROR = 2
ResultCode.java:
// automatically generated by the FlatBuffers compiler, do not modify
package tzutalin.common;
public final class ResultCode {
  private ResultCode() { }
  public static final byte SUCCESS = 0;
  public static final byte TIME_OUT = 1;
  public static final byte UNKNOWN_ERROR = 2;
  public static final String[] names = { "SUCCESS", "TIME_OUT", "UNKNOWN_ERROR", };
  public static String name(int e) { return names[e]; }
}

8/01/2016

Restore missing tools/status/menu bar in Ubuntu 16.04

  Recently, I upgraded my Ubuntu from 14.04 to 16.04. It works well after upgrading. But someday my toolbar and menu bar are missing after I updating some packages and rebooting. Then, I try to enable Unity Launcher again, my toolbar and menu are back. The below steps are what I do

1. $ sudo apt install compizconfig-settings-manager
2. $ ccsm
3. Enable Ubuntu Unity Plugin. It will ask some questions because enabling it conflicts with another one.

7/20/2016

Use Rapidjson in cpp to read/write json file

  In C++, if you want to serialize, deserialize, prettify JSON, there are some libraries to allow you to do that, e.g. JsonCPP and RapidJson. Compare with JsonCpp and Rapidjon, Rapidjson is faster then JsonCPP. Besides, Rapidjson is a header-only library, so it is easy to include Rapidjon using the different build system, and I have tested and used Rapidjon on my Linux application and android native side.

  There is a snippet of code to serialize and deserialize Json file as bellow.

Write
#include <rapidjson/document.h>
#include <rapidjson/prettywriter.h>
#include <rapidjson/stringbuffer.h>
#include <stdio.h>
#include <sys/stat.h>

using namespace rapidjson;
std::stringstream ss_date;
time_t t = time(0);
struct tm * now = localtime(&t);
ss_date << (now->tm_year + 1900) << '-' << (now->tm_mon + 1) << '-'
        << now->tm_mday; 
StringBuffer s;
PrettyWriter<StringBuffer> writer(s);
writer.StartObject();
writer.Key("version");
writer.String("1.0");
writer.Key("data");
writer.String(ss_date.str().c_str());
writer.Key("file");
writer.StartArray();
// m_vWriteFilePath is a vector<std::string> which contains 0.mp3 1.mp3 ...
for (const auto& path : m_vWriteFilePath) {
  writer.String(path.c_str());
}
writer.EndArray();
writer.EndObject();
std::ofstream of(m_indexFilePath);
of << s.GetString();
if (!of.good())
  throw std::runtime_error("Can't write the JSON string to the file!");
Result:
{
    "version": "1.0",
    "data": "2016-7-20",
    "file": [
        "0.mp3",
        "1.mp3",
        "2.mp3",
        "3.mp3",
        "4.mp3"
    ]
}
Read
using namespace rapidjson;
std::stringstream ss;
std::ifstream file(m_indexFilePath);
if (file) {
  ss << file.rdbuf();
  file.close();
} else {
  throw std::runtime_error("!! Unable to open json file");
}
Document doc;
if (doc.Parse<0>(ss.str().c_str()).HasParseError())
  throw std::invalid_argument("json parse error");
// Start parsing json string
std::string version = doc["version"].GetString();
std::string date = doc["data"].GetString();
const Value& array = doc["file"];
for (rapidjson::SizeType i = 0; i < array.Size(); i++) {
  m_vReadFilePath.push_back(array[i].GetString());
}