Material Design的库在视觉效果上相当棒,而且现在也有为iOS提供的MD风格控件,效果上不会输似Android

但是,MD在iOS上的实现在实际的使用中还是存在许多问题的,我打算针对这些已经存在的问题专门写这篇文章,一方面可以记录我在不断尝试中所得到的结论,另一方面也希望后来的人能够少走些弯路

首先,Material Design有个通病,如果使用Storyboard来画界面,那么会无法在Storyboard上进行预览。比如说我拖一个UITextField,然后将Class设置成MDCFilledTextField后,结果界面上依旧还是原来的UITextField的样子。

界面并没有变化
界面并没有变化

而且,MD里面的一些设置属性在界面上也无法进行设置,因为根本就没有设置的地方。。。

还是原来的UITextField的那些属性,没有自定义的那些属性
还是原来的UITextField的那些属性,没有自定义的那些属性

也许你能通过Identity Inspector的key-value来设置属性,我没有去尝试效果如何。

MDCTextField/MDCTextArea

引用一张官方图:

输入框

这里着重说一下7。图中,7所代表的是Helper/error/counter text。它只是个text,本身并没有提供方法设置成具体的helper,或者是error、counter类型,需要开发者自行决定其用途。翻看它所对应的设置方法,官方提供的方法写的实在是太模糊了,容易误导,正确的设置应该是下面这样的:

设置文本内容:

MDCOutlinedTextField * textField;
//这里初始化,随便你是从storyboard中拉还是直接new
//......
textField.leadingAssistiveLabel.text  = @"左侧文本";
textField.trailingAssistiveLabel.text = @"右侧文本";

设置Helper/error/counter text的颜色,是有提供两个方法的:

/**
 Sets the trailing assistive label text color.
 @param trailingAssistiveLabelColor The UIColor for the given state.
 @param state The MDCTextControlState.
 */
- (void)setTrailingAssistiveLabelColor:(nonnull UIColor *)trailingAssistiveLabelColor
                              forState:(MDCTextControlState)state
    NS_SWIFT_NAME(setTrailingAssistiveLabelColor(_:for:));

/**
 Sets the leading assistive label text color.
 @param leadingAssistiveLabelColor The UIColor for the given state.
 @param state The MDCTextControlState.
 */
- (void)setLeadingAssistiveLabelColor:(nonnull UIColor *)leadingAssistiveLabelColor
                             forState:(MDCTextControlState)state
    NS_SWIFT_NAME(setLeadingAssistiveLabelColor(_:for:));

// MDCTextControlState的定义如下:

/**
 A set of mutually exclusive readonly states that text controls can inhabit. The value of a text
 control's MDCTextControlState is internally determined by whether or it it's editing and whether or
 not it's enabled.
 */
typedef NS_ENUM(NSInteger, MDCTextControlState) {
  /**
   The default state of the contained input view, when it is resting and not editing.
   */
  MDCTextControlStateNormal,
  /**
   The state the view is in during normal editing.
   */
  MDCTextControlStateEditing,
  /**
   The disabled state.
   */
  MDCTextControlStateDisabled,
};

你可以根据需要,动态改变文本的颜色。那么字体呢?当然也是可以改变的!

//举个例子:
textField.leadingAssistiveLabel.font=[UIFont fontWithName:@"TimesNewRomanPSMT" size:13];
textField.trailingAssistiveLabel.font=[UIFont fontWithName:@"TimesNewRomanPSMT" size:16];

然后,坑就来了!

坑一:在Android中,可以通过监听输入框中的输入事件来进行一些处理,比如说显示用户输入了多少个字符。但是很遗憾,我研究了很久,包括使用了addTarget方法,在storyboard上右键控件然后拖一个event等,均不能监听到输入框的用户输入事件

坑二:尽量不要在Storyboard上对其高度进行限制。为什么这么说呢?还是来看那张官方图。从上面到下面的helper文本,都是属于输入框的,如果限制了高度,那很有可能会导致下方的helper文本显示不出来。也就是说,它不会根据你的高度约束自动调节内部控件大小。这很不利于使用IB拖控件的方式

总结:这个控件还是有少许坑的,使用需多注意

MDCButton

第4种不支持

这个MD风格的按钮,同样在IB上不能正常显示。如果不设置样式,那运行的时候这个按钮看上去就跟原生的一模一样。设置样式:

- (void)applyContainedThemeWithScheme:(nonnull id<MDCContainerScheming>)scheme;

MDCContainerScheming包含了颜色配置MDCSemanticColorScheme,布局配置MDCTypographyScheme和形状配置MDCShapeScheme三种。可以自行根据需要进行设置,组合成自己想要的风格

要使用key认证的话,首先要确认git remote的地址为ssh地址。https地址仅支持用户名密码认证,这点在Xcode里面体现为push的时候没有SSH Key选项

然后就是将key放到~/.ssh目录中,权限修改成600,这样命令行中的git就可以使用Key进行认证了

如果要用Xcode直接push/pull的话,还需要提供对应的公钥,名称以私钥后面加.pub,提交的时候会让你进行选择。为了方便起见,可以和私钥一起都放在.ssh目录下。

配置完成后,即可通过Key连接git服务器

在用户主目录下如果存在.bash_profile则进行编辑,不存在则创建一个

然后将命令放到里面,一行一个,比如说:

alias ll='ls -la'

最后执行 source ~/.bash_profile即可

注意,不要改~/.bashrc,这个文件在MAC上是没有效果的

本次趟地雷来源: https://blog.csdn.net/w359593616/article/details/50345109 。吐槽:这位兄台的排版实在是难以令我接受,只能将就着看看。我将这位兄台的文字重新排版一下,并且加入我在编译和调试的过程中 趟过的雷尽数标出

前言

我所使用的编译系统为Ubuntu 14.04.2。考虑到AllWinner A20的rom也是上古时代的产物了,用18.04可能需要重新配置很多东西,为了避免一些不必要的麻烦,故选择了这个版本的系统。

在系统位数选择上,推荐使用64位系统。当然也可以使用32位系统,不过会有一些限制,比如说 12.04 的32位系统默认最大支持8个cpu核心(8c16t只能利用8个核心),内存大小也有限制,不能进行打包等等。之前我就是因为盲信rom是32位的,就应该用32位的ubuntu进行编译,结果到后面编译成功后准备打包的时候发现打包程序居然是个64位的程序。。。

搭建编译环境

安装必要的依赖

下面是基础的依赖:

root@ubuntu: ~# sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev  gcc-multilib  g++-multilib  libc6-dev-i386  lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip
root@ubuntu: ~# sudo apt-get install bison texinfo u-boot-tools flex libswitch-perl

链接一个so文件,不链接好像也没啥问题:(32位系统可能不需要这个操作)

sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

安装JDK 1.6

不要问为什么要jdk1.6,没有为什么,就是需要jdk1.6

这个jdk1.6也是相当古老了,在Oracle网站上找起来很费劲,不过在另外一篇博客的文章里找到了下载链接:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html#jdk-6u41-oth-JPR

下载下来的文件是个bin文件,这里以 jdk1.6.0_45 为例,添加执行权限后直接在终端中执行,jdk会被解压到当前目录中,接下来就是把它放到一个找得到的位置,比如/usr/lib/jvm/jdk1.6.0_45,修改权限为755,所有者和所有人群组为root

然后修改/etc/profile,追加以下内容到文件末尾。注意:只要改profile即可,不要去修改/etc/environment,因为这个 environment 万一修改出错会导致开机卡登录界面,tty中找不到某些命令等问题(本质上是PATH路径损坏),修复起来会很麻烦

export JAVA_HOME=/usr/lib/jvm/jdk1.6.0_45
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/:$JRE_HOME/lib:$CLASEEPATH

请不要照抄那位兄台的export,要抄也要抄我提供的。因为他的排版格式问题,导致export后面的空格存在异常,不能被shell识别

接下来配置java,全程root权限执行:

#!/bin/bash
JAVA_PATH=/usr/lib/jvm/jdk1.6.0_45
update-alternatives --install /usr/bin/java java $JAVA_PATH/bin/java 300
update-alternatives --install /usr/bin/javac javac $JAVA_PATH/bin/javac 300
update-alternatives --install /usr/bin/jar jar $JAVA_PATH/bin/jar 300
update-alternatives --install /usr/bin/javah javah $JAVA_PATH/bin/javah 300
update-alternatives --install /usr/bin/javap javap $JAVA_PATH/bin/javap 300
update-alternatives --install /usr/bin/javadoc javadoc $JAVA_PATH/bin/javadoc 300
update-alternatives --config java
update-alternatives --config javac
ln -s $JAVA_PATH/bin/jar  /bin/jar
ln -s $JAVA_PATH/bin/java  /bin/java
ln -s $JAVA_PATH/bin/javac  /bin/javac
ln -s $JAVA_PATH/bin/javah  /bin/javah
ln -s $JAVA_PATH/bin/javadoc  /bin/javadoc

配置Swap分区

为了保证能成功编译,需要调整swap分区的大小。

以M为单位查看swap的大小

free -m

在当前用户home目录创建一个2GB大小的swap文件

dd if=/dev/zero of=~/swapfile bs=1024 count=2000000

建立交换分区

mkswap ~/swapfile

转化并激活swap分区文件

swapon swapfile

取消分区

swapoff ~/swapfile

替换gcc和g++

更新:咨询了厂商,得到的回复是14.04中不需要替换!替换之后反而会出现各种编译不过去的问题,所以这个到底要不要替换,看个人,可以多尝试尝试,记得做好备份,万一不行可以回档重来

gcc和g++版本问题,需要降为4.4 (不知道是否必须要这样做,反正先这样做着),下载完成之后替换系统原有的链接至4.4的版本

apt-get install gcc-4.4
apt-get install g++-4.4
cd /usr/bin
mv gcc gcc.bak
ln -s gcc-4.4 gcc
mv g++ g++.bak
ln -s g++-4.4 g++
# 查看两者版本
gcc -v
g++ -v

最后还需要安装:

apt-get install g++-4.4-multilib
apt-get install libc6-dev-i386

下载源码

我这边源码是合作厂商基于AllWinner A20的源码定制过后的版本,不过和网络上流传的版本基本一致,源码中分为android文件夹和lichee文件夹两个目录。

开始编译

编译lichee

这里有个小技巧,在改动必要文件之后,开始编译之前,利用git命令创建个本地仓库,将所有文件添加进版本控制。万一编译出了什么问题,可以通过git将文件夹中的内容完全重置回最初的状态,这样就省的去clean的工作了

接下来开始编译:

cd lichee
./build.sh -p sun7i_android

中途过程中可能会跳出若干选项,比如选择wifi驱动,3g/4g模块驱动等,按照实际需求进行选择即可

若看到以下输出,即表示lichee编译成功:

INFO: build u-boot OK.
INFO: build rootfs ...
INFO: skip make rootfs for android
INFO: build rootfs OK.
INFO: build lichee OK.

编译android

进入源码的另一个目录android,然后执行以下命令:

cd android
source build/envsetup.sh

注意,不要直接执行 ./build/envsetup.sh,据说会有问题

lunch
admin@ubuntu:android$ lunch

You're building on Linux

Lunch menu... pick a combo:
     1. full-eng
     2. full_x86-eng
     3. vbox_x86-eng
     4. full_mips-eng
     5. full_grouper-userdebug
     6. full_tilapia-userdebug
     7. mini_armv7a_neon-userdebug
     8. mini_armv7a-userdebug
     9. mini_mips-userdebug
     10. mini_x86-userdebug
     11. full_maguro-userdebug
     12. full_manta-userdebug
     13. full_toroplus-userdebug
     14. full_toro-userdebug
     15. sugar_evb-eng
     16. sugar_ref001-eng
     17. sugar_standard-eng
     18. wing_evb_v10-eng
     19. full_panda-userdebug

Which would you like? [full-eng]

根据自己开发平台选择方案,接下来的操作是 “拷贝内核和模块到Android中”,据传编译内核 一般需要接近1个小时???完成后将会在out/target/product/sun7i-xxx/目录下生成boot.img、recovery.img、system.img三个文件镜像。Boot.img包括kernel和ramdisk,system.img为系统文件

extract-bsp
make clean
make -j8

如果编译环境没有什么大的问题的话,应该就能编译成功。如果出现make提示源码中有什么东西找不到,请先确认源码是否完整,其次就是编译环境问题了。如果提示少了什么依赖,就按照提示安装即可

打包镜像

用pack命令打包出编译好的镜像文件

pack

完成后会提示你,出来的镜像文件是保存在哪里的

编译android过程中出现的各种问题

make: *** No rule to make target `out/target/product/sugar-ref001/obj/STATIC_LIBRARIES/libv8_intermediates/export_includes', needed by `out/target/product/sugar-ref001/obj/SHARED_LIBRARIES/libwebcore_intermediates/import_includes'.  Stop.

这就是降级了gcc和g++后使用多线程编译可能会出现的奇葩问题。这种情况下,使用单线程make不会有这个错误。如果不嫌编译慢,可以慢慢等。


Can't Locate Switch.pm in @INC (you may need to install the Switch module) (@INC contains: /etc/perl /usr/local/lib/perl/5.18.2 /usr / Local/share/perl/5.18.2 /usr/lib/perl5 /usr /share/perl5 /usr/Lib/perl/5.18 /usr /share/perl/5.18 /usr/Local/lib/site_ perl .) at external/webkit/Source/WebCore/make -hash- tools.pl line 23.
BEGIN failed-- compilation aborted at external/webki t/Source /WebCore /make-hash- tools.pl line 23.
target Generated: libwebcore <= external/webkit/ Sour ce/WebCore / dom/make_ names. pl
make: *** [out/target/product/sugar-ref001/obj/STATIC LIBRARIES/libwebcore intermediates/Source/WebCore/html/DocTypestr ings.cpp] Error 2

缺少了 libswitch-perl ,安装上即可解决问题


external/dbus/bus/activation.c:26:20: fatal error: config.h: No such file or directory
compilation terminated.

这个还是编译环境问题,具体是什么情况我也没搞清楚

环境:两块机械硬盘组LVM,500GB+1TB的配置;一块nvme固态硬盘安装了windows10,系统重新安装为:Ubuntu 18.04 Desktop

最近因为主机重新配置,需要重装系统,然而在重装系统之前,没有进行lvm配置备份,结果安装完毕后发现悲剧了,系统找不到lvm卷。

慌张了几秒后开始冷静思考:我只是在nvme固态上重新安装了系统,并没有动lvm卷的硬盘,所以理论上应该是可以恢复的。 然后开始搜索怎么来恢复它,结果还真被我找到了:

桌面级的ubuntu默认不带lvm,所以要先安装lvm:sudo apt install lvm2

用pvscan或者pvdisplay看看pv还在不在:

root@ubuntu:~# pvscan
  PV /dev/sdb1   VG lvmdata         lvm2 [<931.51 GiB / 0    free]
  PV /dev/sdc1   VG lvmdata         lvm2 [<465.76 GiB / 996.00 MiB free]
  Total: 2 [1.36 TiB] / in use: 2 [1.36 TiB] / in no VG: 0 [0   ]

root@ubuntu:~# pvdisplay
  --- Physical volume ---
  PV Name               /dev/sdb1
  VG Name               lvmdata
  PV Size               931.51 GiB / not usable 4.69 MiB
  Allocatable           yes (but full)
  PE Size               4.00 MiB
  Total PE              238466
  Free PE               0
  Allocated PE          238466
  PV UUID               wr9hSs-arh6-1kcE-NcDa-1PaT-J1de-ab4d0k

  --- Physical volume ---
  PV Name               /dev/sdc1
  VG Name               lvmdata
  PV Size               465.76 GiB / not usable <3.01 MiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              119234
  Free PE               249
  Allocated PE          118985
  PV UUID               Ql5uAu-CwSO-xjM8-A8z7-toY1-E7GQ-QEUBRy

这个结果表示pv还在,接下来来看看vg还在不在:

root@ubuntu:~# vgscan
  Reading volume groups from cache.
  Found volume group "lvmdata" using metadata type lvm2

root@ubuntu:~# vgdisplay
  --- Volume group ---
  VG Name               lvmdata
  System ID
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  5
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               1.36 TiB
  PE Size               4.00 MiB
  Total PE              357700
  Alloc PE / Size       357451 / 1.36 TiB
  Free  PE / Size       249 / 996.00 MiB
  VG UUID               qJKMJQ-B9Wg-ieJw-th3d-IOUZ-KhLW-OTePci

不错,vg没有丢失,接下来来重新激活它:

root@ubuntu:~# vgchange -ay
  1 logical volume(s) in volume group "lvmdata" now active

接下来检查,是否出现了lvm:(我的lvm group名字叫lvmdata)

root@ubuntu:~# ls -l /dev | grep lvmdata
drwxr-xr-x  2 root root          60 3月  30 16:56 lvmdata

接下来就是用mount命令挂载上去就可以了:

root@ubuntu:~# mount /dev/mapper/lvmdata-xx /mnt/lvm

因为我只在lvm上面建立了一块分区,所以在/dev/mapper下只能看到一个设备节点,找个目录挂载下就可以继续访问之前的数据了

Linux真他么坑爹,配置个dns,到处都是配置,你还不知道应该配置哪个才有效。

之前我的ubuntu 18.04 server配置成了dsl-provider直接进行pppoe拨号上网的,改用路由器进行dhcp之后,就出现了各种问题,先是不知道怎么停掉pppoe拨号,接着就是dns时不时的给你故障一下(真是B了狗了)

pppoe那个问题好解决的,直接修改/etc/network/interfaces文件,把里面的关于dsl-provider的都注释掉,然后 /etc/init.d/networking restart 即可

为了保险起见,同时修改了/etc/netplan/xxxxxxx.yaml配置文件:(ens5改成你自己的)

network:
 version: 2
 renderer: networkd
 ethernets:
  ens5:
  Addresses: []
  dhcp4: true
  optional: true

关于dns,下面是从网上搜集而来的各种办法:

最后,终于通过这个方式解决了:

  • /etc/resolv.conf,这是一般修改的文件,但这次改了以后,重启系统后又被改回去了。系统提示该文件是由networkmanager创建的。
  • /etc/systemd/resolved.conf,是resolv服务的配置,改了以后重启服务,好像没啥变化。
  • /run/resolveconf/resolv.conf,有人说是/etc/resolv.conf的连接指向文件,但我的系统没有。
  • dnsmasq,虽然系统安装了,但是配置都是空的,应该没有作用。
  • netplan,这是Ubuntu 18.04的主流配置,大部分人(大概)通过这个进行dns配置就应该能起作用,可惜在我的机器上无效,这很奇怪,不知道改坏了什么,居然不起作用
  • 通过/etc/network/interfaces,在它的最后增加一句:

    dns-nameservers 8.8.8.8     (复制就好,很多人拼写错误)。。。这个好像也不起作用

编辑 /etc/systemd/resolved.conf 这个文件:

[Resolve]
DNS=<用dns地址替换这个等号的右边内容>

重启下 systemd-resolved服务 就ok了😓

VMware Player现在版本已经更新到15了,说说目前的使用体验。

VMware Player不知道从什么版本开始改名成VMware Workstation Player了(也许是战略调整?),对于个人非商业用途依旧是免费使用,所以可放心下载,在安装完成的界面和workstation pro一样有一个输入许可证的按钮,可以无视之。打开程序之后选择个人非商业用途,即可无需许可证序列号,程序标题栏中也会有“仅用于非商业用途”的字样。

VMware Player中相比workstation pro,少了很多很多功能,以下为我探索到被阉割的功能:

  • 快照。这个功能很鸡肋,从产品的定位角度来看,被阉割了也正常
  • 虚拟网络编辑器。该功能用于创建/修改/删除vmware的网络适配器,一般来说也不太会用到这个功能。多网卡等高级玩法可能会用到它
  • 虚拟化物理机,连接服务器,映射虚拟磁盘等。这些个功能在workstation pro中位于“ 文件 ”菜单下,除了个“ 映射虚拟磁盘 ”还有点用处之外,其余的基本也不会去碰的
  • 虚拟机的选项中的客户机隔离,访问控制,自动保护,还有高级选项(更改固件类型,UEFI还是BIOS,调试信息,进程优先级等)等。其中固件类型这个挺有用的功能被阉割了还是挺可惜的。之前做了一个UEFI引导的Ubuntu,结果发现没有地方设置虚拟机为UEFI导致开不了机,只得作罢
  • 可能还有很多,就不一一列举了

有些功能看似被阉割掉了,但其实还是存在的,比如说:

  • 使用物理磁盘。在创建虚拟的时候,没有使用物理磁盘的选项,但是可以在创建完虚拟机之后再编辑它,移除之前创建的虚拟磁盘,再添加磁盘,这个时候就可以选择使用物理磁盘了

如果只是用它来玩玩虚拟机,不涉及高级功能的话,VMware Player已经可以满足需求了。但如果像我这样玩转物理磁盘的,Ubuntu to go的,还是得上workstation pro

在Windows下,jvm默认是使用GBK的,这会导致使用utf-8的jar文件调用输入输出方法,尤其是写文件的时候出现乱码的情况。

为了避免乱码的出现,现汇总一下办法:

  1. 大部分方法是修改IDE/项目配置的。这个适用于有源代码的情况,对于只有一个jar文件来说不适用;
  2. 直接修改cmd的代码页为65001,即UTF-8,可修复乱码问题。这个确实是可以的,但是存在几个问题:首先是其他程序可能使用该代码页会出现乱码情况(GBK?UTF-8?),其次是cmd不支持UNC路径,即网络路径。为了支持UNC路径,你得使用powershell
  3. 在cmd中执行 java -Dfile.encoding=UTF-8 -jar .\xxxx.jar。这个也是一种可行的方案。正如上面一点所述,cmd不支持UNC路径,所以如果要在网络路径下执行,还是得用powershell,但是,powershell中似乎执行会出错,提示:错误: 找不到或无法加载主类 .encoding=UTF-8
  4. 这个方法是修改环境变量,在环境变量中增加一条环境变量配置:变量名为: JAVA_TOOL_OPTIONS ,变量值为:-Dfile.encoding=UTF-8。再次启动时jvm就会默认先改变初始化字符集为UTF-8,既解决了乱码问题,同时也可以正常使用powershell,是比较推荐的一种做法

准备工作

在开始前,需要准备好下面这些东西:

开始编译

生成 standalone toolchains

这个freetype也是比较坑的,如果直接使用下载下来的ndk中prebuild目录里面提供的gcc,会报各种奇怪的错误。能力有限,不能一个一个的去研究是怎么回事,那就弄个standalone的toolchains出来

进入到下载解压好的ndk目录中,找到build/tools/make-standalone-toolchain.sh 。这个脚本就是帮助构建standalone的toolchain用的。可以看一下它的帮助信息:

root@ubuntu:/home/mkxx/android-ndk-r17c/build/tools# ./make-standalone-toolchain.sh --help                                                                                                                  
HOST_OS=linux                                                                                                                                                                                               
HOST_EXE=                                                                                                                                                                                                   
HOST_ARCH=x86_64                                                                                                                                                                                            
HOST_TAG=linux-x86_64                                                                                                                                                                                       
HOST_NUM_CPUS=4                                                                                                                                                                                             
BUILD_NUM_CPUS=8                                                                                                                                                                                            
Usage: make-standalone-toolchain.sh [options]                                                                                                                                                               
                                                                                                                                                                                                            
Generate a customized Android toolchain installation that includes                                                                                                                                          
a working sysroot. The result is something that can more easily be                                                                                                                                          
used as a standalone cross-compiler, e.g. to run configure and                                                                                                                                              
make scripts.                                                                                                                                                                                               
                                                                                                                                                                                                            
Valid options (defaults are in brackets):                                                                                                                                                                   
                                                                                                                                                                                                            
  --help                   Print this help.                                                                                                                                                                 
  --verbose                Enable verbose mode.                                                                                                                                                             
  --dryrun                 Unsupported.                                                                                                                                                                     
  --toolchain=<name>       Specify toolchain name                                                                                                                                                           
  --use-llvm               No-op. Clang is always available.                                                                                                                                                
  --stl=<name>             Specify C++ STL [gnustl]                                                                                                                                                         
  --arch=<name>            Specify target architecture                                                                                                                                                      
  --abis=<list>            No-op. Derived from --arch or --toolchain.                                                                                                                                       
  --ndk-dir=<path>         Unsupported.                                                                                                                                                                     
  --package-dir=<path>     Place package file in <path> [/tmp/ndk-]                                                                                                                                         
  --install-dir=<path>     Don't create package, install files to <path> instead.                                                                                                                           
  --dryrun                 Unsupported.                                                                                                                                                                     
  --platform=<name>        Specify target Android platform/API level. [android-14]                                                                                                                          
  --force                  Remove existing install directory.

编译toolchain的时候,建议打开verbose开关,可以方便的看到具体出错信息。 以arm64平台为例:

root@ubuntu:/home/mkxx/android-ndk-r17c/build/tools# ./make-standalone-toolchain.sh --platform=android-21 --install-dir=/home/mkxx/ndk-r17c-standalone --arch=arm64 --verbose                               
HOST_OS=linux                                                                                                                                                                                               
HOST_EXE=                                                                                                                                                                                                   
HOST_ARCH=x86_64                                                                                                                                                                                            
HOST_TAG=linux-x86_64                                                                                                                                                                                       
HOST_NUM_CPUS=4                                                                                                                                                                                             
BUILD_NUM_CPUS=8                                                                                                                                                                                            
## COMMAND: python ./make_standalone_toolchain.py --arch arm64 --api 21 --stl gnustl --install-dir=/home/mkxx/ndk-r17c-standalone                                                                           
WARNING:__main__:gnustl is deprecated and will be removed in the next release. Please switch to libc++. See https://developer.android.com/ndk/guides/cpp-support.html for more information.                 
Toolchain installed to /home/mkxx/ndk-r17c-standalone.

注意事项

  • –arch接受的参数在r17c中只有arm,arm64,x86,x86_64 这四个 ,而且不能同时指定多个
  • 如果–arch指定的是arm64,则–platform至少要为android-21,否则会报错: xx is less than minimum platform for arm64 (21)
  • 若想要多个架构,最好指定不同的路径,分多次进行处理;使用–force参数后,原有路径会被删除
  • 如果提示找不到python, 可以通过apt install python命令解决(注意不是python3 )

编译Freetype

在开始前,需要安装几个依赖:(可能还不止这几个)

apt install libtool autoconf automake

把源码包下载下来后解压,然后执行目录中的autogen.sh

root@ubuntu:/home/mkxx/freetype-2.9# ./autogen.sh 
generating `configure.ac'
running `aclocal -I . --force'
running `libtoolize --force --copy --install'
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './config.guess'
libtoolize: copying file './config.sub'
libtoolize: copying file './install-sh'
libtoolize: copying file './ltmain.sh'
libtoolize: Consider adding 'AC_CONFIG_MACRO_DIRS([m4])' to configure.ac,
libtoolize: and rerunning libtoolize and aclocal.
libtoolize: Consider adding '-I m4' to ACLOCAL_AMFLAGS in Makefile.am.
running `autoconf --force'

接下来编写编译脚本,此处使用arm64:

#!/bin/sh

NDK=/home/mkxx/ndk-r17c-standalone
PLATFORM=aarch64-linux-android

export CC="$NDK/bin/aarch64-linux-android-gcc"
export CXX="$NDK/bin/aarch64-linux-android-g++"
export AR="$NDK/bin/aarch64-linux-android-ar"
export LD="$NDK/bin/aarch64-linux-android-ld"
export STRIP="$NDK/bin/aarch64-linux-android-strip"
export CFLAGS="-fPIE -fpie"

./configure \
--prefix="/home/mkxx/libfreetype2" \
--without-zlib \
--with-sysroot=$NDK/sysroot \
--host="$PLATFORM"

如果没有看到明显的输出错误,就可以继续make & make install了

root@ubuntu:/home/mkxx/libfreetype2# ls -la
total 0
drwxr-xr-x 1 root root  36 Oct 16 07:30 .
drwxr-xr-x 1 root root 156 Oct 16 07:30 ..
drwxr-xr-x 1 root root  30 Oct 16 07:30 bin
drwxr-xr-x 1 root root  18 Oct 16 07:30 include
drwxr-xr-x 1 root root 100 Oct 16 07:30 lib
drwxr-xr-x 1 root root  20 Oct 16 07:30 share

至此,freetype for android编译成功

解决方案参考: https://forum.xda-developers.com/pixel-c/help/device-resource-busy-t3449240

正常将只读的/system分区变成可读写是用下面这个命令:

mount -o remount,rw /system

一般情况下,/system就变成可读写了。但是在某些设备上,会提示Device or resource busy错误。这个时候只需要将-o的两个参数顺序调换一下即可,也就是这样:

mount -o rw,remount /system