Makefile、
makefile主要规则:
#伪对象
.PHONY : clean
#规则1
main : main.o
gcc main.o -o main
#规则2
main.o : main.c
gcc -c main.c -o main.o
#规则3
clean :
rm main *.o
如上图所示这个makefile有3个规则,从上述代码可以看出makefile的通用规则。例如规则1,“main”是目标,“main.o”是依赖,“gcc main.o -o main”是命令。makefile的一般规则格式就是:
目标 : 依赖
命令
注意的是命令之前的不是空格而是Tab键。
规则表达的含义:如果目标的更新时间比依赖的更新时间要晚,那么就执行命令。当依赖为空时,就判断目标是否存在,如果不存在就执行命令。当目标是个伪对象(下面会解析伪对象)那么就直接执行命令。当执行“make main”的时候就是执行规则1。如果运行“make”就默认执行第一条规则,也就是规则1。
伪对象:目标可以是个文件也可以是个伪对象。伪对象的含义就是一个名字,表达规则的目标。如果运行make程序的目录中存在一个与伪对象名字一样的文件,那么make程序不知道这个名字是文件还是伪对像。“.PHONY : clean”就是用于告诉make程序,clean是个伪对象而不是文件。如果没有这个声明,make程序会把clean当做是文件,所以如果存在clean文件的时候,那么运行这个规则的时候就会当做文件存在而不执行命令。
变量:
.PHONY : clean
CC = gcc
RM = rm
EXE = main
SRCS = main.c
$(EXE) : $(SRCS )
$(CC) $(SRCS ) -o $(EXE)
clean :
$(RM) -rf .
变量的定义格式:“变量名=变量”
变量的引用:“$(变量名)”
如上代码展现了,变量的定义与引用。
自动变量:
.PHONY : rule rule1 rule2 rule3
rule : rule1 rule2 rule3
@echo "\$$@ = $@"
@echo "$$^ = $^"
@echo "$$< = $<"
rule1 :
@echo "rule1"
rule2 :
@echo "rule2"
rule3 :
@echo "rule3"
$@:表示一个规则中的目标,当一个规则有多个目标的时候,$@代表导致运行命令的目标。
$^:表示所有的依赖
$<:表示第一个依赖
自动变量的作用:可以结合一些make程序的函数来得到对应源文件的文件列表,然后根据这个源文件列表去编译。这样子,开发过程中有新的源文件添加的时候就不用在makefile中手动添加源文件了。
CMake、
CMake程序可以通过CMakeLists.txt文件配置,去生成makefile文件和CMake工程中间文件。
注意:在CMakeLists.txt所在目录去运行“cmake .”那么CMake工程的中间文件就会在这个目录上生成。如果把这个目录copy到另外的目录上作为备份,因为这些中间文件和makefile组成的工程指向的路径是原来的目录上,所以当我们修改源文件编译的时候,编译的源文件是原来目录上的源文件。在CMakeLists.txt所在目录创建一个build目录,然后再buid目录下运行“cmake ..”,那么makefile文件和CMake工程中间文件会在build目录中生成,只要删除build目录下的文件就可以重新建立工程了。
CMakeLists.txt的简单范例:
#设置运行cmake的最低运行版本
cmake_minimum_required(VERSION 2.8)
#工程名字
project(hello-world)
#设置变量SOURCE_FILES
set(SOURCE_FILES main.c)
#打印信息
message(STATUS "This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "This is SOURCE dir " ${PROJECT_SOURCE_DIR})
#生成可执行文件hello-world
add_executable(hello-world ${SOURCE_FILES})
#函数名字大小写不区分(生成可执行文件hello)
ADD_EXECUTABLE(hello ${SOURCE_FILES})
函数名字在cmake里面是不区分大小写,所以add_executable与ADD_EXECUTABLE是一样的,但是变量名是区分大小写的。
变量的引用格式是“${变量名}”
PROJECT_BINARY_DIR与PROJECT_SOURCE_DIR是cmake的内置变量。
PROJECT_BINARY_DIR:运行cmake命令所在目录路径。
PROJECT_SOURCE_DIR:运行cmake对应的CMakeLists.txt所在目录路径。
一个工程多个项目范例:
#目录结构
mult_item
|--CMakeLists.txt
|--build
|--main
|--main.c
|--dir1
|--CMakeLists.txt
|--dir1.h
|--dir1.c
|--dir2
|--CMakeLists.txt
|--dir2.h
|--dir2.c
上图是一个工程的目录结构,mult_item是项目顶层目录,item_a与item_b是项目的目录。
#mult_item目录中的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(mult_item_project)
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
message(STATUS "Release version!")
set(BuildType "Release")
else()
message(STATUS "Debug version!")
set(BuildType "Debug")
endif()
set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
set(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/${BuildType})
set(EXECUTABLE_OUTPUT_PATH ${RELEASE_DIR}/${BuildType})
file(GLOB_RECURSE DIR_SRCS "main/*.c")
include_directories("${PROJECT_SOURCE_DIR}/dir1")
add_subdirectory(dir1)
include_directories("${PROJECT_SOURCE_DIR}/dir2")
add_subdirectory(dir2)
add_executable(mult_item ${DIR_SRCS})
target_link_libraries(mult_item Dir1 Dir2)
#dir1目录中的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(mult_item_project)
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
message(STATUS "Release version!")
set(BuildType "Release")
else()
message(STATUS "Debug version!")
set(BuildType "Debug")
endif()
set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
set(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/${BuildType})
aux_source_directory(. DIR_LIB_SRCS)
add_library(Dir1 SHARED ${DIR_LIB_SRCS})
#dir2目录中的CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(mult_item_project)
if(${CMAKE_BUILD_TYPE} MATCHES "Release")
message(STATUS "Release version!")
set(BuildType "Release")
else()
message(STATUS "Debug version!")
set(BuildType "Debug")
endif()
set(RELEASE_DIR ${PROJECT_SOURCE_DIR}/release)
set(LIBRARY_OUTPUT_PATH ${RELEASE_DIR}/${BuildType})
aux_source_directory(. DIR_LIB_SRCS)
add_library(Dir2 SHARED ${DIR_LIB_SRCS})
以上是各个目录上的CMakeLists.txt,mult_item中的CMakeLists.txt是生成可执行文件mult_item,同时链接库Dir1与Dir2。dir1与dir2目录中的CMakeLists.txt分别生成对应的库文件libDir1.so与libDir2.so。
cmake_minimum_required:指定cmake的最低版本。
project:指定项目名称。
message:打印信息。
set:设置变量。
file:文件系统操作,GLOB是把与模式匹配的文件的文件名加入到变量中,GLOB_RECURSE与GLOB类似,但会在匹配的文件的目录中的子目录递归地把匹配的文件的文件名加入到变量中。
aux_source_directory:把指定目录中的源文件的文件名加入到变量中。
include_directories:编译时包含的头文件目录。
add_subdirectory:在cmake程序中加入子目录,子目录必须含有对应的CMakeLists.txt,这样子这个子目录的CMakeLists.txt才会被cmake执行。
add_executable:生成可执行文件。
add_library:生成库文件。
target_link_libraries:把add_executable或者add_library生成的文件链接库文件。
详细的cmake官方文档请看这里:cmake文档
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)