CMake入門,實例與模板

CMake 入門,實例與模板

什麼是 CMake

CMake 允許開發者編寫一種平臺無關的 CMakeList.txt 文件來定製整個編譯流程,然後再根據目標用戶的平臺進一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。從而做到「Write once, run everywhere」。

在 linux 平臺下使用 CMake 生成 Makefile 並編譯的流程如下:

  1. 編寫 CMake 配置文件 CMakeLists.txt 。
  2. 執行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(ccmake 和 cmake 的區別在於前者提供了一個交互式的界面)。其中, PATH 是 CMakeLists.txt 所在的目錄。
1
2
3
4
5
# 一般是創建一個build目錄進行編譯,CMakeLists.txt在build目錄的上一層
mkdir ./build
cd build
cmake ..
make
  1. 使用 make 命令進行編譯。

模板1 單一源文件

適用於編譯某一目錄中的指定源文件(test01.cpp),且沒有調用第三方庫,最終編譯成一個可執行文件的情況。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 1,設置工程名稱,叫「Demo1」,在Linux下可以隨便設置
project( Demo1 )

# 2,設置 CMake 最低版本號,我電腦裝的是3.5
cmake_minimum_required( VERSION 3.5 )

# 3,設定編譯參數
set(CMAKE_CXX_STANDARD    11)  # 指定 C++ 版本
set(CMAKE_BUILD_TYPE "Release")  # 調試使用Debug,可以查看中間變量;發布使用Release,運行速度快

# 4,把源碼編譯成一個可執行文件,文件名為test01(可以隨便取名),會保存在當前目錄下
add_executable( test01 test01.cpp )
1
2
3
├── template1
│    ├── CMakeLists.txt
│    └── test02.cpp

運行過程

1
2
3
4
5
cd template1
mkdir ./build
cd build
cmake ..
make

會在build目錄下 生成 可執行文件 test01

模板2 多個源文件在一個目錄

適用於編譯同一目錄中的多個源文件,且沒有調用第三方庫,最終編譯成一個可執行文件的情況。 源文件 .c .cpp .cc 和 include文件都放在一個目錄下,只有一個目錄,沒有子目錄。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 1,設置工程名稱,叫「Demo2」(在Linux下可以隨便設置)
project( Demo2 )

# 2,設置 CMake 最低版本號,我電腦裝的是3.5
cmake_minimum_required( VERSION 3.5 )

# 3,設定編譯參數
set(CMAKE_CXX_STANDARD    11)  # 指定 C++ 版本
set(CMAKE_BUILD_TYPE "Release")  # 調試使用Debug,可以查看中間變量;發布使用Release,運行速度快

# 4,把當前文件夾下的源碼列表(文件後綴匹配的那些文件)存到變量 SRCS 中
file( GLOB SRCS *.c *.cpp *.cc *.h *.hpp )

# 5,把源碼編譯成一個可執行文件,文件名為test02(可以隨便取名),會保存在當前目錄下
add_executable( test02 ${SRCS} )
1
2
3
4
├── template2
│    ├── CMakeLists.txt
│    ├── test02.cpp
│    └── test02.h

可以有更多源文件和include文件,只要放在一個目錄下就可以

運行過程

1
2
3
4
5
cd template2
mkdir ./build
cd build
cmake ..
make

會在build目錄下 生成 可執行文件 test02

模板3 源文件和include文件在不同的目錄

適用於cpp文件在一個文件夾(src/中),頭文件在另一個文件夾內(include/中),且沒有調用第三方庫,最終編譯成一個可執行文件的情況。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 1,設置工程名稱,叫「Demo3」,在Linux下可以隨便設置
project( Demo3 )

# 2,設置 CMake 最低版本號,我電腦裝的是3.5
cmake_minimum_required( VERSION 3.5 )

# 3,設定編譯參數
set(CMAKE_CXX_STANDARD    11)  # 指定 C++ 版本
set(CMAKE_BUILD_TYPE "Release")  # 調試使用Debug,可以查看中間變量;發布使用Release,運行速度快

# 4,設定源碼列表,查找指定目錄下的所有源文件,並將名稱保存到 DIR_SRCS 變量中
aux_source_directory(./src/ DIR_SRC)

# 5,設定頭文件路徑
include_directories(./include/)

# 6,把源碼編譯成一個可執行文件,文件名為test03(可以隨便取名),會保存在當前目錄下
add_executable( test03 ${DIR_SRC} )

目錄結構

1
2
3
4
5
6
7
├── template3
│   ├── CMakeLists.txt
│   ├── include
│   │   └── count.h
│   └── src
│       ├── count.cpp
│       └── test03.cpp

運行過程

1
2
3
4
5
cd template3
mkdir ./build
cd build
cmake ..
make

會在build目錄下 生成 可執行文件 test03

模板4 源文件和include文件在不同的目錄,調用安裝在系統中的第三方庫

適用於cpp文件在一個文件夾(src/中),頭文件在另一個文件夾內(include/中),且調用了第三方庫(比如已經安裝在系統中的opencv),最終編譯成一個可執行文件的情況。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 1,設置工程名稱,叫「Demo4」,在Linux下可以隨便設置
project( Demo4 )

# 2,設置 CMake 最低版本號,我電腦裝的是3.5
cmake_minimum_required( VERSION 3.5 )

# 3,設定編譯參數
set(CMAKE_CXX_STANDARD    11)  # 指定 C++ 版本
set(CMAKE_BUILD_TYPE "Release")  # 調試使用Debug,可以查看中間變量;發布使用Release,運行速度快

# 4,設定源碼列表,查找指定目錄(都放在./src/中)中的所有源文件,並將名稱保存到 DIR_SRCS 變量中
aux_source_directory(./src/ DIR_SRC)

# 5,設定頭文件路徑(還可以增加其他第三方庫的頭文件路徑)
include_directories(./include/)

# 6,查找並添加OpenCV的頭文件目錄
find_package(OpenCV REQUIRED)  
# message( STATUS "    version: ${OpenCV_VERSION}" )  # 我電腦上裝的是opencv3.3.1
# message( STATUS "    include path: ${OpenCV_INCLUDE_DIRS}" )
include_directories(${OpenCV_INCLUDE_DIRS})

# 7,把源碼編譯成一個可執行文件,文件名為test04(可以隨便取名),會保存在當前目錄下
add_executable( test04 ${DIR_SRC} )
target_link_libraries( test04 ${OpenCV_LIBS} )  # 可執行文件名 連結 OpenCV庫
1
2
3
4
5
6
├── template4
│   ├── CMakeLists.txt
│   ├── include
│   │   └── test04.h
│   └── src
│       └── test04.cpp

運行過程

1
2
3
4
5
6
7
## 要先安裝 opencv ubuntu下
sudo apt install libopencv-dev
cd template4
mkdir ./build
cd build
cmake ..
make

會在build目錄下 生成 可執行文件 test04

模板5 分成多個子模塊,每個子模塊有自己的CMakeLists.txt, 生成執行文件,靜態庫,動態庫

使用cmake構建一個工程,每個子模塊都有自己的cmakelists,該工程創建了兩個靜態庫和一個動態庫,另外生成一個調用這些庫的可執行文件。 CMakeLists.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
cmake_minimum_required(VERSION 3.5)  # cmake版本最低要求
project(test5)  # 設置工程名稱

set(CMAKE_CXX_STANDARD 11)  # 指定 C++ 版本
set(CMAKE_BUILD_TYPE Release)  # 調試使用Debug,可以查看中間變量;發布使用Release,運行速度快

message("${PROJECT_SOURCE_DIR}=" ${PROJECT_SOURCE_DIR})

# 這裡設置好路徑後,進入子模塊的cmake時不用再次設置
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)  # 設置可執行文件的輸出目錄
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)	   # 設置庫文件的輸出目錄

ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/source/add)     # 會調用該目錄中的CMakeLists.txt進行編譯生成靜態庫
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/source/sub)     # 會調用該目錄中的CMakeLists.txt進行編譯生成靜態庫
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/source/mul)     # 會調用該目錄中的CMakeLists.txt進行編譯生成動態庫
ADD_SUBDIRECTORY(${PROJECT_SOURCE_DIR}/source/main)    # 會調用該目錄中的CMakeLists.txt進行編譯生成可執行文件

add/CMakeLists.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 編譯成靜態庫, libadd.a
# 方法一:逐個添加cpp源文件,適用於文件數量少的情況
# add_library(add ${CMAKE_CURRENT_SOURCE_DIR}/add.cpp ${CMAKE_CURRENT_SOURCE_DIR}/add3.cpp)

# 方法二:搜索有的cpp源文件,並將列表存儲在一個變量中,適用於文件多的情況
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} SRC_LIST)
add_library(add ${SRC_LIST})

# 方法三:遞歸遍歷目錄,獲取所有的CPP文件,適用於多級目錄的情況
# file(GLOB_RECURSE cpp_files  ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)  # GLOB是不遞歸
# add_library(add ${cpp_files})

mul/CMakeLists.txt

1
2
# 編譯成動態庫libmul.so
add_library(mul SHARED ${CMAKE_CURRENT_SOURCE_DIR}/mul.cpp)

sub/CMakeLists.txt

1
2
# 編譯成靜態庫, libsub.a
add_library(sub ${CMAKE_CURRENT_SOURCE_DIR}/sub.cpp)

main/CMakeLists.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 添加頭文件路徑,會檢索目錄中的所有頭文件
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../add
                    ${CMAKE_CURRENT_SOURCE_DIR}/../sub
                    ${CMAKE_CURRENT_SOURCE_DIR}/../mul
                    ${CMAKE_CURRENT_SOURCE_DIR}/../main)

# 把源碼編譯成一個可執行文件
add_executable(main ./main.cpp)
# 添加連結庫,動態和靜態都行
target_link_libraries(main add sub mul)

目錄結構

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
├── template5
│   ├── CMakeLists.txt
│   ├── readme.md
│   ├── run.sh
│   └── source
│       ├── add
│       │   ├── add3.cpp
│       │   ├── add3.h
│       │   ├── add.cpp
│       │   ├── add.h
│       │   └── CMakeLists.txt
│       ├── main
│       │   ├── CMakeLists.txt
│       │   └── main.cpp
│       ├── mul
│       │   ├── CMakeLists.txt
│       │   ├── mul.cpp
│       │   └── mul.h
│       └── sub
│           ├── CMakeLists.txt
│           ├── sub.cpp
│           └── sub.h

運行過程

1
2
3
4
5
6
7
8
cd template5
rm -rf build
mkdir build
cd build/
cmake ..
make  
cd ../bin
./main

模板6 分成多個子模塊,只有1個CMakeLists.txt, 生成執行文件,靜態庫,動態庫

使用cmake構建一個工程,包含多個子模塊,但子模塊沒有自己的cmakelists,整個項目只有一個CMakeLists.txt, 該工程創建了兩個靜態庫和一個動態庫,另外生成一個調用這些庫的可執行文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cmake_minimum_required(VERSION 3.5)  # cmake版本最低要求
project(test6)  # 設置工程名稱

set(CMAKE_CXX_STANDARD 11)  # 指定 C++ 版本
set(CMAKE_BUILD_TYPE Release)  # 調試使用Debug,可以查看中間變量;發布使用Release,運行速度快

message("${PROJECT_SOURCE_DIR}=" ${PROJECT_SOURCE_DIR})

# 這裡設置好路徑後,進入子模塊的cmake時不用再次設置
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)  # 設置可執行文件的輸出目錄
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)	   # 設置庫文件的輸出目錄

# 編譯add,生成靜態庫
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/add ADD_SRC_LIST)
add_library(add ${ADD_SRC_LIST})

# 編譯sub,生成靜態庫
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/sub SUB_SRC_LIST)
add_library(sub ${SUB_SRC_LIST})

# 編譯mul,生成動態庫
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/mul MUL_SRC_LIST)
add_library(mul SHARED ${MUL_SRC_LIST})

# 添加頭文件路徑,用於編譯可執行文件
include_directories(./source/add
                    ./source/sub
                    ./source/mul)

# 編譯main,生成可執行文件
add_executable(main ${CMAKE_CURRENT_SOURCE_DIR}/source/main/main.cpp)
target_link_libraries(main add sub mul)  # 連結所有庫

目錄結構

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
├── template6
│   ├── CMakeLists.txt
│   ├── readme.md
│   ├── run.sh
│   └── source
│       ├── add
│       │   ├── add3.cpp
│       │   ├── add3.h
│       │   ├── add.cpp
│       │   └── add.h
│       ├── main
│       │   └── main.cpp
│       ├── mul
│       │   ├── mul.cpp
│       │   └── mul.h
│       └── sub
│           ├── sub.cpp
│           └── sub.h

運行過程

1
2
3
4
5
6
7
8
cd template6
rm -rf build
mkdir build
cd build/
cmake ..
make 
cd ../bin
./main

常用命令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Note:cmake中不區分大小寫。

# 設置變量,方便後面自動配置,進入子模塊的cmake時不用再次設置
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)  # 設置可執行文件的輸出目錄
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)	   # 設置庫文件的輸出目錄

# 設定源碼列表,查找指定目錄下的所有源文件,並將名稱保存到 DIR_SRCS 變量中
aux_source_directory(./src/ DIR_SRC)

# 設定頭文件查找路徑,可以將所有頭文件路徑都添加到這裡面
include_directories(./include/
                    ./source/sub)

# 查找並添加OpenCV的頭文件目錄,在target_link_libraries()中需要進行動態連結
find_package(OpenCV REQUIRED) 

# 編譯子模塊,會自動調用子模塊中的Cmakelists.txt進行編譯
add_subdirectory(sub)

# 將${ADD_SRC_LIST}中的所有源碼編譯生成靜態庫add
add_library(add ${ADD_SRC_LIST})

# 將${SRCS}中的所有源碼編譯成一個可執行文件,文件名為main
add_executable( main ${SRCS} )
# 編譯可執行文件之後,添加動態連結庫,會連結靜態庫subadd和opencv庫
target_link_libraries(main subadd ${OpenCV_LIBS})

# 列印一些日誌信息
message("PROJECT_SOURCE_DIR=" ${PROJECT_SOURCE_DIR})

常用變量

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Note:cmake中不區分大小寫。

# 工程頂層目錄
${CMAKE_SOURCE_DIR} ${PROJECT_SOURCE_DIR}

# 當前處理的 CMakeLists.txt 所在路徑
${CMAKE_CURRENT_SOURCE_DIR}

# 返回Cmakelists.txt開頭通過 PROJECT 指令定義的項目名稱
${PROJECT_NAME}

# 分別用來重新定義最終結果(可執行文件、動靜態庫文件)的存放目錄
${EXECUTABLE_OUTPUT_PATH} ${LIBRARY_OUTPUT_PATH}

附加1 交叉編譯 CH32V203

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
cmake_minimum_required(VERSION 3.20)

# 工具鏈設置
set(TOOLPATH  D:/0wch/toolchain/RISCVEmbeddedGCC/bin/riscv-none-embed-)

if (WIN32)
	MESSAGE(STATUS "Now is windows!")
    set(CMAKE_C_COMPILER ${TOOLPATH}gcc.exe)
    set(CMAKE_CXX_COMPILER ${TOOLPATH}g++.exe)
    set(CMAKE_ASM_COMPILER ${TOOLPATH}gcc.exe)
    set(CMAKE_AR ${TOOLPATH}ar.exe)
    set(CMAKE_OBJCOPY ${TOOLPATH}objcopy.exe)
    set(CMAKE_OBJDUMP ${TOOLPATH}objdump.exe)
    set(SIZE ${TOOLPATH}size.exe)
elseif (UNIX)
	MESSAGE(STATUS "Now is UNIX-like OS!")
    set(CMAKE_C_COMPILER ${TOOLPATH}gcc)
    set(CMAKE_CXX_COMPILER ${TOOLPATH}g++)
    set(CMAKE_ASM_COMPILER ${TOOLPATH}gcc)
    set(CMAKE_AR ${TOOLPATH}ar)
    set(CMAKE_OBJCOPY ${TOOLPATH}objcopy)
    set(CMAKE_OBJDUMP ${TOOLPATH}objdump)
    set(SIZE ${TOOLPATH}size)
else ()
    MESSAGE(STATUS "Unsupported system!")
endif ()

# 項目設置
project(ch32v203-ninja C CXX ASM)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_C_STANDARD 99)

# 編譯參數 一般不用改
add_compile_options(-march=rv32imac -mabi=ilp32 -mcmodel=medany -msmall-data-limit=8 -mno-save-restore)
add_compile_options(-fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -fno-common)

# 編譯等級
add_compile_options(-O2)

# 編譯信息等級
add_compile_options(-Wall)

# 頭文件路徑
include_directories(APP
                    Core
                    Debug 
                    Peripheral/inc)

# 宏定義
# add_definitions(-DDEBUG=1)

# 源碼文件
file(GLOB_RECURSE SOURCES 
                "APP/*.c"
                "Core/core_riscv.c" 
                "Debug/debug.c"
                "Peripheral/src/*.c" 
                "Startup/startup_ch32v20x_D6.S"
                )

# 連結參數
set(LINKER_SCRIPT  ${CMAKE_SOURCE_DIR}/Ld/Link.ld)
add_link_options(
                -march=rv32imac -mabi=ilp32
                -nostartfiles 
                -Xlinker --gc-sections  
                -Wl,--print-memory-usage
                -Wl,-Map,${PROJECT_NAME}.map 
                --specs=nano.specs 
                --specs=nosys.specs)
add_link_options(-T ${LINKER_SCRIPT})

# 編譯可執行文件
add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})

# 連結靜態庫
# target_link_libraries(${PROJECT_NAME}.elf printfloat)

# 輸出hex和bin
set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
set(LST_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.lst)
add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
        COMMAND ${CMAKE_OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
        COMMAND ${CMAKE_OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
        COMMAND ${CMAKE_OBJDUMP} --all-headers --demangle --disassemble $<TARGET_FILE:${PROJECT_NAME}.elf> > ${LST_FILE}
        COMMAND ${SIZE} --format=berkeley $<TARGET_FILE:${PROJECT_NAME}.elf>
)

Link.ld文件

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
ENTRY( _start )

__stack_size = 2048;

PROVIDE( _stack_size = __stack_size );


MEMORY
{  
/* CH32V20x_D6 - CH32V203F6-CH32V203G6-CH32V203K6-CH32V203C6 */
	FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 32K
	RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 10K

/* CH32V20x_D6 - CH32V203K8-CH32V203C8-CH32V203G8-CH32V203F8 */
	/* FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K
	RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K */
 
/* CH32V20x_D8 - CH32V203RB
   CH32V20x_D8W - CH32V208x
   FLASH + RAM supports the following configuration
   FLASH-128K + RAM-64K
   FLASH-144K + RAM-48K
   FLASH-160K + RAM-32K

	FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 160K
	RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
*/
}


SECTIONS
{

	.init :
	{
		_sinit = .;
		. = ALIGN(4);
		KEEP(*(SORT_NONE(.init)))
		. = ALIGN(4);
		_einit = .;
	} >FLASH AT>FLASH

  .vector :
  {
      *(.vector);
	  . = ALIGN(64);
  } >FLASH AT>FLASH

	.text :
	{
		. = ALIGN(4);
		*(.text)
		*(.text.*)
		*(.rodata)
		*(.rodata*)
		*(.glue_7)
		*(.glue_7t)
		*(.gnu.linkonce.t.*)
		. = ALIGN(4);
	} >FLASH AT>FLASH 

	.fini :
	{
		KEEP(*(SORT_NONE(.fini)))
		. = ALIGN(4);
	} >FLASH AT>FLASH

	PROVIDE( _etext = . );
	PROVIDE( _eitcm = . );	

	.preinit_array  :
	{
	  PROVIDE_HIDDEN (__preinit_array_start = .);
	  KEEP (*(.preinit_array))
	  PROVIDE_HIDDEN (__preinit_array_end = .);
	} >FLASH AT>FLASH 
	
	.init_array     :
	{
	  PROVIDE_HIDDEN (__init_array_start = .);
	  KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
	  KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
	  PROVIDE_HIDDEN (__init_array_end = .);
	} >FLASH AT>FLASH 
	
	.fini_array     :
	{
	  PROVIDE_HIDDEN (__fini_array_start = .);
	  KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
	  KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
	  PROVIDE_HIDDEN (__fini_array_end = .);
	} >FLASH AT>FLASH 
	
	.ctors          :
	{
	  /* gcc uses crtbegin.o to find the start of
	     the constructors, so we make sure it is
	     first.  Because this is a wildcard, it
	     doesn't matter if the user does not
	     actually link against crtbegin.o; the
	     linker won't look for a file to match a
	     wildcard.  The wildcard also means that it
	     doesn't matter which directory crtbegin.o
	     is in.  */
	  KEEP (*crtbegin.o(.ctors))
	  KEEP (*crtbegin?.o(.ctors))
	  /* We don't want to include the .ctor section from
	     the crtend.o file until after the sorted ctors.
	     The .ctor section from the crtend file contains the
	     end of ctors marker and it must be last */
	  KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
	  KEEP (*(SORT(.ctors.*)))
	  KEEP (*(.ctors))
	} >FLASH AT>FLASH 
	
	.dtors          :
	{
	  KEEP (*crtbegin.o(.dtors))
	  KEEP (*crtbegin?.o(.dtors))
	  KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
	  KEEP (*(SORT(.dtors.*)))
	  KEEP (*(.dtors))
	} >FLASH AT>FLASH 

	.dalign :
	{
		. = ALIGN(4);
		PROVIDE(_data_vma = .);
	} >RAM AT>FLASH	

	.dlalign :
	{
		. = ALIGN(4); 
		PROVIDE(_data_lma = .);
	} >FLASH AT>FLASH

	.data :
	{
    	*(.gnu.linkonce.r.*)
    	*(.data .data.*)
    	*(.gnu.linkonce.d.*)
		. = ALIGN(8);
    	PROVIDE( __global_pointer$ = . + 0x800 );
    	*(.sdata .sdata.*)
		*(.sdata2.*)
    	*(.gnu.linkonce.s.*)
    	. = ALIGN(8);
    	*(.srodata.cst16)
    	*(.srodata.cst8)
    	*(.srodata.cst4)
    	*(.srodata.cst2)
    	*(.srodata .srodata.*)
    	. = ALIGN(4);
		PROVIDE( _edata = .);
	} >RAM AT>FLASH

	.bss :
	{
		. = ALIGN(4);
		PROVIDE( _sbss = .);
  	    *(.sbss*)
        *(.gnu.linkonce.sb.*)
		*(.bss*)
     	*(.gnu.linkonce.b.*)		
		*(COMMON*)
		. = ALIGN(4);
		PROVIDE( _ebss = .);
	} >RAM AT>FLASH

	PROVIDE( _end = _ebss);
	PROVIDE( end = . );

    .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size :
    {
        PROVIDE( _heap_end = . );   
        . = ALIGN(4);
        PROVIDE(_susrstack = . );
        . = . + __stack_size;
        PROVIDE( _eusrstack = .);
    } >RAM 

}
记录并分享
Built with Hugo
Theme Stack designed by Jimmy