gcc参数说明
无选项编译 gcc test.c,默认生成a.out
-E
只激活预处理,不生成文件,需要重定向到一个文件中
gcc -E test.c | more
或者gcc -E test.c -o test.i
-S
只激活预处理和编译,就是指把文件编译成汇编代码,生成.s
文件
gcc -S test.c
或者gcc -S test.i
-c
只激活预处理、编译和汇编,生成.o
文件
gcc -c test.c
或者gcc -c test.s
-o
指定目标名称,缺省的时候文件为a.out
gcc -o test test.c
-pipe
使用管道代替编译中临时文件
gcc -pipe -o test test.c
-llibrary
定制编译的时候使用的库
gcc -lpthread test.c
//编译的时候要依赖pthread这个库,动态库静态库都可以
-L dir
定制编译的时候搜索库的路径,比如自己定义的库的路径
-L .
//当前文件夹查找库
-D
添加宏定义
gcc -DENABLE_DEBUG
-I
include路径
-o0
没有优化
-o1
缺省值
-o2
二级优化
-o3
最高优化级别
级别越大优化越好,但编译时间越长
-g
在编译的时候加入debug调试信息,用于gdb调试
-ggdb
产生的debug信息更倾向于给GDB使用
-g3
3是级别,级别越高会产生的更多的额外debug信息,3这个级别可以调试宏
-static
链接时使用静态链接,但是要保证系统中有静态库
-share
尽量使用动态库,所以生成文件比较小,但是系统必须有动态库
-w
不生成任何警告信息
-wall
生成所有警告信息
CMakeLists.txt编写说明
CMakeList.txt中命令不区分大小写,变量区分大小写,make clean
对构建结果进行清理
-
定义工程名字,并可指定工程支持的语言,可忽略
project(projectname [CXX][C][Java])
隐式定义两个cmake变量
<projectname>_BINARY_DIR
和<projectname_SOURCE_DIR>
,与PROJECT_BINARY_DIR
和PROJECT_SOURCE_DIR
一样,对于out-of-source
编译方式来说,PROJECT_SOURCE_DIR
为工程路径/backup/cmake/t1
,PROJECT_BINARY_DIR
为编译路径/backup/cmake/t1/build
-
定义变量,或者设置CMAKE常用变量和环境变量
set(VAR [Value])
SET(SRC_LIST main.c)
,多个源文件也可以SET(SRC_LIST main.c t1.c t2.c)
-
list 追加或者删除变量的值
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
-
向终端输出用户定义的信息
message([WARNING | SEND_ERROR | STATUS | FATAL_ERROR] "message to display")
三种类型:
WARNING
,警告
SEND_ERROR
,产生错误,会继续执行,生成过程被跳过;
STATUS
,输出前缀为-的信息;
FATAL_ERROR
,立即终止所有cmake过程 -
生成可执行文件
add_executable(hello ${SRC_LIST})
源文件可以在后面列ADD_EXECUTABLE(hello main.c fun.c)
,也可以用引用变量的方式${}
。变量引用在控制语句中如if中直接使用变量名,不需要加${}
-
生成动态库或静态库
add_library(common SHARED/STATIC util.cpp)
默认生成静态库,若需要默认生成动态库,则需要set(BUILD_SHARED_LIBS ON)
注意add_executable\add_library生成的可执行文件和库文件不能同名,否则会报错,若需要同名,则采用以下方式:
add_library(hello SHARED ${LIBHELLO_SRC})
add_library(hello_static STATIC ${LIBHELLO_SRC})
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
-
添加一个文件夹进行编译
add_subdirectory(sub_name)
,该文件夹下的CMakeLists.txt负责编译该文件夹下的源码。每一级文件目录用一个cmakelist,如果需要用到上层cmakelist文件参数如projectname_SOURCE_DIR
,应采用projectname_SOURCE_DIR
而不是PROJECT_SOURCE_DIR
,因为在子目录中的cmakelistPROJECT_SOURCE_DIR
是子目录 -
添加头文件查找路径
include_directories(${PROJECT_SOURCE_DIR}/include)
-
设置目标属性
set_target_properties(target1 target2.. PROPERTIES prop1 value1 prop2 value2)
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
重新设置目标名字 -
获取目标属性
get_target_property(VAR target property)
get_target_property(OUTPUT_VALUE hello_static OUTPUT_NAME)
获取hello_static库的OUTPUT_NAME属性,保存在OUTPUT_VALUE中,可以通过${OUTPUT_VALUE}得到 -
添加第三方库
target_link_libraries(target lib1 lib2)
有多种方式:
link_directory(path)//添加第三方库查找路径
//target为目标,hello为第三方库,这里使用libhello.so会报错
target_link_libraries(target hello)
//libhello.so为库,libpath为查找路径,VAR保存查找后的路径,包括libhello.so
find_library(VAR libhello.so libpath)
//等价target_link_libraries(target .../libhello.so)
target_link_libraries(target ${VAR})
//相当于在gcc指令中添加
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/hello/lib")
//或者target_link_libraries(target libhello.so)
target_link_libraries(target hello)
-
查找一个目录下的所有源文件
aux_source_directory(dir VAR)
找到文件夹dir下的所有源文件并保存在变量VAR中,不包括头文件 -
第三方头文件和库
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/hello/lib")
添加第三方头文件和库通用,与gcc使用方式相同 -L为库文件路径 -l(小写L)为库文件 -I(大写i)为头文件查找路径,CMAKE_CXX_FLAGS
为cpp,CMAKE_C_FLAGS
为c -
添加-D定义
add_definitions(-DENABLE_DEBUG -DABC)
定义了ENABLE_DEBUG和ABC两个宏,可以在代码中使用,也可以通过CMAKE_CXX_FLAGS
添加 -
查找指令
find_XX(VAR target path)
查找文件路径
find_path
查找后结果不包括文件本身,会在默认路径中查找,然后在path中查找,也可以通过环境变量CMAKE_INCLUDE_PATH
进行设置,如export CMAKE_INCLUDE_PATH=/usr/include/hello
查找文件
find_file
用于查找文件,查找后结果包括文件本身
查找库
find_library
用于查找库文件,可以通过环境变量CMAKE_LIBRARY_PATH
进行设置
查找程序
find_program
查找包
find_package(pack [QUIET][NO_MODULE][REQUIRED]])
查找.cmake包
模块查找模式:查找路径先在CMAKE_MODULE_PATH
中查找,然后在模块目录/usr/share/cmake/Module
中查找,查找路径可以通过set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
设置。
配置查找模式:如果没找到这样的文件,find_package()会在~/.cmake/packages/或/usr/local/share/中的各个包目录中查找,寻找<库名字的大写>Config.cmake 或者 <库名字的小写>-config.cmake (比如库Opencv,它会查找/usr/local/share/OpenCV中的OpenCVConfig.cmake或opencv-config.cmake)
find_package指令可以生成一些cmake变量,如查找BZIP2包:
BZIP2_FOUND - system has BZip2
BZIP2_INCLUDE_DIR - the BZip2 include directory
BZIP2_LIBRARIES - Link these to use BZip2
BZIP2_NEED_PREFIX - this is set if the functions are prefixed with BZ2_ BZIP2_VERSION_STRING - the version of BZip2 found (since CMake 2.8.8)
因此可以在cmakelist中使用:
project(helloworld)
add_executable(helloworld hello.c)
find_package (BZip2)
if (BZIP2_FOUND)
include_directories(${BZIP_INCLUDE_DIRS})
target_link_libraries (helloworld ${BZIP2_LIBRARIES})
endif (BZIP2_FOUND)
编写属于自己的 FindHello 模块。
//查找hello.h头文件路径,保存在HELLO_INCLUDE_DIR中
find_path(HELLO_INCLUDE_DIR hello.h /usr/include/hello /usr/local/include/hello)
//查找hello库文件,保存在HELLO_LIBRARY中
find_library(HELLO_LIBRARY NAMES hello PATH /usr/lib /usr/local/lib)
if(HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
//设置查找标志
set(HELLO_FOUND TRUE)
endif(HELLO_INCLUDE_DIR AND HELLO_LIBRARY)
if(HELLO_FOUND)
if(NOT HELLO_FIND_QUIETLY)
message(STATUS "Found Hello: ${HELLO_LIBRARY}")ENDIF (NOT HELLO_FIND_QUIETLY)
endif(NOT HELLO_FIND_QUIETLY)
else(HELLO_FOUND)
if(HELLO_FIND_REQUIRED)
message(FATAL_ERROR "Could not find hello library")
endif(HELLO_FIND_REQUIRED)
endif(HELLO_FOUND)
QUIET
参数,对应编写中的HELLO_FIND_QUIETLY
,如果不指定该参数,就会打印相应的信息
REQUIRED
参数,其含义是指这个共享库是否是工程必须的,如果使用了这个参数,说明这个链接库是必备库,如果找不到这个链接库,则工程不能编译。对应于FindHELLO.cmake 模块中的 HELLO_FIND_REQUIRED 变量。
- 安装指令
通过make install
指令安装,同时可以通过CMAKE_INSTALL_PREFIX
变量添加前缀路径
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr ..
make
make install
安装动态库、静态库和目标二进制
install(TARGETS targets ...
[ [ARCHIVE | LIBRARY | RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS] permissions...
[CONFIGURATIONS [Debug | Release | ...]]
[COMPONENT <component>]
[OPTIONAL]][...]
)
install(TARGETS myrun mylib mystaticlib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
上面的例子会将:
可执行二进制myrun安装到${CMAKE_INSTALL_PREFIX}/bin
目录
动态库libmylib 安装到${CMAKE_INSTALL_PREFIX}/lib
目录
静态库libmystaticlib安装到${CMAKE_INSTALL_PREFIX}/libstatic
目录
安装文件
install(FILES files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。如果
默认不定义权限 PERMISSIONS,安装后的权限为:OWNER_WRITE, OWNER_READ,
GROUP_READ,和 WORLD_READ,即 644 权限。
非目标文件的可执行程序安装(比如脚本)
install(PROGRAMS files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
跟上面的 FILES 指令使用方法一样,唯一的不同是安装后权限为:
OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限
目录的安装:
INSTALL(DIRECTORY dirs... DESTINATION <dir>
[FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permissions...]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE] [PERMISSIONS permissions...]] [...])
DIRECTORY 后面连接的是所在 Source 目录的相对路径,但务必注意:abc 和 abc/有很大的区别。
如果目录名不以/结尾,那么这个目录将被安装为目标路径下的 abc,如果目录名以/结尾,代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
PATTERN 用于使用正则表达式进行过滤,
PERMISSIONS 用于指定 PATTERN 过滤后的文件权限。
INSTALL(DIRECTORY icons scripts/ DESTINATION share/myprojPATTERN "CVS" EXCLUDE
PATTERN "scripts/*"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READGROUP_EXECUTE GROUP_READ)
这条指令的执行结果是:
将 icons 目录安装到 /share/myproj,将 scripts/中的内容安装到/share/myproj
不包含目录名为 CVS 的目录,对于 scripts/* 文件指定权限为 OWNER_EXECUTE
OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ.
set(LIBRARY_OUTPUT_PATH ${projectname_SOURCE_DIR}/lib)
设置库文件生成路径set(EXECUTABLE_OUTPUT_PATH ${projectname_SOURCE_DIR}/bin)
设置可执行文件生成路径