上一篇文章《Linux下动态链接库的创建和使用》中在创建链接库的时候,我们也有简单介绍了CMake的使用。那么如果构建一个C++项目呢,当然我们可以手动去写Makefile,或许你会认为那是一件有趣的事情,但是既然有工具可以代劳,我们也就没那么必要手动去写Makefile。在大型项目中收写Makefile,那是一件相当令人头疼的事情。那么有那些工具可以为我们代劳这件事呢,在CMake没出现之前,我们可以使用Autotools, 也就是说个人比较推荐使用CMake, 理由就是CMake配置使用相对简单一些。下面我们就介绍一下Autotools和CMake的区别。
Autotools是一个工具集具有强大的灵活性。Autotools包含五个命令 : aclocal、autoscan、autoconf、autoheader、automake。现在我们看一下他的步骤。
autotools详细步骤如下:
- 1、运行autoscan命令
- 2、将configure.scan 文件重命名为
- 3、适当修改configure.sc 文件
- 4、运行aclocal命令,扫描 configure.ac 文件生成 aclocal.m4文件
- 5、运行autoconf命令, 生成configure 文件
- 6、运行autoheader命令, 生成config.h.in文件
- 7、手工创建Makefile.am文件, 并添加相关内容
- 8、手动创建NEWS、 README、 AUTHORS、ChangeLog文件,运行automake –add-missing命令, 生成 Makefile.in 文件
- 9、运行./confiugre脚本, 生成Makefile 文件
我们再看看cmake的步骤:
- 1、编写CMakeLists.txt, 内容格式可以参考《Linux下动态链接库的创建和使用》一文的示例
- 2、运行cmake命令
另外至于配置文件
- autoconfig的配置文件configure.ac我们通过autosan生成,我们只需要修改就可以、autoconfig的配置文件Makefile.am我们需要自己手工从头编写;
- cmake的配置文件CMakeLists.txt需要手工编写,当然cmake提供了gui的配置工具供大家使用;
重点看一下两者配置文件的内容吧,因为这是我们实际使用的关键步骤:
- autotools cmake 变量定义 name=… set(name, “…”) 环境检测 AC_INIT
测试程序
AC_PROG_CC
测试函数库
AC_CHECK_LIB([pthread], [pthread_rwlock_init])
AC_PROG_RANLIB
测试头文件
测试类型定义
测试结构
测试编译器特性
测试库函数
测试系统调用
AC_OUTPUTfind_library(lib libname pathllist)
find_package(packename)
find_path(var name pathlist)
find_program(var name pathlist)子目录 SUBDIRS= add_subdirectory(list) 可执行文件 bin_PROGRAMS=binname
binname_SOURCES=
binname_LDADD=
binname_CFLAGS=
binname_LDFLAGS=add_executable(binname ${sources})
target_link_libraries(binname librarylist)静/动态库 lib_LIBRARIES=libname.a/libname.so
libname_SOURCES=add_library(libname static/shared ${source} ) 头文件 INCLUDES=
include_HEADES=或CFLAGS=-Iinclude_directories(list) 源码搜索 aux_source_directories(. list) 依赖库 LIBS=
LDADD=target_link_libraries(binname librarylist)) 标志 CFLAGS=
LDFLAGS=set(CMAKE_C_FLAGS …) libtool AC_PROG_LIBTOOL
lib_LTLIBRARIES=name.la name_la_SOURCES=安装设置 install(TARGETS targets..[…]) 其他文件 EXTRA_DIST install(FILES files.. )
install(DIRECTORY dirs..)条件语句 if()
endifif() else() endif() while() endwhile() 执行外部命令 exec_program(commd ) 子模块 include() 信息输出 messge(STATUS “messge”) 项目 project(name)
假设有一个test项目, test目录下有maic.cpp , include/test.h, lib/test.cpp 。
main.cpp代码:
#include
#include "include/test.h"
int main(){
test_method();
}
test.h代码:
void test_method();
test.cpp代码:
#include
#include "../include/test.h"
void test_method() {
printf("hello world!/n");
}
然后我们根据上文所说的九个步骤,看一下autotools在linux环境下的使用。
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
#AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_INIT(hello,1.0,abc@126.com)
AM_INIT_AUTOMAKE(hello,1.0)
AC_CONFIG_SRCDIR([main.cpp])
AC_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
说明:
(1)以“#”号开始的行均为注释行。
(2)AC_PREREQ 宏声明本文要求的 autoconf 版本, 如本例中的版本 2.59。
(3)AC_INIT 宏用来定义软件的名称、版本等信息、作者的E-mail等。
(4)AM_INIT_AUTOMAKE是通过手动添加的, 它是automake所必备的宏, FULL-PACKAGE-NAME是软件名称,VERSION是软件版本号。
(5)AC_CONFIG_SCRDIR 宏用来侦测所指定的源码文件是否存在, 来确定源码目录的有效性.。此处为当前目录下main.cpp。
(6)AC_CONFIG_HEADER 宏用于生成config.h文件,以便 autoheader 命令使用。
(7)AC_PROG_CC用来指定编译器,如果不指定,默认gcc。
(8)AC_OUTPUT 用来设定 configure 所要产生的文件,如果是makefile,configure 会把它检查出来的结果带入makefile.in文件产生合适的makefile。使用 Automake 时,还需要一些其他的参数,这些额外的宏用aclocal工具产生。
(9)AC_CONFIG_FILES宏用于生成相应的Makefile文件。
[root@localhost test]# aclocal
[root@localhost test]# ls
aclocal.m4 autom4te.cache autoscan.log configure.in include lib main.cpp
[root@localhost test]# autoconf
[root@localhost test]# ls
aclocal.m4 autom4te.cache autoscan.log configure configure.in include lib main.cpp
[root@localhost test]# autoconf
[root@localhost test]# ls
aclocal.m4 autom4te.cache autoscan.log config.h.in configure configure.in include lib main.cpp
UTOMAKE_OPTIONS = foreign
bin_PROGRAMS = hello
hello_SOURCES = main.cpp include/test.h lib/test.cpp
说明:
(1)其中的AUTOMAKE_OPTIONS为设置automake的选项. 由于GNU对自己发布的软件有严格的规范, 比如必须附带许可证声明文件COPYING等,否则automake执行时会报错. automake提供了3中软件等级:foreign, gnu和gnits, 供用户选择。默认级别是gnu. 在本例中, 使用了foreign等级, 它只检测必须的文件。
(2)bin_PROGRAMS定义要产生的执行文件名. 如果要产生多个执行文件, 每个文件名用空格隔开。
(3)hello_SOURCES 定义”hello”这个可执行程序所需的原始文件。如果”hello”这个程序是由多个源文件所产生的, 则必须把它所用到的所有源文件都列出来,并用空格隔开。如果要定义多个可执行程序,那么需要对每个可执行程序建立对应的file_SOURCES。
[root@localhost test]# touch NEWS
[root@localhost test]# touch README
[root@localhost test]# touch AUTHORS
[root@localhost test]# touch ChangeLog
[root@localhost test]# automake --add-missing
[root@localhost project]# ./configure
Makefile的用法说明:
- 1、make: 用来编译代码
- 2、make clean 命令清除编译时的obj文件,它与 make 命令是对应关系,一个是编译,一个清除编译的文件
- 3、make install 命令把目标文件安装到系统中
- 4、make uninstall 命令把目标文件从系统中卸载。
- 5、make dist 命令将程序和相关的文档打包为一个压缩文档以供发布
在实际应用中, Makefile.am的创建还是很复杂的,还要配置引用其他动态库、第三方动态库等关系, 在本中只是一个简单的demo, 有时间可以在研究一下他的详细规则。
1.首先安装autotools plugins, 如果是使用的是最新版,则使用 http://download.eclipse.org/releases/mars
2.修改autotools plugins的配置, 如下图:
3.创建工程,工程类型选择,如下图:
4、eclipse会调用autoscan/aclocal/ automake/autoconf自动创建一些列文件。
5、修改 configure.ac
AC_PREREQ(2.59)
AC_INIT(auto, 1.0)
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE()
AC_PROG_CC
AC_CONFIG_FILES(Makefile
src/Makefile
src/container/Makefile
src/config/Makefile)
AC_OUTPUT
6、修改各级目下的Makefile.am, 执行 automake命令。
7、 最后执行./configure过程中,会将Makefile.in生成各层最终的Makefile