嵌套式CMakeLists写法,文件结构如下:
|--examples
| |--add_example.c
| |--sub_example.c
|--CMakeLists.txt
|--add
| |--add.c
| |--add.h
|--sub
| |--sub.c
| |--sub.h
文件内容详情见C/C++开发之CMakelist(其一) 将C/C++开发之CMakeList(其一)的内容推广,我们可以将对应文件相对路径分别记录,再统一编译运行 需要注意添加include_directories,指定include目录,否则在add.c与sub.c中可能找不到头文件。
cmake_minimum_required(VERSION 2.8)
project(simple_exe)
set(CMAKE_C_STANDARD 99)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/add/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sub/)
set(SOURCES
add/add.c
sub/sub.c
)
set(MAIN_FILES
examples/add_example.c
examples/sub_example.c
)
add_library(alg STATIC ${SOURCES})
foreach(mainfile ${MAIN_FILES})
get_filename_component(mainname ${mainfile} NAME_WE)
add_executable(${mainname} ${mainfile})
target_link_libraries(${mainname} alg)
endforeach()
但是头文件过多时,写起来不方便,用户调用也不方便,最好的方式是将所有头文件整合到一起,统一加到alg.h中,文件结构如下:
|--examples
| |--add_example.c
| |--sub_example.c
|--CMakeLists.txt
|--add
| |--add.c
|--sub
| |--sub.c
|--include
| |--alg.h
头文件alg.h:
#ifndef __ALG_H
#define __ALG_H
int my_sub(int a, int b);
int my_add(int a, int b);
#endif
源文件add.c,sub.c add.c
#include "alg.h"
int my_add(int a, int b){
return a + b;
}
sub.c
#include "alg.h"
int my_sub(int a, int b){
return a - b;
}
main文件sub_example.c, add_example.c add_example.c
#include "alg.h"
#include<stdio.h>
int main(){
int a = 1, b = 2;
printf("add:%d\n", my_add(a, b));
return 0;
}
sub_example.c
#include "alg.h"
#include<stdio.h>
int main(){
int a = 1, b = 2;
printf("sub:%d\n", my_sub(a, b));
return 0;
}
对应cmake也需要改写include_directories
cmake_minimum_required(VERSION 2.8)
project(simple_exe)
set(CMAKE_C_STANDARD 99)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
set(SOURCES
add/add.c
sub/sub.c
)
set(MAIN_FILES
examples/add_example.c
examples/sub_example.c
)
add_library(alg STATIC ${SOURCES})
foreach(mainfile ${MAIN_FILES})
get_filename_component(mainname ${mainfile} NAME_WE)
add_executable(${mainname} ${mainfile})
target_link_libraries(${mainname} alg)
endforeach()
如果源文件也特别多,文件夹里面也嵌套了很多文件夹,将文件中所有目录全写入最外层CMakeLists显得特别混乱,不利于团队开发。解决方案为在合适的文件嵌套深度写CMakelists.txt文件,然后将内部的CMakelists.txt文件中的变量层层传入外部合适的位置。不慌,看案例: 我们再增加一层目录,如下
|--examples
| |--add_example.c
| |--sub_example.c
|--CMakeLists.txt
|--include
| |--alg.h
|--alg
| |--add
| | |--add.c
| | |--CMakeLists.txt
| |--sub
| | |--sub.c
| | |--CMakeLists.txt
| |--CMakeLists.txt
alg/add/CMakeLists.txt中重点为set(SRCS ${SRCS} ${SOURCES} PARENT_SCOPE),表示作用域在父目录
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
set(SOURCES
alg/add/add.c
)
set(SRCS ${SRCS} ${SOURCES} PARENT_SCOPE)
alg/sub/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
set(SOURCES
alg/sub/sub.c
)
set(SRCS ${SRCS} ${SOURCES} PARENT_SCOPE)
alg/CMakeLists.txt如下,重点为add_subdirectory,表示调用子目录的CMakeLists:
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
set(MODULES
add
sub
)
foreach(module ${MODULES})
add_subdirectory(${module})
endforeach()
set(SRCS ${SRCS} PARENT_SCOPE)
CMakeLists.txt如下:
cmake_minimum_required(VERSION 2.8)
project(simple_exe)
set(CMAKE_C_STANDARD 99)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
set(MODULES
alg
)
foreach(module ${MODULES})
add_subdirectory(${module})
endforeach()
set(MAIN_FILES
examples/add_example.c
examples/sub_example.c
)
add_library(alg STATIC ${SRCS})
foreach(mainfile ${MAIN_FILES})
get_filename_component(mainname ${mainfile} NAME_WE)
add_executable(${mainname} ${mainfile})
target_link_libraries(${mainname} alg)
endforeach()
但是!!!如果main示例文件过多而且也存在各种文件嵌套,怎么办? 修改文件目录如下:
|--examples
| |--add_example.c
| |--sub_example.c
| |--CMakeLists.txt
|--CMakeLists.txt
|--include
| |--alg.h
|--alg
| |--add
| | |--add.c
| | |--CMakeLists.txt
| |--sub
| | |--sub.c
| | |--CMakeLists.txt
| |--CMakeLists.txt
|--build
examples/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(simple_exe)
set(CMAKE_C_STANDARD 99)
set(MAIN_FILES
add_example.c
sub_example.c
)
foreach(mainfile ${MAIN_FILES})
get_filename_component(mainname ${mainfile} NAME_WE)
add_executable(${mainname} ${mainfile})
target_link_libraries(${mainname} alg)
endforeach()
alg/add/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
set(SOURCES
add/add.c
)
set(SRCS ${SRCS} ${SOURCES} PARENT_SCOPE)
alg/sub/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
set(SOURCES
sub/sub.c
)
set(SRCS ${SRCS} ${SOURCES} PARENT_SCOPE)
alg/CMakeLists.txt,重点理解一下SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/…/lib)
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
set(MODULES
add
sub
)
foreach(module ${MODULES})
add_subdirectory(${module})
endforeach()
add_library(alg STATIC ${SRCS})
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(simple_exe)
set(CMAKE_C_STANDARD 99)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/)
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
set(MODULES
alg
examples
)
foreach(module ${MODULES})
add_subdirectory(${module})
endforeach()
查看一下编译之后的文件目录,对比一下编译之前的目录
|--examples
| |--add_example.c
| |--sub_example.c
| |--CMakeLists.txt
|--CMakeLists.txt
|--include
| |--alg.h
|--alg
| |--add
| | |--add.c
| | |--CMakeLists.txt
| |--sub
| | |--sub.c
| | |--CMakeLists.txt
| |--CMakeLists.txt
|--lib
| |--libalg.a
还差一步就可以打包发布自己的程序啦,回忆一下我们源码安装c/c++程序时,离不开这几个命令,cmake, make , make install。目前我们仅仅在使用cmake, make之后在build/examples里面可以找到自己的源码,所以如何使用make install呢? make install发布自己的程序 只需要替换上一节中alg/CmkaeLists.txt的内容如下,注意Install命令
cmake_minimum_required(VERSION 2.8)
project(simple_alg_exe)
set(CMAKE_C_STANDARD 99)
SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../lib)
set(MODULES
add
sub
)
foreach(module ${MODULES})
add_subdirectory(${module})
endforeach()
add_library(alg STATIC ${SRCS})
install(FILES ../include/alg.h DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../output/include)
install(FILES ../lib/libalg.a DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/../output/lib)
当输入make install时输出如下:
make install
[ 42%] Built target alg
[ 71%] Built target sub_example
[100%] Built target add_example
Install the project...
-- Install configuration: ""
-- Installing: /home/lichangshi/ML2/my_test/test_cmake/alg/../output/include/alg.h
-- Installing: /home/lichangshi/ML2/my_test/test_cmake/alg/../output/lib/libalg.a
安装成功,查看目录结构
|--examples
| |--add_example.c
| |--sub_example.c
| |--CMakeLists.txt
|--CMakeLists.txt
|--include
| |--alg.h
|--alg
| |--add
| | |--add.c
| | |--CMakeLists.txt
| |--sub
| | |--sub.c
| | |--CMakeLists.txt
| |--CMakeLists.txt
|--output
| |--lib
| | |--libalg.a
| |--include
| | |--alg.h
|--lib
| |--libalg.a
安装成功,其它程序只要正确找到对应的头文件与静态库就可以直接调用自己的程序。
|