CMake 工程调用 Makefile 编译项目

本文主要介绍如何将一个依赖 Makefile 项目(MIDG)移植到 CMake 上。

首先介绍项目文件结构,文件主要由三个目录组成

  1. 3rdParty
  2. include
  3. src

其中,3rdParty 中包含两个外部函数库,即 Metis 与 ParMetis,生成两个静态链接库 libmetis.a 与 libparmetis.a。 src 包含项目所有源程序, include 则包含了全部头文件。

因此,我们在根目录下 cmake 配置文件内容如下

cmake_minimum_required(VERSION 3.1)
project(DGOM)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")

set(CMAKE_C_COMPILER /usr/local/bin/mpicc)
set(CMAKE_CXX_COMPILER /usr/local/bin/mpicxx)


# 3rdParty library
# Build with original makefile
set(METIS_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libmetis.a)
set(PARMETIS_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/lib/libparmetis.a)

add_custom_target(build_metis ALL
        COMMAND ${CMAKE_MAKE_PROGRAM}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/ParMetis-3.1/METISLib/
        COMMENT "Original metis makefile target")

add_custom_target(build_parmetis ALL
        COMMAND ${CMAKE_MAKE_PROGRAM}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/ParMetis-3.1/ParMETISLib/
        COMMENT "Original parmetis makefile target")

add_library(metis STATIC IMPORTED)
add_library(parmetis STATIC IMPORTED)

set_property(TARGET metis APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(metis PROPERTIES IMPORTED_LOCATION_NOCONFIG "${METIS_LIBRARY}")

set_property(TARGET parmetis APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(parmetis PROPERTIES IMPORTED_LOCATION_NOCONFIG "${PARMETIS_LIBRARY}")

add_dependencies(metis build_metis)
add_dependencies(parmetis build_parmetis)

# source file
add_subdirectory(src)
  1. set(CMAKE_C_COMPILER mpicc)set(CMAKE_CXX_COMPILER mpicxx) 负责选择项目编译器,本项目中选择 mpich2
  2. Metis Parmetis 第三方库采用原始 makefile 编译,将编译好的静态库文件添加到项目中

1. 3rdParty

3rdParty 目录如下

./
└── ParMetis-3.1
    ├── METISLib
    ├── Manual
    └── ParMETISLib

METISLib 与 ParMETISLib 分别为两个不同的网格划分库。原始make命令分别进入两个项目所在目录使用make命令即可。因此,在主目录 CMakeLists.txt 中调用 make 命令编译库函数,主要步骤如下:

1.1. 增加自定义编译方法

add_custom_target(build_metis ALL
        COMMAND ${CMAKE_MAKE_PROGRAM}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/ParMetis-3.1/METISLib/
        COMMENT "Original metis makefile target")

add_custom_target(build_parmetis ALL
        COMMAND ${CMAKE_MAKE_PROGRAM}
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/3rdParty/ParMetis-3.1/ParMETISLib/
        COMMENT "Original parmetis makefile target")

add_custom_target 通过用户给定的指令来增加一个新的编译目标。ALL 代表该目标添加到默认编译目标中,因此每次编译都会执行。

1.2. 增加两个编译目标

这两个目标为外部库 IMPORTED,而非项目自己编译的

add_library(metis STATIC IMPORTED)
add_library(parmetis STATIC IMPORTED)

set_property(TARGET metis APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(metis PROPERTIES IMPORTED_LOCATION_NOCONFIG "${METIS_LIBRARY}")

set_property(TARGET parmetis APPEND PROPERTY IMPORTED_CONFIGURATIONS NOCONFIG)
set_target_properties(parmetis PROPERTIES IMPORTED_LOCATION_NOCONFIG "${PARMETIS_LIBRARY}")

1.3. 将编译目标与编译方法联系

确保首先执行编译过程

add_dependencies(metis build_metis)
add_dependencies(parmetis build_parmetis)

2. 项目源文件

源文件编译时候需要头文件路径,并且与第三方库进行链接

set(SRC_LIST
        Mesh2d.c Utils.c LoadBalance2d.c FacePair2d.c
        ParallelPairs.c BuildMaps2d.c StartUp2d.c
        MaxwellsRun2d.c MaxwellsMPI2d.c MaxwellsDriver2d.c
        MaxwellsRHS2d.c InitCPU2d.c)

add_executable(DGOM2 ${SRC_LIST})

include_directories("../include")
target_link_libraries(DGOM2 metis parmetis)

2.1. 增加可执行程序

add_executable(DGOM2 ${SRC_LIST})

2.2. 给出头文件路径

include_directories("../include")

2.3. 给定链接第三方函数库

target_link_libraries(DGOM2 metis parmetis)

你可能感兴趣的:(服务器)