CMake第四课--编写程序使用上一节安装的库和头文件

CMake第四课  编写程序使用上一节安装的库和头文件 

一.完整过程

  手把手教你学CMake,上一节我们将自己写的头文件和共享库安装到了电脑上 。这一节,我们将编写程序,应用上一节安装的头文件和库文件。 

===================================================================================

绝对路径:/home/guo/cmake_practice/4(工程目录) 

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

目标:编写一个程序使用我们上一节构建的共享库 

   安装的头文件在/home/guo/cmake_practice/3/include/hello下 

   安装的库在       /home/guo/cmake_practice/3/include/lib下 

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

工程目录结构(按照下面结构添加文件夹和文件) 

1.编写工程主文件(/home/guo/cmake_practice/4) CMakeLists.txt: 

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )  # 声明要求的 cmake 最低版本
PROJECT(NEWHELLO)                      # 声明一个 cmake 工程
ADD_SUBDIRECTORY(src) 

2.建立 src 目录(/home/guo/cmake_practice/4/src),编写源文件 main.cpp和CMakeLists.txt。 

src/main.cpp内容如下: 

#include <hello.h>
int main()
{
   HelloFunc();
   return 0;
} 

src/CMakeLists.txt内容如下:

CMAKE_MINIMUM_REQUIRED( VERSION 2.8 ) # 声明要求的 cmake 最低版本

INCLUDE_DIRECTORIES(/home/guo/cmake_practice/3/include/hello)
LINK_DIRECTORIES(/home/guo/cmake_practice/3/include/lib)

ADD_EXECUTABLE(main main.cpp)

TARGET_LINK_LIBRARIES(main libhello.so)
#TARGET_LINK_LIBRARIES(main libhello.a) 

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

外部编译 

cd /home/guo/cmake_practice/4

mkdir build    (新建build文件夹)

cd build 

cmake .. 

make

执行二进制可执行文件

cd   /home/guo/cmake_practice/4/build/src

./main

编译完之后我们就可以进入build/src文件夹,运行二进制程序。 

====================================================================================

 

二.详细解释 

1.由于hello.h 位于/home/guo/ cmake_practice/3/include/hello 目录中,并没有位于系统标准的头文件路径(/usr/include, /usr/local/include 等),为了让我们的工程能够找到 hello.h 头文件,我们需要引入一个新的指令INCLUDE_DIRECTORIES,它的语法规则是: 

INCLUDE_DIRECTORIES([AFTER|BEFORE]   [SYSTEM]   dir1  dir2 ...) 

这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割,如果路径中包含了空格,可以使用双引号将它括起来。默认的行为是追加到当前的头文件搜索路径的后面,你可以通过两种方式来进行控制搜索路径添加的方式: 

  • 第一种方式,CMAKE_INCLUDE_DIRECTORIES_BEFORE,通过 SET 这个 cmake 变量为 on,可以将添加的头文件搜索路径放在已有路径的前面。
  • 第二种方式,通过 AFTER 或者 BEFORE 参数,也可以控制是追加还是置前。 

2.虽然我们引用好了头文件,但我们还需要将目标文件链接到 libhello,不然就会报HelloFunc 未定义错误。这里我们需要引入两个新的指令LINK_DIRECTORIES 和 TARGET_LINK_LIBRARIES。 

  • LINK_DIRECTORIES 的全部语法是:   LINK_DIRECTORIES(directory1   directory2 ...)                                                                                                            添加非标准的共享库搜索路径,比如,在工程内部同时存在共享库和可执行二进制,在编译时就需要指定一下这些共享库的路径。 
  • TARGET_LINK_LIBRARIES 的全部语法是:     TARGET_LINK_LIBRARIES(target library1 

                    <debug | optimized> library24  ...) 

          这个指令可以用来为 target 添加需要链接的共享库。 

3.从build文件夹中打开终端,输入ldd   src/main,检查一下 main 的链接情况。 

4.如何链接到静态库呢? 

将 TARGET_LINK_LIBRRARIES 指令修改为:    TARGET_LINK_LIBRARIES(main  libhello.a) 

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

  

三. 介绍两个特殊的环境变量 CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH 

注意:这两个是环境变量而不是 cmake 变量!使用方法是: 在.bashrc中用 export CMAKE_INCLUDE_PATH=/home/include/cmake .. 

如果头文件没有存放在常规路径(/usr/include, /usr/local/include 等),则可以通过这些变量进行弥补。我们以本例中的 hello.h 为例,它存放在/home/guo/ cmake_practice/3/include/hello目录,所以直接查找肯定是找不到的。前面我们直接使用了绝对路径 INCLUDE_DIRECTORIES(/home/guo/ cmake_practice/3/include/hello)告诉工程这个头文件目录。

①.为了将程序更智能一点,我们可以使用 CMAKE_INCLUDE_PATH 来进行,使用 bash 的方法如下: 

  1. 开终端输入:gedit   ~/.bashrc    
  2. 打开.bashrc后,写入
    export  CMAKE_INCLUDE_PATH=/home/guo/cmake_practice/3/include/hello
  3. 再输入:source ~/.bashrc 

②.然后在src/CMakeLists.txt文件中将 INCLUDE_DIRECTORIES(/home/guo/ cmake_practice/3/include/hello)替换为:

FIND_PATH(myHeader  hello.h)  #名字myHeader随便取,不影响
IF(myHeader)
INCLUDE_DIRECTORIES(${myHeader})
ENDIF(myHeader) 
  • 这里简单说明一下,FIND_PATH 用来在指定路径中搜索文件名,比如:  FIND_PATH(myHeader  NAMES  hello.h   PATHS /home/guo/ cmake_practice/3/include/hello)。这里我们没有指定路径,但是,cmake 仍然可以帮我们找到 hello.h 存放的路径,就是因为我们设置了环境变量 CMAKE_INCLUDE_PATH。 
  • 如果你不使用FIND_PATH命令 ,CMAKE_INCLUDE_PATH 变量的设置对编译器是没有作用的,你不能指望它会直接为编译器命令添加参数<CMAKE_INCLUDE_PATH>。 
  • 以此为例,CMAKE_LIBRARY_PATH 可以用在 FIND_LIBRARY 中。同样,因为这些变量直接为 FIND_指令所使用,所以所有使用 FIND_指令的 cmake 模块都会受益。

 

 

 

 

 

posted @ 2018-09-06 20:31  小果子啊  阅读(442)  评论(0编辑  收藏  举报