修复 KDE5 Plasma 下的 konsole 终端字体加粗问题

首先,好久没写博客了=。=接下来一年一定挤出时间咕咕咕

最近遇到了一个比较实际的玄学问题。在 konsole 配置 Draw intense as color时,konsole终端打印高亮(打印字符 \x1B[1;37mhello 屏幕上会输出高亮白色的 hello)时会将高亮部分单独加粗。相比于单纯的终端配色,这种加粗比较符合个人的习惯。但我所使用的 KDE5 Plasma 桌面在某次更新后,konsole 的终端字体加粗消失了。大概效果是这样:

变化前:

intense_font_with_bold_style

变化后(WTF!):

intense_font_without_bold

 

考虑到应该是一些脚本被自动更新,不太可能是字体本身的问题(freetype库并不在此次更新之列),Qt库的核心也并未更新所以也不太可能是 Qt 渲染出了问题。Google此类问题后并未找到合适的解决方案,大概是此类问题一般不会有人想着去解决,一般也不会引起注意(大概世界上只有我一个强迫症)

(不过奇怪的是,Monospace字体竟没有受到影响,但是个人实在是喜欢 Consolas 字体,因此还是选择继续折腾)

 

Solved:

我最终解决方案是编辑 ~/.config/kdeglobals如果你也是强迫症,这些内容可能对你有用。

 

Step1. 首先确保 [General]段包含fixedfontmenufont三种不同场合的字体设置。

我的 General 段内容:

[General]
ColorScheme=Breeze
Name=Breeze
fixed=Consolas,11,-1,0,50,0,0,0,0,0
font=Noto Sans,10,-1,5,50,0,0,0,0,0
menuFont=Noto Sans,10,-1,5,50,0,0,0,0,0

;注意以上三行
shadeSortColumn=true
smallestReadableFont=Noto Sans,8,-1,5,50,0,0,0,0,0
toolBarFont=Noto Sans,10,-1,5,50,0,0,0,0,0
widgetStyle=Breeze

Step2. 删除[General]段所有,Regular$

 

完毕后保存该文件,启动一个新的 konsole 看看效果~

 

 

争取今年抽出时间写博客~给大家拜个晚年

 

关于博客近期的情况

由于4月末毕业设计答辩临近,紧追慢赶完善毕业设计,结果忘记给 Linode 续费(侧面反映出有多忙,连邮件都没看,Linode 发了好几封催费信),最终导致之前的 Linode VPS 被回收,从而所有博客内容都丢失了。

检讨之余发现,有个神奇的网站叫「为程序员服务」默默地收录了我所有的博文!相当于帮我做了备份。惊喜之下,立即将博文中重要的一些内容复制回自己的新博客。所有恢复的博文都带有前缀 「[recover]」。在此向为程序员服务表示诚挚的谢意!(真是为程序员服务啊,改名叫为老中医服务吧lol(开个玩笑

近期将毕设制作过程发到博文上(先预告,再咕咕咕

[recover]使用 chroot 大法在 Android 上体验 Debian

用 Android 手机五年多,对于一上手就尝试安装终端模拟器的我来讲,这种东西少不了折腾(。

在 Android 下折腾过的同学们应该有感触,这确实是个 Linux,却和寻常的 Linux 并不太像。例如目录结构不同,软件移植有困难,常用的库和软件在 Android 下几乎找不到……等等。虽然早早入了 CM 大法,有了少量的 GNU 工具至少改善了环境,但还是觉得很不爽,似乎我在一个 Linux 设备上工作,行为却得不到 100% Free 的保证。

尝试过 N 多次移植工作,包括将 GNU/Linux 上好用的工具跨平台编译到 Android,甚至直接用 Linux 桌面发行版替换 Android,但均以失败告终,无非是手机不如 PC 好折腾,平台封闭,厂家说一不二,等等。

直到后来,看到了 Debian 官网上的一篇文章: https://wiki.debian.org/ChrootOnAndroid ,颇有兴趣,并至今都使用这种笨办法。

工具:

  • 一个现有的、CPU指令集和你的手机CPU指令集兼容的 Linux(以 Debian 为例)平台。
  • debootstrap
  • Busybox for Android。
  • 手机(我使用我的旧手机 ZTE N909 来作为例子)
  • 一个 TF 闪存卡(至少4GB,推荐 32GB+)

基础知识:

Step1.

先给你的手机获取root权限。

警告!此步骤可能会导致你的手机丧失保修。请参考你手机厂商的保修政策再继续。本文仅供参考,造成的损失博主不予负责。

这个步骤我就没什么说的了,各家手机都有各家的方法,不一一列举了。反正最终你的手机获取了root权限,这就可以了。

Step2.

给你的手机安装 BusyBox。

个人推荐 BusyBox Pro 安装器,比较方便,Google Play 地址为 https://play.google.com/store/apps/details?id=stericson.busybox 。当然你用别家的 busybox 也可以,但是请注意 一定要有 chroot 和 mount 这个命令 ,不然等于没有安装。

安装完毕后,打开 终端模拟器 ,在shell下输入 busybox,可以得到这样的输出:

请忽略最后一行那个提示符后面的问号(

Step3.

构建一个最小化可用的根文件系统。

这一步我们需要现有的 Linux 平台,并要求这个平台和你的手机 CPU 平台是兼容的。所以嘛,你 PC 上的 Linux 就不能用啦,还有什么服务器大型机统统不适合这个情景。个人推荐 树莓派 Orange pi 等直接可以拿来用的设备。

安装 debootstrap 只需要 apt-get install 即可,输入下列命令:
~ # apt-get install debootstrap

然后在终端命令行下敲下 debootstrap 就会有这样的回显:

然后插上你的TF卡,挂载到一个位置(我这里挂载到 /mnt/target_debian),然后执行命令:

~ # debootstrap --arch armhf jessie /mnt/target_debian/ http://mirrors.sohu.com/debian

然后你的屏幕就会出现以下提示:

Tips:–arch armhf 这个参数是从源中下载 armhf 的软件包。如果你的手机实在太太太老…CPU 平台为 ARM11,请选择 armel 或者可以选择“树莓派版本的 Debian” — Raspbian,方法大同小异。

Step4.

对你的根文件系统进行初始化。

此时 cd 到你的这个目录下,可以发现,这里产生了一个完整的根文件系统。

然而这个根文件系统却无法直接应用到 Android 设备上,这是因为:

  1. Debian 的 udev 依赖于内核中的 devtmpfs,然而 Android 的内核多半精简掉了这个组件。所以我们使用 busybox 中的 mdev 来代替 udev(当然如果你意外地发现,Debian 自带的 udev 能够启动,那说明你的内核支持 devtmpfs,那就正常用咯:))。
  2. 正常的系统启动依赖于 init 脚本化的初始化过程,然而 Android 的启动过程迥异于正常的 Linux 系统,所以我们需要编写一个 initscript。

在你刚准备好的根文件系统目录下面,执行命令:

~ # chroot .

便会发现,你的 shell 指示的当前路径又变成了 / 。

执行命令:apt-get install busybox, 这一步非常重要! 因为我们将采用 mdev 来初始化 /dev,而 mdev 是 busybox 中的工具之一。

然后我们编写 initscript。这个script一般情况下是参考个人的手机特性,进行删减修补,但是目的只有一个,保证chroot后的环境足够健壮可用。下面我贴出我的 initscript:


#! /bin/dash

# 初始化用户变量
export PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
export HOME=/root
export SHELL=/bin/bash
export TERMINFO=/etc/terminfo
export LD_LIBRARY_PATH=/lib:/usr/lib

#设置主机名
hostname ZTE-PHONE
mount sysfs /sys -t sysfs
mount proc /proc -t proc
mount tmpfs /dev -t tmpfs

#初始化 /dev 目录
busybox mdev -s

#初始化 devpts。切记!一定要把这一步摆在 mdev 后面,不然 /dev/pts 将被新的 /dev 覆盖而失效。
mkdir /dev/pts
mount devpts /dev/pts -t devpts
chmod -R 777 /dev/
mount tmpfs /run/lock -t tmpfs -o rw,nosuid,nodev,noexec,relatime,size=5120k
cp /system/etc/mtab.rc /etc/mtab
clear

# 打印欢迎信息
echo "Welcome to Debian 8 jessie on Android!"
echo "Create by M0xkLurk3r at Sep.23 2015"
echo ""
cat /etc/motd
echo ""
/bin/bash

完毕后将 initscript 保存至 chroot 后的根目录的 /system/bin/sh(也可以是其他位置,只要你能记住。主要是我的 chroot 命令会在 chroot() 之后默认执行该位置的shell,所以个人喜欢这个位置啦(-。-;)),加上可执行权限。

Step5.

安装 sshd。

这样我们可以从电脑端进行控制。实际上安装之后,你会发现你的手机上的 Debian 系统多半是通过 ssh 连接操作的:(

执行命令: apt-get install sshd

Step6.

将卡插到手机上,测试启动。

一般情况下,插上卡以后,你的TF卡都会挂载到 /dev/block/mmcblk1 这个位置,然后第一个分区是 /dev/block/mmcblk1p1。然后我们现在要挂载这个设备,然后chroot。

执行下列命令:

~ # busybox mount /dev/block/mmcblk1p1 /storage/sdcard1/

(切记使用 busybox 的 mount,toolbox 的 mount 非常弱智,不建议使用)

~ # busybox chroot /storage/sdcard1/ -s /system/bin/sh

(chroot 也是 busybox 中的工具。切记 -s 跟着你的 initscript 脚本)

然后你就会发现,你的shell变了一个风格。恭喜,你在手机上运行了一个Debian。

下面附上:我的手机运行效果:

Screenshot_2016-02-17-17-10-10

已知问题:

  • 普通账户无法访问网络。这表现为:mysql、squid 等做了“为了防止远程代码执行而将 working process 降权” 的服务无法启动,普通用户无法 bind,甚至 ssh 无法连接。这是因为,Android 为了适配自身的权限管理,对内核做了些许改动(具体代码可以看这里: https://android.googlesource.com/kernel/common/+/android-4.4/include/linux/android_aid.h )。在不重刷无限制的内核(不推荐,可能会导致 Android 自己的权限管理机制失效)的情况下,你只能将普通权限账户加入到这个头文件中规定的组中。使用命令:

~ # addgroup inet_a --gid 3003

~ # addgroup inet_w --gid 3004

~ # usermod -g inet_a heaperchan

~ # usermod -g inet_w heaperchan

这样就解决了。

  • systemd 基本报废。因为 systemd 需要的系统功能你的手机内核并不支持,而且 systemd 根本不支持在 chroot 环境中运行(其实都不支持吧)。我的手机执行 systemd 相关命令,会显示如下提示:

没有办法,在这里启动或关闭服务,你只能使用 service 命令。

  • 其他问题有待补充。

[recover]Qt5.1.1 Windows下编译静态链接教程

偶最近开始使用Qt来编写程序。Qt的高效和可移植性很吸引人,但是一个坑爹的问题就是输出可执行文件始终都是共享链接EXE,需要Qt的动态链接库。而且修改Makefile参数不能更改设置(仅能设置是否依赖 MSVCRT),甚是恼人。在 Linux 下面可以要求用户使用软件前安装相应库作为依赖包,但是Windows下面这么搞一定会招致用户的厌烦。
经过不懈的Google,终于找到了一个可行的办法,现介绍使用 VS2010 和 MinGW 时的方法。

要求原料:
Qt5.1.1 源码:
http://mirrors.neusoft.edu.cn/qt/official_releases/qt/5.1/5.1.1/single/qt-everywhere-opensource-src-5.1.1.7z
ActivePerl-5.16.1.1601-MSWin32-x86-296175:
http://www.leekai1995.com/dl/Perl.7z
python-3.3.0:
http://www.leekai1995.com/dl/Python33.7z
Ruby:
http://www.rubyinstaller.org/
MinGW 或者 MSVC201X 编译器。这个你应该已经折腾好了吧(-。-;)

开始工作!
先将 qt-everywhere-opensource-src-5.1.1.7z 解压到D:\Qt\5.1.1(假如你的Qt安装到了D:\Qt),解压完后把解出的文件夹qt-everywhere-opensource-src-5.1.1更名为msvc2010-static 或者 mingw32-48-static (你不改名也行。我有强迫症)。Perl.7z 和 Python33.7z 解压到 C:\。Ruby安装到 D:\Ruby200。最终应该包含这些目录/文件:

D:\Qt\5.1.1\msvc2010-static(或者mingw32-48-static)\qtbase\mkspecs\win32-g++
D:\Qt\5.1.1\msvc2010-static(或者mingw32-48-static)\qtbase\mkspecs\win32-msvc2010
C:\Perl\bin
C:\Perl\site\bin
C:\Python33\python.exe
D:\Ruby200\bin
D:\Qt\Tools\mingw48_32\bin

搞定后,打开cmd(如果你想编译基于MSVC2010的Qt,请打开 Visual Studio 命令提示),执行命令:


set PATH=C:\Perl\bin;C:\Perl\site\bin;C:\Python33;D:\Ruby200\bin;%PATH%
set PATH=D:\Qt\Tools\mingw48_32\bin;%PATH% (可选。这条编译MinGW的时候必须执行,MSVC2010的时候随意。)
set PATH-D:\Qt\Tools\QtCreator\bin;%PATH% (可选。使用MSVC2010的话如果觉得nmake.exe太慢可以执行这条命令,到最后可以使用jom.exe代替nmake.exe)

上列命令执行成功的标志是在执行过命令的cmd窗口里执行gcc会提示 no input files,执行python会进入python的交互命令行,执行Perl和Ruby都会有反应。

完毕后,切换到之前解压Qt源码的目录,编译基于MinGW的Qt5.1.1的话,执行这个命令:

configure.bat -confirm-license -opensource -platform win32-g++ -release -static -ltcg -c++11 -accessibility -rtti -qt-sql-sqlite -qt-sql-odbc -plugin-sql-sqlite -plugin-sql-odbc -qt-zlib -qt-libpng -qt-libjpeg -audio-backend -opengl desktop -no-qml-debug -no-vcproj -no-dbus -nomake tests -nomake examples -qt-freetype

基于MSVC2010的Qt执行这个命令:

configure.bat -confirm-license -opensource -platform win32-msvc2010 -release -static -ltcg -c++11 -accessibility -rtti -qt-sql-sqlite -qt-sql-odbc -plugin-sql-sqlite -plugin-sql-odbc -qt-zlib -qt-libpng -qt-libjpeg -audio-backend -opengl desktop -no-qml-debug -no-vcproj -no-dbus -nomake tests -nomake examples -qt-freetype

等待刷屏,一会儿会提示配置成功,只需要执行mingw32-make或者nmake就表示成功了。此时您可以执行make命令:

MinGW 执行这个命令:
>mingw32-make
想快点的话可以适当使之多线程运行Makefile脚本:
>mingw32-make -j8 (笔者的机器CPU2内核4逻辑核心,使用8线程同时编译。读者可以根据自己的机器配置来适当调整线程。)

MSVC2010:
>mingw32-make
想快点的话可以适当使之多线程运行Makefile脚本:
>mingw32-make -j8 (同上。读者根据自己的机器配置适当调整/J后的数字)

完毕后,打开 Qt Creator,点击 Tools(工具(T))-> Options(选项(O)…),点击 Build and run(构建和运行),选择右侧的 Qt Version,点击右侧的Add… 按钮。之后切到你解压源码的目录,选择\qtbase\bin\qmake.exe即可。
之后切到 Build Kit(构建套件),新建一个套件,在下面Qt Version一栏选择你刚新建的Qt 版本,编译器选择和你刚编译的Qt版本同一类型的编译器即可。
完毕后,你就可以使用新的Qt编译工程了!做出来的EXE不依赖于任何Qt的动态链接库,完全的静态链接。

实测:笔者之前做过的一个将近千行的工程,用MinGW静态版编译,EXE大小14M,用UPX压缩后4.9M。用MSVC2010编译8M,UPX压缩后4.7M。但是MinGW速度较快,可能是mingw32-make比nmake执行速度快的缘故。

[recover]Attempting to face the unknown future.

高考结束了,三年的高中生涯感觉就像一场梦一样,忽然醒了。梦的结局也在意料之中,高考惨败。到现在爸妈还在为我的学校筹划,而且三本学校的学费也很多,这令我愧怍万分。但是经过商讨还是决定只要有学上就不复习了。与其浪费一年青春,还不如在大学里继续去拼,毕竟到时候就可以正儿八经的钻研自己想做的事、为自己想达到的目的而奋斗了。爸妈也没有更多的诘责,但我也从来没有把这个心理包袱真正的放下过。不过也希望这个成为我将来拼搏的动力吧。
感觉高中最对不起的就是爸妈,掏了赞助费让我来到四中上学,却没有如他们所愿考上一个好大学,甚至觉得当时就不应该来四中。不过如果不来四中,也许现在我的人生轨迹就会发生改变,不会见到这班同学,不会交到几个可以掏心窝子的兄弟,也许也不会遇到一个让我单恋两年难以自已的她。经历了这么多,感觉这三年还是体验颇丰的,最起码学会了如何看人,如何做事。
感觉现在面对的还是一个未知的未来。我梦想着在电脑上取得极高的造诣,闲暇时用音乐调节,或者写写歌,自抒己怀。但是我担心被人高高的举起又狠狠地抛下。当然这些都是未知数,也可能第二天我就要负箧曳屣到远方,也许这要等到很长时间以后,也许这又是一个未知数,也许。。。

[recover]通过 Google Git 仓库获取 Android 代码得到的几点经验。

写这篇文章纯属无聊,下个代码的操作有什么可写的,又不是给人说我编程序的经验。不过下源码这么长时间,感觉这里面门道还是有的,所以分享出来。
最近无聊,下下安卓源码看看。一是想研究研究这里面的玄妙,二是在我手里的两个Android Phone实在是不争气(一个是海尔 HE-N6E,一个是Coolpad 5930),而且硬件平台我已经知道了,所以想换尝试给他们制作一个ROM。前面的那个手机还是ARM11处理器架构,android 2.2.2老到不能在老的系统,玩个愤怒的小鸟都卡到AppHang掉,后面的那个也就是我现在正用的手机,性能还不错,但是。。。酷派这个坑爹的,做的ROM各种坑啊,新浪微博闪退。更恶心的是破解了root权限删了系统软件一重启,那些令人作呕的图标就又回来了。而且貌似没出过新的ROM。。。
好了废话不多说了,开始言归正传。我下载下载源码用的是git-repo(废话),环境是cygwin,必须装的软件包是git-core,curl,python2.7这几个。遇到的问题更多的莫过于repo被迫中断吧。下面就这个问题讨论一下。
1. 一般情况下最常见的提示就是Exit sync due to fetch errors。遇到这个八成是repo自己抽了,重新执行repo sync即可。
2. 如果连接反复出错,可能是google git仓库的问题。我当时从网上搜了一下,看到的结果是登录到https://android.googlesource.com/new-password 这个页面,会请求和你的谷歌账号连接,之后有个提示反正就是问你要不要允许什么的,直接允许就行,最后给出一串代码,有machine、login、password的,用兼容unix格式的文本编辑器保存到家目录下(cygwin就是 \home\<你的windows用户账号> ,Linux就直接在终端下cd ~ 就到了)即可。
3. 如果第 2 条作完还反复出错,你可以考虑找一个代理。找到合适的代理后在终端下输入 export HTTP_PROXY=<代理服务器IP>:<端口> 和 export HTTPS_PROXY=<代理服务器IP>:,如果没有这情况还是不挂代理的好。而且据本人观察,Google GIT 代码仓库一般在上午8:00~11:00左右抽风的几率比较小,所以可以选择这个时间段开始下载代码。
4. 如果提示403 Forbidden那实在没辙,参考第二条的方法;如果提示Operation now in progress(估计给了提示repo就会卡死,没当场卡斯也会很快卡死,但是不会返回命令行),那就打开一个新终端,杀死所有python(有可能是python2.7,以实际情况为准)、git、git-remote-https进程(win下为.exe,可以用任务管理器结束。其他都一样,下同)。之前的那个终端中的repo就会退出。这时重新执行repo sync就行。
5. 如果执行了repo sync后迟迟没反应,那就看一下进程。如果发现只有一个git、git-remote-https(如果之前初始化的时候你用的不是https地址那这里就是git-remote-http),果断使用第四条的方法一次。如果还是这样,那就重新拨号,重新启动电脑。
6. 如果给提示Not a git repository,那证明这个软件包对应的git目录是损坏的(可能之前下载时git-repo抽了)。解决方法是,找到终端中提示的无效git目录,在源码目录中找到这个git,直接删除即可。再执行repo sync一般问题就会解决。(据本人观察,有时候403 Forbidden错误也可以用这个方法解决。例如提示https://android.googlesource.com/a/platform/foo/bar 403 Forbidden,直接找到<源码目录>/.repo/projects/foo/bar.git这个目录直接删掉,在运行repo sync就行了。

就这几点经验,也是使用过程中得来的,在这儿分享给大家。有好的也欢迎分享给我。关于编译Android源码的过两天再发布。