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整合。

Continue reading

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}")
foreach (file ${files})
    message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
    if (EXISTS "$ENV{DESTDIR}${file}" OR IS_SYMLINK "$ENV{DESTDIR}${file}")
        execute_process(
            COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
            OUTPUT_VARIABLE rm_out
            RESULT_VARIABLE rm_retval
        )
        if(NOT ${rm_retval} EQUAL 0)
            message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
        endif (NOT ${rm_retval} EQUAL 0)
    else (EXISTS "$ENV{DESTDIR}${file}" OR IS_SYMLINK "$ENV{DESTDIR}${file}")
        message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
    endif (EXISTS "$ENV{DESTDIR}${file}" OR IS_SYMLINK "$ENV{DESTDIR}${file}")
endforeach(file)

然后在你的源代码根目录的CMakeLists.txt 里面写上

# uninstall target
configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    IMMEDIATE @ONLY)

add_custom_target(uninstall
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)

就大功告成了。

顺带一提,这里列出的版本比cmake wiki上的好用,大家可以自行对比(http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F

那么原理是什么?就从主文件的CMakeLists.txt 开始吧。首先是 configure_file 命令。熟悉autotools的同学知道,经常有些内容是配置完才能决定的,configure_file就是这样的命令,甚至语法和autotools都一样(采用@扩起需要替换的部分)。

第一个,第二个参数分别是输入和输出文件,考虑和cmake向下兼容性的问题,请使用绝对路径,否则2.6之前的版本是构建根目录,2.8则是相对当前CMakeLists.txt的目录。@ONLY 表示只对使用 @ 括起的变量进行替换。

add_custom_target 则是建立一个自己的target,并且对应的命令为COMMAND后面指定的命令。target的概念熟悉Makefile的人都知道了。

Posted in cmake | Tagged | 3 Comments

围观对岸的输入法小风波

围观而已。

GCIN & HIME

http://moto.debian.tw/viewtopic.php?f=49&t=16373

http://moto.debian.tw/viewtopic.php?f=49&t=16384

估计他们想不到这边还有个坐在几千公里外的fcitx开发者在远处……

Posted in Linux | 8 Comments

fcitx-libpinyin & fcitx-table-extra

其实是前几天才看到有0.3发布了,于是这几天开始完成fcitx-libpinyin,没想到真的和在Twitter上说的一样是3天的事情。目前已经基本完成了,除非要增加额外libpinyin没提供的功能,现在拼音,双拼,以及注音都应该可以正常工作。

代码:

https://github.com/fcitx/fcitx-libpinyin

需要 fcitx-git 的代码(4.2)。

想要使用cloudpinyin的话,也请使用 fcitx-cloudpinyin 的 git 代码(其实也就是增加几个输入法名称判断而已。)。注音不能用 fcitx-cloudpinyin(考虑到用词不同……意义不大)。

fcitx-table-extra

包含了额外码表,需要 fcitx 4.2 (git),因为需要码表新的支持。目前包含郑码(专利已过期),仓颉,和嘸蝦米(专利已过期)。

https://github.com/fcitx/fcitx-table-extra

顺带一提,fcitx-libpinyin实现代码量 1154 行。

嘛,算个fcitx的伪圣诞礼物?开始写的时候可没想这么多……

Posted in fcitx development | Tagged , , , , | 5 Comments

My CMake Tutorial 1

CMake 是一个跨平台的开源构建系统。

1、CMake的诞生

既然维基百科有我就不多说了。

http://zh.wikipedia.org/wiki/CMake

2、为什么要使用CMake

http://lwn.net/Articles/188693/  Why the KDE project switched to CMake — and how

原因之一是跨平台,本来他们想采用 SCons 作为构建系统, 但在跨平台上遇见了许多问题。CMake的优势在于它只依赖于C++编译器,跨平台,可以生成各个平台特定的Makefile和工程文件,并且支持单元测试。

另外一点就是性能,但我一时间找不到具体的引用了。

3、使用CMake的基本方法

mkdir build
cd build
cmake ..
make
make install

针对一般用户来说就是以上内容,和当年的传统 configure make 很像吧?

4、第一个项目

cmake_minimum_required (VERSION 2.6)
project(test)

add_executable(test test.cpp)

cmake项目一开始都需要指定cmake的最低版本,一般来说2.6即可,最新版是2.8.6。第二行制定项目名称,其次就是添加一个可执行文件。源代码是 test.cpp 。这样cmake就会编译生成一个test的可执行文件。

当然一个好习惯是为一堆文件设置一个变量名。

例如:http://code.google.com/p/fcitx/source/browse/src/core/CMakeLists.txt

 set(FCITX_SOURCES
     fcitx.c
     errorhandler.c
 )

设置了一个名为FCITX_SOURCES的变量,引用

上面的链接中还出现了一些新命令,那么我们也来一一解释:

install(TARGETS fcitx RUNTIME DESTINATION ${bindir})

将 target fcitx安装到 ${bindir} 目录下。

target_link_libraries(fcitx fcitx-core ${LIBEXECINFO_LIBRARIES})

fcitx这个target和fcitx-core,以及 ${LIBEXECINFO_LIBRARIES} 进行link。

用过makefile的人对target一定不陌生。fcitx这个target在那里定义的呢?就是在上面的add_executable那里定义的。类似add_executable的还有add_library,用于构建库而不是可执行文件。

至此针对一个简单的C/C++的工程来说,这些就已经足够了。

Posted in cmake | Tagged | 4 Comments