1. 編譯單目錄工程
1.創(chuàng)建工程文件夾
mkdir hello #工程目錄
cd hello
mkdir src # 存放源代碼的目錄
mkdir build # 存放編譯中間代碼和目標(biāo)代碼的目錄
2.進(jìn)入src
目錄萝玷,編寫一個(gè)main.c
文件
#include <stdio.h>
int main(int argc, char **argv)
{
printf("hello world\n");
return 0;
}
3.編寫工程頂層目錄的CMakeLists.txt
cmake_minumum_required(VERSION 2.6)
#指定項(xiàng)目名
project(hello)
#指定子目錄
add_subdirectory(src)
4.編寫子目錄src
的CMakeLists.txt
aux_source_directory(. SRC_LIST)
add_executable(hello ${SRC_LIST})
5.編譯工程
1.進(jìn)入
build
目錄
2.執(zhí)行命令cmake ..
創(chuàng)建Makefile
3.執(zhí)行命令make
編譯工程
4.在build
的子目錄src
生成了執(zhí)行文件
2. 編譯多目錄工程
1.創(chuàng)建工程目錄
mkdir hello # 工程目錄
cd hello
mkdir src # 存放源碼目錄
mkdir build # 存放編譯產(chǎn)生的中間文件
cd src
mkdir hello # 存放hello 模塊
mkdir world # 存放world 模塊
2.編寫hello
模塊
- 進(jìn)入
hello
目錄 - 編寫
hello.h
文件
#ifndef HELLO_H
#define HELLO_H
void Hello_Print(void);
#endif
- 編寫
hello.c
文件
#include "hello.h"
#include <stdio.h>
void Hello_Print(void)
{
printf("hello ");
}
- 編寫
CMakeLists.txt
文件
aux_source_directory(. DIR_HELLO_SRC)
add_library(hello_lib ${DIR_HELLO_SRC})
3.編寫world
模塊
- 進(jìn)入
world
目錄 - 編寫
world.h
文件
#ifndef WORLD_H
#define WORLD_H
void World_Print(void);
#endif
- 編寫
world.c
文件
#include "world.h"
#include <stdio.h>
void World_Print(void)
{
printf("world");
}
- 編寫
CMakeLists.txt
文件
aux_source_directory(. DIR_WORLD_SRC)
add_library(world_lib ${DIR_WORLD_SRC})
4.編寫主模塊
- 進(jìn)入
src
目錄 - 編寫
main.c
文件
#include "hello/hello.h"
#include "world/world.h"
int main(int argc, char **argv)
{
Hello_Print();
World_Print();
return 0
}
- 編寫
CMakeLists.txt
文件
add_source_directory(. DIR_SRC)
# 添加子目錄
add_subdirectory(hello)
add_subdirectory(world)
# 執(zhí)行文件
add_executable(hello_prj ${DIR_SRC})
target_link_libraries(hello_prj ello_lib world_lib)
5.編寫頂層目錄的CMakeLists.txt
文件
cmake_minumum_required(VERSION 2.6)
project(hello_prj)
add_subdirectory(src)
3. 動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的構(gòu)建和使用
1.使用一個(gè)hello world
工程來(lái)展開說(shuō)明
項(xiàng)目結(jié)構(gòu)
|-- CMakeLists.txt
|-- build
|-- include
| |-- hello
| | `-- hello.h
| `-- world
| `-- world.h
|-- src
| |-- CMakeLists.txt
| |-- hello
| | `-- hello.c
| `-- world
| `-- world.c
`-- test
|-- CMakeLists.txt
`-- mytest.c
2.頂層目錄CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(helloworld)
#設(shè)置庫(kù)文件存放路徑
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/lib)
#設(shè)置執(zhí)行文件存放路徑
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build/bin)
#獲取當(dāng)前目錄及子目錄(遞歸獲取),添加到頭文件搜索路徑
function(include_sub_directories_recursively root_dir)
if (IS_DIRECTORY ${root_dir}) # 當(dāng)前路徑是一個(gè)目錄嗎蕉毯,是的話就加入到包含目錄
message("include dir: " ${root_dir})
include_directories(${root_dir})
endif()
file(GLOB ALL_SUB RELATIVE ${root_dir} ${root_dir}/*) # 獲得當(dāng)前目錄下的所有文件丐黄,讓如ALL_SUB列表中
foreach(sub ${ALL_SUB})
if (IS_DIRECTORY ${root_dir}/${sub})
include_sub_directories_recursively(${root_dir}/${sub}) # 對(duì)子目錄遞歸調(diào)用们衙,包含
endif()
endforeach()
endfunction()
#項(xiàng)目的所有目錄都為頭文件搜索路徑
include_sub_directories_recursively(${PROJECT_SOURCE_DIR})
#添加庫(kù)文件搜索路徑
link_directories(
${PROJECT_SOURCE_DIR}/build/lib
)
#添加子目錄
add_subdirectory(src)
add_subdirectory(test)
#設(shè)置安裝目錄
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/install)
3.helloworld
庫(kù)的源代碼
hello.h文件
#ifndef HELLO_H
#define HELLO_H
void Hello_Print(void);
#endif
hello.c文件
#include "hello/hello.h"
#include <stdio.h>
void Hello_Print(void)
{
printf("hello ");
}
world.h文件
#ifndef WORLD_H
#define WORLD_H
void World_Print(void);
#endif
world.c文件
#include "world/world.h"
#include <stdio.h>
void World_Print(void)
{
printf("world");
}
4.子目錄src
下的CMakeLists.txt
#遞歸獲取當(dāng)前目錄及子目錄下的所有c文件
file(GLOB_RECURSE c_files "*.c")
#生成動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)
add_library(helloworld_lib_shared SHARED ${c_files})
add_library(helloworld_lib_static STATIC ${c_files})
#將動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)的名字設(shè)置為一致
set_target_properties(helloworld_lib_shared PROPERTIES OUTPUT_NAME "helloworld")
set_target_properties(helloworld_lib_static PROPERTIES OUTPUT_NAME "helloworld")
#設(shè)置動(dòng)態(tài)庫(kù)版本
set_target_properties(helloworld_lib_shared PROPERTIES VERSION 1.2 SOVERSION 1)
#安裝動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)
INSTALL(TARGETS helloworld_lib_shared helloworld_lib_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
#安裝頭文件
INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include)
5.mytest.c
文件測(cè)試生成的庫(kù)文件
mytest.c文件
#include "hello/hello.h"
#include "world/world.h"
#include <stdio.h>
int main(int argc, char **argv)
{
Hello_Print();
World_Print();
printf("\n");
return 0;
}
CMakeLists.txt文件
#遞歸獲取所有當(dāng)前目錄及子目錄下的C文件
file(GLOB_RECURSE c_files ./*.c)
#生成執(zhí)行文件
add_executable(mytest ${c_files})
#鏈接外部庫(kù)
target_link_libraries(mytest libhelloworld.so)
6.構(gòu)建工程
1.進(jìn)入目錄build
2.執(zhí)行命令: cmake ..
3.執(zhí)行命令: make
4.執(zhí)行命令: make install
4. 指定編譯器和編譯選項(xiàng)
1.CMAKE_C_COMPILER
: 指定C編譯器
2.CMAKE_CXX_COMPILTER
:指定C++編譯器
3.CMAKE_C_FLAGS
: 指定C編譯選項(xiàng)
4.CMAKE_CXX_FLAGS
:指定C++編譯選項(xiàng)
5.EXECUTABLE_OUTPUT_PATH
: 指定執(zhí)行文件存放目錄
6.LIBRARY_OUTPUT_PATH
: 指定庫(kù)文件存放目錄
7.CMAKE_BUILD_TYPE
:指定build類型[Debug|Release]
8.BUILD_SHARED_LIBS
: 指定默認(rèn)庫(kù)編譯方式[OFF|ON]
上述內(nèi)部變量使用說(shuō)明:
1.CMakeLists.txt
文件上使用set
命令
2.cmake 命令中指定字支,如: cmake -DCMAKE_C_COMPILER=gcc
add_definitions
:添加編譯參數(shù)
5. 配置編譯模塊
6. CMake 常用變量和語(yǔ)句
1.include_directories
:指定頭文件搜索路徑
2.link_directories
:指定庫(kù)文件搜索路徑
3.add_subdirectory
:添加子目錄
4.target_link_libraries
:指定文件鏈接庫(kù)文件