您的位置:首页 > 其它

CMake学习笔记

2012-05-10 16:08 246 查看
CMake学习笔记

现在再看这些东西,发现有很多不完善的地方,我也没有将其改正过来,发现这种记日记的过程对于自己对Cmake的理解有很大的帮助

2012年4月24号:

代码例子如下描述:

1,当前目录有两个子目录 incl和src 。

2,其中incl中放的是book.h,而src中放的是book.cpp和main.cpp

3,在当前目录下编写CMakeLists.txt文件。

4,源代码如下:

book.h

-------------------------

#ifndef BOOK_H

#define BOOK_H

#include <string>

class Book

{

public:

Book(char* bn = "bookname");

void print();

private:

std::string book_name;

};

#endif

book.cpp

------------------------------

#include "book.h"

#include <iostream>

using namespace std;

Book::Book(char* bn):book_name(bn){};

void Book::print()

{

cout << book_name << std::endl;

}

main.cpp

------------------------------

#include "book.h"

#include <iostream>

using namespace std;

int main()

{

Book bb;

bb.print();

cout << "good" << endl;

return 0;

}

一。//此时的三个文件在同一目录下

cmake_minimum_required(VERSION 2.6) #要求最低的cmake版本号

PROJECT (MAIN) #定义工程名

SET(SRC_LIST main.cpp book.cpp book.h) #SET指令可以用来显式的定义变量,SRC_LIST是变量

ADD_EXECUTABLE(hello ${SRC_LIST}) #生成一个文件名为hello的可执行文件,相关的源文件是SRC_LIST中

#定义的源文件列表

二。

cmake_minimum_required(VERSION 2.6)

PROJECT (MAIN)

SET(SAM .)

SET(SSS ${SAM}/src)

SET(AAA ${SAM}/incl)

INCLUDE_DIRECTORIES(${SSS}/) #将子目录包含进来,不可少。

INCLUDE_DIRECTORIES(${AAA}/)

SET(SRCL ./incl/book.h ./src/main.cpp ./src/book.cpp)

ADD_EXECUTABLE(hello ${SRCL})

三。

cmake_minimum_required(VERSION 2.6)

PROJECT (MAIN)

SET(SAM .)

SET(SSS ${SAM}/src)

SET(AAA ${SAM}/incl)

INCLUDE_DIRECTORIES(${SSS}/)

INCLUDE_DIRECTORIES(${AAA}/)

SET(SRCL ${SSS}/main.cpp ${SSS}/book.cpp ${AAA}/book.h )

ADD_EXECUTABLE(hello ${SRCL})

四。

cmake_minimum_required(VERSION 2.6)

PROJECT (MAIN)

SET(SAM .)

SET(SSS ${SAM}/src)

SET(AAA ${SAM}/incl)

INCLUDE_DIRECTORIES(${SSS}/)

INCLUDE_DIRECTORIES(${AAA}/)

AUX_SOURCE_DIRECTORY(${SSS} DIR_SRCS) #将${SSS}目录下的源文件名赋值给DIR_SRCS

SET(SRCL ${DIR_SRCS} ${AAA}/book.h )

ADD_EXECUTABLE(hello ${SRCL})

五。

cmake_minimum_required(VERSION 2.6)

PROJECT (MAIN)

SET(SAM .)

SET(SSS ${SAM}/src)

SET(AAA ${SAM}/incl)

INCLUDE_DIRECTORIES(${SSS}/)

INCLUDE_DIRECTORIES(${AAA}/)

AUX_SOURCE_DIRECTORY(${SSS} DIR_SRCS)

SET(SRCL ${DIR_SRCS} ${AAA}/ ) #小小的变化。

ADD_EXECUTABLE(hello ${SRCL})

2012年4月25日:

代码例子如下描述:

1,当前目录有一个子目录 src 。

2,其中src中放的是book.cpp和book.h ,当前存放main.cpp 。

3,在当前目录下编写CMakeLists.txt文件,在src目录下也要编写CMakeLists.txt文件。

4,源代码如下:和前一天的一模一样。

一。

在当前目录下的CMakeLists.txt如下:

PROJECT(MAIN)

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

ADD_SUBDIRECTORY(src) #ADD_SUBDIRECTORY 指明本项目包含一个子目录 src ,

#此句不可少,因为若少了的话就链接不上如下指定的库了。如果不需要链

#接指定的库,则不需要此句。

INCLUDE_DIRECTORIES(./src) #不要以为有了上面的一句,就可以省这句。此句的作用是将指定目录包含
#进来

AUX_SOURCE_DIRECTORY(. DIR_SRCS)

SET(MAIN_SRCS ${DIR_SRCS} ./src/book.h)

ADD_EXECUTABLE(main ${MAIN_SRCS})

TARGET_LINK_LIBRARIES(main Book)

在src子目录下的CMakeLists.txt如下:

AUX_SOURCE_DIRECTORY(. DIR_BOOK_SRCS) #

ADD_LIBRARY(Book ${DIR_BOOK_SRCS}) #ADD_LIBRARY 将 src 目录中的源文件编译为静态库

#如果加上SHARED则为共享库,如:

ADD_LIBRARY(Book SHARED ${DIR_BOOK_SRCS})

2012-4-27系统地做了一个小练习,可以从中理会之前没有理会到的东西。

1、当前目录下建立三个目录:build book desk 并编写CMakeLists.txt main.cpp

2、在book desk下各建两个目录incl src 在incl中存放头文件 在src中存放头文件

3、分别在book desk下各写一个CMakeLists.txt文件

4、结构如下:

当前目录(工程目录)

|

+--- main.cpp

|

+--- book

| |

| +--- incl

| | |

| | +--- book.h

| |

| +--- src

| |

| +--- book.cpp

+--- desk

|

+--- incl

| |

| +--- desk.h

|

+--- src

|

+--- desk.cpp

源代码如下:

1)main.cpp

#include "book.h"

#include "desk.h"

int main()

{

Book bk;

bk.book_say();

Desk dk;

dk.desk_say();

return 0;

}

2)book.h

#ifndef BOOK_H

#define BOOK_H

class Book

{

public:

Book();

void book_say();

private:

};

#endif

3)book.cpp

#include "book.h"

#include <iostream>

Book::Book()

{

}

void Book::book_say()

{

std::cout << "book say hello" << std::endl;

}

4)desk.h

#ifndef DESK_H

#define DESK_H

class Desk

{

public:

Desk();

void desk_say();

private:

};

#endif

5)desk.cpp

#include "desk.h"

#include <iostream>

Desk::Desk()

{

}

void Desk::desk_say()

{

std::cout << "desk say hello" << std::endl;

}

在工程目录下的CMakeLists.txt如下:

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

PROJECT(PRO_TEST)

ADD_SUBDIRECTORY(book)

ADD_SUBDIRECTORY(desk)

INCLUDE_DIRECTORIES(./book/incl ./desk/incl)
#只要将需要的头文件包含进来就可以了。

AUX_SOURCE_DIRECTORY(. SRCS)

ADD_EXECUTABLE(main ${SRCS})

TARGET_LINK_LIBRARIES(main book)

TARGET_LINK_LIBRARIES(main desk)

book目录下的CMakeLists.txt

INCLUDE_DIRECTORIES(./incl)

SET(SRCS ./src/book.cpp) #AUX_SOURCE_DIRECTORY(./src/ SRCS)也可以,但是SET(SRCS ./src/)不行

ADD_LIBRARY(book SHARED ${SRCS})

desk目录下的CMakeLists.txt

INCLUDE_DIRECTORIES(incl)

AUX_SOURCE_DIRECTORY(./src/ SRCS)

ADD_LIBRARY(desk SHARED ${SRCS})

2012-4-26

外部编译的学习:

1、在当前目录下建一个build目录和一个src目录,在src目录下编写源文件main.cpp,能打印“hello,ni hao"。

2、在当前目录下编写CMakeLists.txt使之能很好地编译src中的源文件

3、进入build目录,cmake .. 然后make(注:cmake后面的是CMakeLists.txt的路径,build其实是可以在

任何地方的。)

外部编译的好处:可能使生成的中间文件在指定的build目录中,使得工程目录看上去简洁些。

一。

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

PROJECT(MAIN)

ADD_SUBDIRECTORY(src)

INCLUDE_DIRECTORIES(./src)

AUX_SOURCE_DIRECTORY(./src DIR_SRCS)

ADD_EXECUTABLE(main ${DIR_SRCS})

二。

1,准备工作:

建立t2目录。

将t1工程的main.c和CMakeLists.txt拷贝到t2目录中。

2,添加子目录src:

mkdir src

mv main.c src

现在的工程看起来是这个样子:

一个子目录src,一个CMakeLists.txt。

上一节我们提到,需要为任何子目录建立一个CMakeLists.txt,

进入子目录src,编写CMakeLists.txt如下:

ADD_EXECUTABLE(hello main.c)

将t2工程的CMakeLists.txt修改为:

PROJECT(HELLO)

ADD_SUBDIRECTORY(src bin)

然后建立build目录,进入build目录进行外部编译。

cmake ..

make

构建完成后,你会发现生成的目标文件hello位于build/bin目录中。

语法解释:

ADD_SUBDIRECTORY指令

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

这个指令用于向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存

放的位置。EXCLUDE_FROM_ALL参数的含义是将这个目录从编译过程中排除,比如,工程

的example,可能就需要工程构建完成后,再进入example目录单独进行构建(当然,你

也可以通过定义依赖来解决此类问题)。(看下面一段就明白了)。

上面的例子定义了将src子目录加入工程,并指定编译输出(包含编译中间结果)路径为

bin目录。如果不进行bin目录的指定,那么编译结果(包括中间结果)都将存放在

build/src目录(这个目录跟原有的src目录对应),指定bin目录后,相当于在编译时

将src重命名为bin,所有的中间结果和目标二进制都将存放在bin目录。

这里需要提一下的是SUBDIRS指令,使用方法是:

SUBDIRS(dir1 dir2...),但是这个指令已经不推荐使用。它可以一次添加多个子目录,

并且,即使外部编译,子目录体系仍然会被保存。

如果我们在上面的例子中将ADD_SUBDIRECTORY (src bin)修改为SUBDIRS(src)。

那么在build目录中将出现一个src目录,生成的目标代码hello将存放在src目录中。

三,换个地方保存目标二进制

不论是SUBDIRS还是ADD_SUBDIRECTORY指令(不论是否指定编译输出目录),我们都可

以通过SET指令重新定义EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH变量

来指定最终的目标二进制的位置(指最终生成的hello或者最终的共享库,不包含编译生成

的中间文件)

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

在第一节我们提到了<projectname>_BINARY_DIR和PROJECT_BINARY_DIR变量,他

们指的编译发生的当前目录,如果是内部编译,就相当于PROJECT_SOURCE_DIR也就是

工程代码所在目录,如果是外部编译,指的是外部编译所在目录,也就是本例中的build

目录。

所以,上面两个指令分别定义了:

可执行二进制的输出路径为build/bin和库的输出路径为build/lib.

本节我们没有提到共享库和静态库的构建,所以,你可以不考虑第二条指令。

问题是,我应该把这两条指令写在工程的CMakeLists.txt还是src目录下的

CMakeLists.txt,把握一个简单的原则,在哪里ADD_EXECUTABLE或ADD_LIBRARY,

如果需要改变目标存放路径,就在哪里加入上述的定义。

在这个例子里,当然就是指src下的CMakeLists.txt了。

四,install 安装

那么我们的HelloWorld应该怎么进行安装呢?

这里需要引入一个新的cmake指令INSTALL和一个非常有用的变量CMAKE_INSTALL_PREFIX。

CMAKE_INSTALL_PREFIX变量类似于configure – 脚本的 prefix,常见的使用方法看

起来是这个样子:

cmake -DCMAKE_INSTALL_PREFIX=/usr .

INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及

文件、目录、脚本等。

5,修改Helloworld支持安装

在本节开头我们定义了本节的任务如下:

1,为工程添加一个子目录src,用来存储源代码;

2,添加一个子目录doc,用来存储这个工程的文档hello.txt

3,在工程目录添加文本文件COPYRIGHT, README;

4,在工程目录添加一个runhello.sh脚本,用来调用hello二进制

4,将构建后的目标文件放入构建目录的bin子目录;

5,最终安装这些文件:将hello二进制与runhello.sh安装至/<prefix>/bin,将

doc目录中的hello.txt以及COPYRIGHT/README安装到

/<prefix>/share/doc/cmake/t2,将

首先我们先补上为添加的文件。

添加doc目录及文件:

cd /backup/cmake/t2

mkdir doc

vi doc/hello.txt

随便填写一些内容并保存

在工程目录添加runhello.sh脚本,内容为:

hello

添加工程目录中的COPYRIGHT和README

touch COPYRIGHT

touch README

下面改写各目录的CMakeLists.txt文件。

1,安装COPYRIGHT/README,直接修改主工程文件CMakelists.txt,加入以下指令

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t2)

2,安装runhello.sh,直接修改主工程文件CMakeLists.txt,加入如下指令:

INSTALL(PROGRAMS runhello.sh DESTINATION bin)

3,安装doc中的hello.txt,这里有两种方式:一是通过在doc目录建立

CMakeLists.txt并将doc目录通过ADD_SUBDIRECTORY加入工程来完成。另一种方

是直接在工程目录通过

INSTALL(DIRECTORY来完成),前者比较简单,各位可以根据兴趣自己完成,我们来尝

后者,顺便演示以下DIRECTORY的安装。

因为hello.txt要安装到/<prefix>/share/doc/cmake/t2,所以我们不能直接安装

整个doc目录,这里采用的方式是安装doc ” 目录中的内容,也就是使用doc/”

在工程文件中添加

INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t2)

路漫漫……
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: