驭风万里无垠

转换autoconf的配置文件为CMake配置文件

不少现存的第三方开源程序是用autotools来组织的,将其加入到CMake的代码里的时候,有个麻烦的问题是,makefile的更新会产生不一致,尤其是./configure脚本的执行速度实在不敢恭维,当然希望往Windows上移植的话,是另外一个大问题了。

对于源代码比较少的程序,基本可以通过比照config.h的内容,类比造出一个CMake风格的配置文件,然后利用下述命令:
configure_file(config.h.in config.h)
这个方法可行的根源在于,CMake提供了类似的机制来进行跨平台的检测,具体来说是如下几个Module:

CheckFunctionExists
CheckIncludeFile
CheckIncludeFileCXX
CheckIncludeFiles
CheckLibraryExists
CheckStructHasMember
CheckSymbolExists
CheckTypeSize
CheckVariableExists
< /div> 对于大部分简单的config.h,CheckIncludeFile/CheckIncludeFiles/CheckLibraryExists /CheckFunctionExists就足够了。
需要的工作是,手工写一个config.h.in,另外加一个 Detect.cmake,在config.h.in里边,将对应的声明变化cmakedefine,在Detect.cmake里边,加上查找对应 macro的方法.

  • 头文件
/*Define to 1 if you have <netinet/in.h>*/
#define HAVE_NET_INET_IN_H 1

对应的声明分别为:
//config.h.in
#cmakedefine HAVE_NET_INET_IN_H

//detect.cmake
INCLUDE(CheckIncludeFile)
CHECK_INCLUDE_FILE(netinet
/in.h HAVE_NET_INET_IN_H)



其内部的工作机制为:根据宏参数构造一个基本的C文件,然后用CC编译看是否有错误,如果没有,则定义上述符号(HAVE_XXX_H),否则,undefine
.

对于某些系统头文件而言,可能头文件自身是不完备的(依赖于其他的头文件),此时需要按照依赖顺序写出对应的头文件序列:
/*Define to 1 if you have xxx/yyy.h */
#define HAVE_XXX_YYY_H
//detect.cmake
INCLUDE(CheckIncludeFiles)
CHECK_INCLUDE_FILES(
"dir1/top1.h;dir2/top2.h;xxx/yyy.h" HAVE_XXX_YYY_H)

  • 库检测已经查找库中的某一个函数
对于检查库存在与否的情况,则稍微有些复杂,config.h通常会如下(autoconf的情况):
/*Define to 1 if you have the library `xxx'*/
#define HAVE_LIBXXX对应的定义部分即config.h.in

没有太大差异,照样cmakedefine即可。

对于detect.cmake,需要指明lib中的一个函数:
INCLUDE(CheckLibraryExists)
find_libaray(libloc libname)
#Get the library directory
string(REGEX REPLACE ".*/(.*)" "\\1" libloc ${libloc})
CHECK_LIBRARY_EXISTS(XXX fun_in_lib ${libloc} HAVE_LIBXXX)

上述方法可以很检测某个库中是否包含某个需要的函数,只有找到的情况下,才定义对应的宏。

如果只需要知道库是否存在,只需要根据find_library的结果即可:
find_libaray(libloc xxx)
if (libloc)
   
set(HAVE_LIBXXX 1)
endif()
  • 函数
函数的处理方法则相对简单,只需要如下的cmake代码即可:
INCLUDE(CheckFunctionExists)
CHECK_FUNCTION_EXISTS(testfunc HAVE_TEST_FUNC)

  • 调试
上述代码可能在某些情况下不能正常工作,或者你不知道需要怎样去填入里边的信息(比如多头文件依赖顺序的问题),那么可以自己手工模拟对应CMake模块的工作方法,自己造一个C文件来编译,看看缺少哪些头文件或者链接库。
  • Automation?
如果手边有现成的autotools生成的config.h,并且这个文件比较大,手工一一改动有些太繁琐。注意到autoconf 生成的config.h文件有某些特征,用脚本来做某些自动化转换是可能的,一个可行的思路是,通过正则表达式匹配来检测注释,从而可以得出接下来的宏声明是头文件还是库、函数等,由于宏命名的规律性,可以很容易的推导出对应的头文件名或者函数名。

在我自己实验的一个例子中,用100行的python脚本可以转换得到200个可以正常工作的cmake代码和 config.h.in。

posted on 2009-09-20 21:10 skyscribe 阅读(2084) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2009年9月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

导航

统计

常用链接

留言簿(3)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜