用 CMake target 来管理依赖库

虽然有越来越多的包提供 CMake config 了,时常还是需要手写一个。但是如果你还活在 cmake 2.8 的时代, 你可能浪费了很多的精力在不必要的地方。

简单来说,如果你还在写 include_directories,link_directories 来给你的依赖添加找头文件和库的目录,那么你大概已经 OUT 了。

比较现代的一种方式是,用 Target 来管理依赖的库的一切。最早我是从 Qt5 的 cmake 那里学到的。简单来说,就是通过 add_library([Library] [TYPE] IMPORTED]) 来把你依赖的库变成一个 cmake target。同时这个 target 就自带了 include_directories 的属性和 library 自身路径。

那么可以来看看一个我写的新 libintl 的例子:https://github.com/fcitx/fcitx5/blob/master/cmake/FindLibIntl.cmake

精髓就是在最后这里:

if(LIBINTL_FOUND AND NOT TARGET LibIntl::LibIntl)
 if (LIBINTL_LIBRARY)
 add_library(LibIntl::LibIntl UNKNOWN IMPORTED)
 set_target_properties(LibIntl::LibIntl PROPERTIES
 IMPORTED_LOCATION "${LIBINTL_LIBRARY}")
 else()
 add_library(LibIntl::LibIntl INTERFACE IMPORTED )
 endif()
 set_target_properties(LibIntl::LibIntl PROPERTIES
 INTERFACE_INCLUDE_DIRECTORIES "${LIBINTL_INCLUDE_DIR}"
 )
endif()

也就是说,如果你在你的项目上 target_link_libraries([YourTarget] LibIntl::LibIntl),它就会自动在编译和链接时找到库和头文件,再也不用写 include_directories(…) 了。

上面还有用到了一个

 add_library(LibIntl::LibIntl INTERFACE IMPORTED )

通过这个来表示这个 library 是纯头文件的库。对于很多模板库,或者 libc 内置的情况来说是很有用的。

对于多 pc 文件的库,例如 cairo 来说,把它用 package + component 的方式来表示有时会很方便。这里可以请出 KDE 写的 extra-cmake-modules。里面自带的 FindXCB.cmake 可以作参考。

这里有一个我写的 Cairo 的实例:https://github.com/fcitx/fcitx5/blob/master/cmake/FindCairo.cmake

find_package(Cairo COMPONENTS Cairo XCB EGL)

使用时可以这样,是不是看起来就很高端大气上档次。实际 link 时就只要 target_link_libraries([Target] Cairo::XCB) 就可以了。

实际上,这样引入的 Tagert 也并不只有这一些属性,甚至可以直接指定依赖时需要使用的 C++ 标准之类。

另一方面,如果你想要在编译时支持 third_party 可以使用系统库,或者使用 bundle 的 source,这个方式就可以在不改变你自己 target 的 CMakeLists.txt 的前提下,更加方便的自动变换。

希望有更多的库使用这种方式直接提供 Find[Package].cmake 呢。

另外实际上,如果你采用 cmake 自动 export 的方式,也可以直接获得这样的效果。暂且挖一个坑,下一次再来说一下 install(EXPORT …) 的故事。

Posted in cmake | Tagged | Leave a comment

讲个有意思的事。

不要奇怪为什么在这个分类下面。这是一个 fcitx 躺枪的故事。

Continue reading

Posted in fcitx development | Leave a comment

最近买的最满意的笔记本

其实就是这个 Thinkpad X1 yoga 了。在这之前,其实也经历了不少笔记本……

最早最早的联想天逸……忘了型号。Gateway I43…Asus Zenbook UX31E,Dell XPS 13 老版本,Ideapad yoga 2 pro,Surface Pro 4……回想起来会觉得太败家了……幸好 Surface Pro 4 是卖了个  6 折回血。

总之之前的都各有各的问题。最早的当然都是沉啦。后来就有了超级本,就不想回到砖头了。

Asus 的问题是妈逼电源线插头太脆弱了,老断啊,断了买了新电源再断,感觉哪天就要被电死了。

Dell 没买一个月换了主板……虽然之后就一直用了,后来给老婆用去了用到现在,但是 wifi 似乎也是有毛病的,而且分辨率是比较惨的 1366×768,之前的 asus 是 1600×900 都能看出明显差距了。

所以后来为了分辨率和屏幕弄了 yoga 2 pro,基本是不错,不过蓝牙和 wifi 同时使用网速网络质量都会大幅下降,家里路由器距离远一些就会经常突发慢到暴走。

后来一时鬼迷心窍看了 M$ 发布会之后想要 SP4。Surface Pro 4 主要是驱动问题,严重的问题……M$ 去掉了待机,然而 Linux 不支持 connected standby,但是换用休眠经常唤醒不能。另外就是 wifi 经常时不常死掉, https://bugzilla.kernel.org/show_bug.cgi?id=109681 最开始我汇报到今天都一年多了……一个小时就要重启电脑也是受不了的。

然后,终于让我遇见了 Linux 驱动都没问题的……这台 Thinkpad X1 yoga。wifi 没问题,wwan 没问题,触摸屏没问题,笔也没问题,待机没问题 ´_>` 这么多年就没遇见这么一个没问题的电脑了。感觉之前都活着什么样的地狱里面……

Posted in Linux | Tagged , , , | 6 Comments

DLNA 大法好,蓝牙转发大法也好

笔记本上的视频懒得四处复制了再看,于是 DLNA 拯救你,ps3 media server 一开,找个播放器看就是了…最简易的方案,用 VLC 就好,Android,Sailfish (也是 Android 的 App 啦,毕竟能跑的程序相对有限),Linux 都可以。

因为平时还抢了老婆的 iPhone 用…所以 iPhone 上也费劲找了个播放器。而且果然是付费的靠谱…否则解码都成问题…

耳机只能配两个设备,自己手机一个,笔记本一个,想换配对设备还要进配对模式重新搞,怎么办…iPhone 蓝牙转发到笔记本上……于是就这么凑合着连了三个设备。

不过延迟就比较悲剧,凑合用呗。反正都是为了方便床上看……

Posted in Linux | 4 Comments

休闲玩家的「口袋妖怪·走」的入门心得

总之 Pokémon Go 也是开服几天了,赶时髦玩了一玩,总之是勾引宅男出门锻炼的好游戏。这游戏的教学系统不可谓不烂,进去之后几天下来走了不少弯路,那么记录一下也许可以帮助其他人。

1、精灵捕捉

你以为的 pokemon go 是这样的:

CnPyrCjWYAAYfOa

其实是这样的:

CnNBjtPUEAAstJL

但是不要小看拉达和波波。游戏中等级是十分重要的,升级的途径是获得经验。而获得经验的途径有以下几种:

  • 捕捉精灵(100exp + 10exp 取决于扔球姿势)
  • 获得新精灵图鉴(500exp)
  • 对战(胜利一次好像是100?)
  • 进化(500exp)
  • pokestop(50exp)

进化需要获得这个精灵家族的糖果,糖果的获得方式是:

  • 捕捉(3)
  • 孵化(10-25,可能取决于种类)
  • 放走(说明是传送给博士,1)

拉达进化需要 25,比比鸟进化需要 12。而进化比雕需要 50。想要刷经验的话,拼命捕捉波波和拉达就可以获得大量经验,可不要忽视了。

对战获得的经验其实不是非常可持续性,因为并没有自动回血/复活这样的设定。

另外坐在原地是几乎不可能刷新精灵的,除非周围有人用 lure module 或者自己使用吸引精灵的道具。

我曾经尝试原地并使用吸引精灵的道具,30分钟的时间内只有 4 只,lure module 我坐在原地刷新则奇快。

2、道具

pokestop 刷新时间其实极短(几分钟),找到有多个 pokestop 聚集的地点可以快速刷道具和经验。

hp 0 只能复活,然而这时如果对气绝的精灵使用 power up 则会增加 hp 反而直接活过来,则不能使用复活药回血。复活药回血有时更加划算(50% hp),精灵血多(hp > 40)的时候优先复活,否则优先升级。

3、对战

打不过就跑是很重要的,即使跑了也可以获得经验,而不用浪费 hp 在打不过的精灵上。

4、技能

我查了半天才发现必杀技能是长按释放(未测试)。攻击需要使用加藤鹰之指拼命点屏幕。每种技能频率好像不同,有些频率快的技能(大概多是低攻击力的?)需要拼命点屏才能获得高伤害。闪避躲必杀可能才比较划算。

精灵进化之后技能是会再随机刷新的!获得好技能的未进化精灵大概毫无意义!

技能选择上要注意属性!

5、属性

精灵肯定有个体值差异,并且会影响最大 CP,目前和体重之间的关系不明。然而需要注意的是最大的 CP 也和你自己等级挂钩,所以拼命升级也是很重要的。

不要浪费 Stardust 在低初始 CP 的精灵上,Stardust 是稀缺资源。高初始 CP 的精灵在你高等级之后十分容易刷出。

6、选择精灵

拉达属性实在不够看……比雕还不错,算是初期易于获得的精灵之一,可以容易刷到 500 CP 去战一场。

7、等级的影响

  • 精灵出现种类?似乎有些精灵在我低等级时并不出现。
  • CP 最大值(升一级可以多 power up 1-2 次)
  • 升级赠送道具
  • 野生精灵 CP (我现在很少见到 10 CP 的了……)

8、对战

捡软柿子打,不要浪费 HP 在打不过的人上。例如你有 500 CP 的精灵 1只,其他 5 只都是低 CP,道馆有 200 和 800 的。你打败 200 的就能降低 1000 道馆的进度。每 4000 进度增加一个人。也就是说踢出去一个人,你之后要打的精灵数量就减少。对于我这种当单机玩的人来说是一种节省药品的方式。

刷自己阵营的道馆的空位也可以使用类似方式节省药。占领道馆位置才能刷 20 小时一次的游戏币和 Stardust。

9、阵营选择

本地急冻鸟阵营人最多,从外形上其实可以预测吧,我推测世界上其他地方也是类似…选择人多的还是人少的就见仁见智了。

Posted in 日志 | Tagged | Leave a comment