CMakeLists.txt编写简述
以下为必须选项:
CMAKE_MINIMUM_REQUIRED (VERSION 3.5)
set(TARGET_NAME HelloWorld)
1. include path
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/inc)
#PROJECT_SOURCE_DIR 最顶层cmakelist位置
2. source code path
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/temp0 SRCS_LIST)
#AUX_SOURCE_DIRECTORY 源文件路径,所有都添加到生成.o
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/temp1 SRCS_LIST_TEMP1)
set(SRCS_LIST_TEMP2 ${PROJECT_SOURCE_DIR}…/…/temp.c)
#指定单独的源文件
3. lib path
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
4. set output path
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/out/bin)
#PROJECT_BINARY_DIR 执行编译命令的目录,比如新建的build目录即为PROJECT_BINARY_DIR
5.ADD_EXECUTABLE add src .o
ADD_EXECUTABLE(${TARGET_NAME} ${SRCS_LIST} ${SRCS_LIST_TEMP1} ${SRCS_LIST_TEMP2})
6.TARGET_LINK_LIBRARIES add dependence lib
TARGET_LINK_LIBRARIES(
${TARGET_NAME}
dmcli
cJSON
sqlite3
)
以下为可选项
1. copy func
file(GLOB header_files “./inc/*.h”)
#设置全局变量
file(COPY ${header_files} DESTINATION ${PROJECT_BINARY_DIR}/out/include)
2.-Wl,–start-group ${LIBS} -Wl,–end-group 多重包函依赖库(静态库/动态库)
FILE(GLOB LIBS “${PROJECT_SOURCE_DIR}/third-lib/*.a”)
TARGET_LINK_LIBRARIES(
${TARGET_NAME}
-Wl,–start-group ${LIBS} -Wl,–end-group
cJSON
}
3.MESSAGE消息打印
MESSAGE(STATUS "test ${PROJECT_SOURCE_DIR} : " ${PROJECT_SOURCE_DIR})
4.set CFLAGS
SET(CMAKE_C_FLAGS “-O0 -g”)
SET(CMAKE_CXX_FLAGS “-O0 -ggdb”)
#设置所需编译条件,比如 -g ,c++11支持等,都可以在此处设置
参考:CFLAGS简述
General Compiler and Linker Flags
Search Path and Library Linking Flags
-l[linalg]
=> Links to shared library or shared object - Specifically, it links to linalg.dll on Windows, liblinalg.so (on Unix-like oses like Linux, BSD, AIX, …) or linalg.dylib on MacOSX.
-L[/path/to/shared-libraries]
=> Add search path to shared libraries, directory containing *.so, *.dll or *.dlyb files such as libLinearAlgebra.so depending on the current operating system.
-I[/path/to/header-files]
Add search path to header files (.h) or (.hpp).
-D[FLAG] or -D[FLAG]=VALUE
Pass preprocessor flag #if FLAG …
GCC and Clang Most common compiler flags:
std - Specify the C++ version or ISO standard version.
-std=c++11 (ISO C++11)
-std=c++14 (ISO C++14)
-std=c++1z (ISO C++17)
-std=c++20 (C++20 experimental)
-std=gnu++ (ISO C++ with GNU extensions)
Verbosity - [W stands for warning]
-Wall
Turns on lots of compiler warning flags, specifically (-Waddress, -Wcomment, -Wformat, -Wbool-compare, -Wuninitialized, -Wunknown-pragmas, -Wunused-value, -Wunused-value …)
-Werror
Turn any warning into a compilation error.
-Wextra or just -W (see more)
Enables extra flags not enabled by -Wall, such as -Wsign-compare (C only), -Wtype-limits, -Wuninitialized …
-pendantic or -Wpendantic
Issue all warning required by ISO C and ISO C++ standard, it issues warning whenever there are compiler extensions non compliant to ISO C or C++ standard.
-Wconversion
-Wcast-align
-Wunnused
-Wshadow
-Wold-style-cast
-Wpointer-arith -Wcast-qual -Wmissing-prototypes -Wno-missing-braces
Output file: -o <outputfile>
g++ file.cpp -o file.bin
Common library flags
-lm - Compiles against the shared library libm (basic math library, mostly C only)
-lpthread - Compile against Posix threads shared library
Include Path - Directories containing headers files.
-I/path/to/include1 -I/path/to/include2 …
Compilation flags -D<flag name>
-DCOMPILE_VAR -> Enable flag COMPILE_VAR - It is equivalent to add to the code (#define COMPILE_VAR)
-DDO_SOMETHING=1 - Equivalent to add to the code #define DO_SOMETHING = 1
-DDISABLE_DEPRECATED_FUNCTIONS=0
Optmization - docs
-O0
No optmization, faster compilation time, better for debugging builds.
-O2
-O3
Higher level of optmization. Slower compile-time, better for production builds.
-OFast
Enables higher level of optmization than (-O3). It enables lots of flags as can be seen src (-ffloat-store, -ffsast-math, -ffinite-math-only, -O3 …)
-finline-functions
-m64
-funroll-loops
-fvectorize
-fprofile-generate
Misc
-fexceptions -fstack-protector-strong –param=ssp-buffer-size=4
Special Options
-g
=> Builds executable with debugging symbols for GDB GNU Debugger or LLDB Clang/LLVM Debugger. It should only be used during development for debugging builds.
-c
=> Compiler source(s) to object-code (input to linker). This option is better for incremental compilation when using multiple files.
-pie
=> Builds a dynamically linked position independent executable.
-static-pie
=> Builds a staticlaly linked position independent executable.
-shared
=> Build a shared library (.so or .dylib on U*nix-like Oses) or .dll on MS-Windows.
-fno-exceptions
=> Disable C++ exceptions (it may be better for embedded systems or anything where exceptiions may not be acceptable).
-fno-rtti
=> Disable RTTI (Runtime Type Information) - There many texts around where game and embedded systems developers report that they disable RTTI due to performance concerns.
-fvisibility=hidden
=> Make library symbols hidden by default, in a similar way to what happens in Windows DLLs where exported symbols must have the prefix __declspec(dllexport) or __declspec(dllimport). When all symbols are exported by default, it may increase the likelyhood of undefined behavior if there a multiple definitions of same symbol during linking. See more at:
Simple C++ Symbol Visibility Demo | LabJack
https://wiki.debian.org/Hardening
=> Lots of compiler flags for hardening security.
Linker Flags
Verbose
-Wl,–verbose
-Wl,–print-memory-usage
Directory which linker will search for libraries (*.so files on Unix; *.dylib on MacOSX and *.dll on Windows)
-L/path/to-directory
Strip Debug Information
-Wl,-s
Build Shared Library
-shared
Set Unix Shared Library SONAME (See)
–Wl,soname,<NAME>
–Wl,soname,libraryname.so.1
General Format of Linker Options
-Wl,–<OPTION>=<VALUE>
Windows-only (MINGW)
-Wl,–subsystem,console => Build for console subsystem.
-Wl,–subsystem,windows => Build for winodw subsystem.
-ld3d9 => Link against DirectX (d3d9.dll)
Windows-only DLL (Dynamic Linked Libraries)
-shared
-Wl,–export-all-symbols
-Wl,–enable-auto-import
Static link against LibGCC runtime library:
-static-libgcc
Static link against libstdC++ runtime library:
-static-libstdc++
Static link against Gfortran (GNU fortran) runtime library.
-static-libgfortran
Set Unix RPATH (Note Windows does not have rpath)
–Wl,rpath=/path/to/directory1;/path/to/directory2
Set Unix RPATH to executable current directory.
–Wl,rpath=$ORIGIN
Change the default dynamic linker (UNIX and Linux)
-Wl,-dynamic-linker,/path/to/linker/ld-linux.so.2.1
Common Unix Dependencies:
-lpthread => Link against POSIX threads library.
-ldl => Link against libdl library for dlopen(), dlclose(), APIs.
Exclude Runtime Libraries (gcc docs)
-nostartfiles => "Do not use the standard system startup files when linking. The standard system libraries are used normally, unless -nostdlib, -nolibc, or -nodefaultlibs is used."
-nodefaultlibs => Do not use the standard system libraries when linking.
-nolibc => Do not use the C library or system libraries tightly coupled with it when linking.
-nostdlib => Do not use the standard system startup files or libraries when linking.
Set heap size
-Wl,–heap,201561
Stack reserve size
-Wl,–stack,419525
Generate Linker Map (mostly used for embedded systems)
-Wl,-Map=linker-map.map
Use a custom linker script (embedded systems)
-Wl,T/path/to/linker-script.ld
Linker version script
-Wl,–version-script,criptfile
Eliminate dead-code or unused code for decreasing the program or firmware size (embedded systesm) - (Elinux)
-ffunction-sections -fdata-sections -Wl,–gc-sections
Miscellaneous
-Wl,–allow-multiple-definition
-fno-keep-inline-dllexport
-Wl,–lager-address-aware
-Wl,–image-base,358612
Files Generated by the Compiler
Object Files
*.o -> Generated on *NIX - Linux, MacOSX … by GCC or Clang
*.obj -> Windows
Binary Native Executable - Object Code
*NIX: Linux, MacOSX, FreeBSD -> Without extension.
Windows: *.exe
*.hex -> Extension of many compiled firmwares generated by embedded systems compilers such as proprietary compilers for Microcontrollers.
Shared Objects - Shared Libraries
*.dll -> Called dynamic linked libraries on Windows -> libplot.dll
*.so -> Called shared Object on Linux -> libplot.so
*.dylib -> Extension used on MacOSX.
Static Library
*.a - extension
Review See:
Things to remember when compiling and linking C/C++ programs · GitHub
Linker Options
GNU Linker Command Language => GNU Linker Script Command Language, widely used for embedded systems.
Man7.org - Shared Libraries
https://gcc.gnu.org/onlinedocs/gcc/Link-Options.html
https://interrupt.memfault.com/blog/get-the-most-out-of-the-linker-map-file
https://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html
Link time dead code and data elimination using GNU toolchain
https://www.avrfreaks.net/forum/keep-and-wl-gc-sections
Removing Unused Functions and Dead Code (Washigton University)
The why and how of RPATHs - Flameeyes
Creating relocatable Linux executables by setting RPATH with origin
Compiling NTL for Android
Building and Using DLLs Prev Chapter 4. Programming with Cygwin (MINGW - Windows)
5.ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(HelloWorld_Temp1)
#整体编译时,提供模块功能,到模块内继续寻找cmakelist.txt
6.add_library
add_library(hello_dynamic SHARED ${SRCS_LIST})
add_library(hello_static STATIC ${SRCS_LIST})
#生成动态库.so,静态库.a
7. find_package(***)
Find an external project, and load its settings.
Basic Signature and Module Mode
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
Finds and loads settings from an external project. ``<PackageName>_FOUND``will be set to indicate whether the package was found.
When the package is found package-specific information is provided through variables and :ref:`Imported Targets` documented by the package itself.
The ``QUIET`` option disables informational messages, including those indicating that the package cannot be found if it is not ``REQUIRED``.
The ``REQUIRED`` option stops processing with an error message if the package cannot be found
If the package configuration file cannot be found CMake will generate an error describing the problem unless the QUIET argument is specified. If REQUIRED is specified and the package is not found a fatal error is generated and the configure step stops executing. If <PackageName>_DIR has been set to a directory not containing a configuration file CMake will ignore it and search from scratch.
Package maintainers providing CMake package configuration files are encouraged to name and install them such that the Search Procedure outlined below will find them without requiring use of additional options.
示例
eg:结构
—inc
------hello.h
—src
------hello.c
—CMakeLists.txt
hello.h
#ifndef HELLO_H
#define HELLO_H
void PrintHello();
#endif
hello.c
#include "stdio.h"
#include "../inc/hello.h"
void PrintHello()
{
printf("hello\n");
}
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED (VERSION 3.5)
set(TARGET_NAME HelloWorld)
#1. include path
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/inc)
#PROJECT_SOURCE_DIR 最顶层cmakelist位置
#2. source code path
AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/ SRCS_LIST)
#AUX_SOURCE_DIRECTORY 源文件路径,所有都添加到生成.o
#AUX_SOURCE_DIRECTORY(${PROJECT_SOURCE_DIR}/src/temp1 SRCS_LIST_TEMP1)
#set(SRCS_LIST_TEMP2 ${PROJECT_SOURCE_DIR}…/…/temp.c)
#指定单独的源文件
#3. lib path
#LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
#4. set output path
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/out)
#PROJECT_BINARY_DIR 执行编译命令的目录,比如新建的build目录即为PROJECT_BINARY_DIR
#5.ADD_EXECUTABLE add src .o
#ADD_EXECUTABLE(${TARGET_NAME} ${SRCS_LIST} ${SRCS_LIST_TEMP1} ${SRCS_LIST_TEMP2})
#used to generate Executable file, exe need include main function.
#ADD_EXECUTABLE(${TARGET_NAME} ${SRCS_LIST})
#used to generate dynamic so
add_library(hello_dynamic SHARED ${SRCS_LIST})
add_library(hello_static STATIC ${SRCS_LIST})
#6.TARGET_LINK_LIBRARIES add dependence lib
#TARGET_LINK_LIBRARIES(
#${TARGET_NAME}
#cJSON
#sqlite3
#)