CMake学习笔记

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)

路漫漫……



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值