步驟 8:加入自訂命令和產生檔案¶
假設為了本教學的目的,我們決定永遠不使用平台的 log
和 exp
函數,而是希望產生一個預先計算的值的表格,以便在 mysqrt
函數中使用。在本節中,我們將在建置過程中建立表格,然後將該表格編譯到我們的應用程式中。
首先,讓我們移除 MathFunctions/CMakeLists.txt
中對 log
和 exp
函數的檢查。然後從 mysqrt.cxx
中移除對 HAVE_LOG
和 HAVE_EXP
的檢查。同時,我們可以移除 #include <cmath>
。
在 MathFunctions
子目錄中,已提供名為 MakeTable.cxx
的新原始程式檔來產生表格。
檢視該檔案後,我們可以發現該表格是以有效的 C++ 程式碼產生的,並且輸出檔案名稱是作為引數傳入的。
下一步是建立 MathFunctions/MakeTable.cmake
。然後,將適當的命令新增至該檔案,以建置 MakeTable
可執行檔,然後將其作為建置過程的一部分執行。需要幾個命令才能完成此操作。
首先,我們為 MakeTable
新增一個可執行檔。
add_executable(MakeTable MakeTable.cxx)
建立可執行檔後,我們使用 target_link_libraries()
將 tutorial_compiler_flags
新增至我們的可執行檔。
target_link_libraries(MakeTable PRIVATE tutorial_compiler_flags)
然後,我們新增一個自訂命令,指定如何透過執行 MakeTable 來產生 Table.h
。
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
接下來,我們必須讓 CMake 知道 mysqrt.cxx
相依於產生的檔案 Table.h
。這是透過將產生的 Table.h
新增至程式庫 SqrtLibrary
的原始檔清單來完成。
add_library(SqrtLibrary STATIC
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
我們還必須將目前的二進位目錄新增至包含目錄的清單中,以便 mysqrt.cxx
可以找到並包含 Table.h
。
target_include_directories(SqrtLibrary PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)
# link SqrtLibrary to tutorial_compiler_flags
最後一步,我們需要在 MathFunctions/CMakeLists.txt
的頂部包含 MakeTable.cmake
。
include(MakeTable.cmake)
現在讓我們使用產生的表格。首先,修改 mysqrt.cxx
以包含 Table.h
。接下來,我們可以重寫 mysqrt
函數以使用表格
double mysqrt(double x)
{
if (x <= 0) {
return 0;
}
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
result = 0.1;
}
double delta = x - (result * result);
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
return result;
}
}
}
執行 cmake
可執行檔或 cmake-gui
來設定專案,然後使用您選擇的建置工具來建置它。
當這個專案建置時,它會先建置 MakeTable
可執行檔。然後它將執行 MakeTable
來產生 Table.h
。最後,它會編譯包含 Table.h
的 mysqrt.cxx
以產生 MathFunctions
程式庫。
執行 Tutorial 可執行檔並驗證它正在使用表格。