Việc mở rộng vĩ mô, được trả lời bởi Yantao Xie thực sự mở rộng tầm mắt của tôi!
Tôi cũng thấy hướng dẫn bên dưới đi kèm với một số ví dụ cụ thể, rất hữu ích để hiểu khái niệm phạm vi biến.
Trích dẫn từ Learn cmake trong 15 phút :
Trong CMake, bạn có thể sử dụng một cặp lệnh function
/ endfunction
để xác định một hàm. Đây là một trong những nhân đôi giá trị số của đối số của nó, sau đó in kết quả:
function(doubleIt VALUE)
math(EXPR RESULT "${VALUE} * 2")
message("${RESULT}")
endfunction()
doubleIt("4") # Prints: 8
Các hàm chạy trong phạm vi riêng của chúng. Không có biến nào được xác định trong một hàm gây ô nhiễm phạm vi của người gọi. Nếu bạn muốn trả về một giá trị, bạn có thể chuyển tên của một biến vào hàm của mình, sau đó gọi set
lệnh với đối số đặc biệt PARENT_SCOPE
:
function(doubleIt VARNAME VALUE)
math(EXPR RESULT "${VALUE} * 2")
set(${VARNAME} "${RESULT}" PARENT_SCOPE) # Set the named variable in caller's scope
endfunction()
doubleIt(RESULT "4") # Tell the function to set the variable named RESULT
message("${RESULT}") # Prints: 8
Tương tự, một cặp lệnh macro
/ endmacro
xác định một macro. Không giống như các hàm, macro chạy trong cùng phạm vi với trình gọi của chúng. Do đó, tất cả các biến được xác định bên trong macro đều được đặt trong phạm vi của người gọi. Chúng ta có thể thay thế chức năng trước bằng chức năng sau:
macro(doubleIt VARNAME VALUE)
math(EXPR ${VARNAME} "${VALUE} * 2") # Set the named variable in caller's scope
endmacro()
doubleIt(RESULT "4") # Tell the macro to set the variable named RESULT
message("${RESULT}") # Prints: 8
Cả hàm và macro đều chấp nhận một số lượng đối số tùy ý. Các đối số không tên được hiển thị cho hàm dưới dạng danh sách, thông qua một biến đặc biệt có tên ARGN
.
Đây là một hàm tăng gấp đôi mọi đối số mà nó nhận được, in từng đối số trên một dòng riêng biệt:
function(doubleEach)
foreach(ARG ${ARGN}) # Iterate over each argument
math(EXPR N "${ARG} * 2") # Double ARG's numeric value; store result in N
message("${N}") # Print N
endforeach()
endfunction()
doubleEach(5 6 7 8) # Prints 10, 12, 14, 16 on separate lines
function
vàmacro
: ngữ nghĩa củareturn()
: Khi được sử dụng trong amacro
, bạn sẽ không trả về từ macro mà từ hàm gọi.