Category Archives: cmake

用 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 … Continue reading

Posted in cmake | Tagged | Leave a comment

My CMake Tutorial 5

这篇是教你如何用cmake和pkg-config搅基。 关于这个系列的宗旨,就是用我写过的项目里面用的那屁点CMake给大家看看,有些技巧我可能还自鸣得意,很有和大家分享的冲动。你想要找以前的文章,就去点下分类里面的cmake就好。 cmake 内置了 pkgconfig支持,想要用的话只需要 find_package(PkgConfig) 里面内置的命令是这样的 pkg_check_modules(LIBPINYIN “libpinyin >= 0.5.0”) 前面是变量名的前缀,一般来说会生成以下变量 <VAR>_FOUND,<VAR>_INCLUDE_DIRS,<VAR>_LIBRARY_DIRS,<VAR>_LIBRARIES。 这就是通常的用法,非常的简单。 以下是我常用的trick之一,实际上是用了一个内部命令,不过实在太好用了。 _pkgconfig_invoke(“libpinyin” LIBPINYIN EXECPREFIX “” “–variable=exec_prefix”) 简单来说,就是在pkgconfig的文件中经常会有定义一些变量,不过不幸的是CMAKE并没有直接获得这些变量的方法,于是就用了以上的手段。 具体参数是,pkgconfig配置名,变量前缀,变量名,空字符串,pkgconfig参数。 这样就可以顺利得到LIBPINYIN_EXECPREFIX这样的变量名啦。  

Posted in cmake | Tagged | 5 Comments

My CMake Tutorial 4

这篇的目的是教你 CMake 如何和 Qt 搅基。 总所周知的是,CMake和Qt自古就搅基搅的很深,CMake自带的find_package脚本其实蛮少,不过其中确绝对会有 Qt 的和KDE的,即使所引用的KDE的cmake脚本其实在KDE Libs里面。 说是介绍,其实主要是介绍一些在QtMacro.cmake里面的宏,cmake的自带脚本都在 /usr/share/cmake-<version>/Modules 下面,可以自行查看。 在开始之前,先来说说Qt的moc。Qt的信号和槽的机制其实大部分是靠代码生成的,Qt自带了一个名为moc的工具,负责解析C++的源文件,并且生成相关的代码。moc是meta object compiler 的缩写,关于moc都干了什么可以自己放狗去搜。 qt4_wrap_cpp(<varname> <header file(s)>) 用来把头文件生成moc文件,并且对应的文件名写到<varname>里面去。 这样你可以在增加target的时候直接使用<varname>和你的cpp文件,这样就可以一起编译了。 当然对于KDE来说,有更方便的automoc,这里按下不表。 Qt DBus DBus 的接口是通过xml文件指定的,qt也提供了按照DBus的introspect的xml文件直接生成代码的方法,具体来说有两边,一个是adaptor,一个是interface。adaptor是作为实现dbus那一方的,而interface则是调用dbus那一方的。 https://github.com/fcitx/kcm-fcitx/blob/master/src/CMakeLists.txt 例如这里 QT4_ADD_DBUS_INTERFACE(kcm_SRCS     org.fcitx.Fcitx.InputMethod.xml     org.fcitx.Fcitx.InputMethod ) 最后就会生成 org.fcitx.Fcitx.InputMethod.h 这个文件,然后直接include就可以直接使用这个类啦。 类似的adaptor则是相当于注册服务的那一方。

Posted in cmake | Tagged | 3 Comments

My CMake Tutorial 3

我的风格其实极其诡异,因为我只想讲我乐意讲的,但保证实用性,除了第一次的类hello world,全部脚本都在实际项目中使用(当然很多是fcitx的 😛 )。学习曲线什么的,谁管啊。 如果你想找前面的内容,请猛击 https://www.csslayer.info/wordpress/category/cmake/ 顺带一提,本人近期一直占据oholh cmake 语言提交 http://www.ohloh.net/languages/74 排行中的一名。(有段生猛的时间也挤进过C语言的排名……不过现在出来了 :P) 本次大容量,包括三个内容,创建自己的可以被find_package使用的CMake脚本,复杂自定义文件生成,Gettext整合。

Posted in cmake | Tagged | 3 Comments

My CMake Tutorial 2

其实我的感觉是大家都被我第一篇给蒙骗了……从第二篇开始我就要开始走非主流路线。 如何 make uninstall cmake是没有make uninstall支持的。 你可能觉得很无语。不过还是有方法的,这个方法也被应用于fcitx的每个项目当中。另外如果你使用KDE的话 – find_package(KDE4) – 那么KDE也会自动提供uninstall,不用你麻烦了。 那么现在来看看这是怎么实现的。 在make install的时候,cmake会生成一个文件 install_manifest.txt ,里面是要安装的文件。而uninstall的基本思想就是读他,然后把里面列出的文件删掉。 一般而言我会这么做,新建一个文件夹叫cmake,然后在里面放上以下内容的文件,命名为cmake_uninstall.cmake.in。 if (NOT EXISTS “@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt”)     message(FATAL_ERROR “Cannot find install manifest: \”@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\””) endif(NOT EXISTS “@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt”) file(READ “@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt” files) string(REGEX REPLACE “\n” “;” files “${files}”) … Continue reading

Posted in cmake | Tagged | 3 Comments