CMake構建學習筆記8-OpenSceneGraph庫的構建

charlee44發表於2024-08-27

1. 概論

在連續構建了zlib、libpng、libjpeg、libtiff、giflib以及freetype這幾個庫之後,接下來我們就要來一個大的,構建OpenSceneGraph這樣大型庫。OpenSceneGraph(簡稱 OSG)是一個高效能、跨平臺的三維圖形應用程式框架,廣泛應用於科學視覺化、模擬模擬、遊戲開發等領域。理論上來說,上述幾個庫不是OSG的必須依賴庫,但是將它們作為依賴庫構建,OSG的功能就更完整。

2. 構建過程

構建OSG庫的關鍵指令如下所示:

# 配置CMake      
cmake .. -G "$Generator" -A x64 `
    -DCMAKE_BUILD_TYPE=RelWithDebInfo `
    -DCMAKE_PREFIX_PATH="$InstallDir" `
    -DCMAKE_INSTALL_PREFIX="$InstallDir" `
    -DGIFLIB_LIBRARY="$InstallDir/lib/giflib.lib" `
    -DBUILD_OSG_APPLICATIONS=ON `
    -DBUILD_OSG_EXAMPLES=OFF `
    -DBUILD_OSG_DEPRECATED_SERIALIZERS=OFF `
    -DCMAKE_RELWITHDEBINFO_POSTFIX=""

# 構建階段,指定構建型別
cmake --build . --config RelWithDebInfo -- /m:8

# 安裝階段,指定構建型別和安裝目標
cmake --build . --config RelWithDebInfo --target install

再次強調一遍,如果要優先找到提前編譯好的依賴庫,就需要設定CMAKE_PREFIX_PATH變數。我們把所有的庫都安裝到同一個目錄中並設定成CMAKE_PREFIX_PATH變數,這樣在構建新的依賴庫的時候,CMake就能準確查詢到相關的依賴庫。不過,也會出現少數查詢不到的情況,這裡的GIFLIB就沒有查詢到,因此我們手動設定GIFLIB_LIBRARY。

其餘的幾個OSG提供的自定義構建選項中:

  1. BUILD_OSG_APPLICATIONS表示是否構建基於OSG的可執行程式,例如osgviewer、osgconv等。這樣的應用工具還是非常實用的,推薦還是進行構建。
  2. BUILD_OSG_EXAMPLES表示是否構建示例程式,像這樣的構建選項,為了加快構建速度一般不用進行構建。
  3. BUILD_OSG_DEPRECATED_SERIALIZERS看到這個DEPRECATED字眼就不用參與進行構建了,反正也是非必須項。
  4. CMAKE_RELWITHDEBINFO_POSTFIX表示是否給RelWithDebInfo方式編譯的結果增加字尾,預設會增加字尾“rd”,這裡將其設定為空。

3. 經驗總結

構建像OSG這樣的大型程式庫,最好多看看CMake配置完成後的輸出資訊,例如這裡的輸出資訊如下所示:

CMake Deprecation Warning at CMakeLists.txt:16 (CMAKE_MINIMUM_REQUIRED):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.22631.
-- Could NOT find EGL (missing: EGL_LIBRARY EGL_INCLUDE_DIR) 
-- Checking windows version...
-- 64 bit architecture detected
-- Could NOT find Jasper (missing: JASPER_LIBRARIES JASPER_INCLUDE_DIR) 
-- Could NOT find LibXml2 (missing: LIBXML2_INCLUDE_DIR) 
CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (GTA).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindGTA.cmake:11 (INCLUDE)
  CMakeLists.txt:751 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (GTA).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindGTA.cmake:15 (INCLUDE)
  CMakeLists.txt:751 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Checking for module 'gta'
--   No package 'gta' found
-- Trying to find DCMTK expecting DCMTKConfig.cmake
-- Trying to find DCMTK expecting DCMTKConfig.cmake - failed
-- Trying to find DCMTK relying on FindDCMTK.cmake
-- Please set DCMTK_DIR and re-run configure (missing: DCMTK_config_INCLUDE_DIR DCMTK_dcmdata_INCLUDE_DIR DCMTK_dcmimage_INCLUDE_DIR DCMTK_dcmimgle_INCLUDE_DIR DCMTK_dcmjpeg_INCLUDE_DIR DCMTK_dcmjpls_INCLUDE_DIR DCMTK_dcmnet_INCLUDE_DIR DCMTK_dcmpstat_INCLUDE_DIR DCMTK_dcmqrdb_INCLUDE_DIR DCMTK_dcmsign_INCLUDE_DIR DCMTK_dcmsr_INCLUDE_DIR DCMTK_dcmtls_INCLUDE_DIR DCMTK_ofstd_INCLUDE_DIR DCMTK_oflog_INCLUDE_DIR)
-- Could NOT find GStreamer (missing: GSTREAMER_INCLUDE_DIRS GSTREAMER_LIBRARIES GSTREAMER_VERSION GSTREAMER_BASE_INCLUDE_DIRS GSTREAMER_BASE_LIBRARIES GSTREAMER_APP_INCLUDE_DIRS GSTREAMER_APP_LIBRARIES GSTREAMER_PBUTILS_INCLUDE_DIRS GSTREAMER_PBUTILS_LIBRARIES)
-- Could NOT find SDL2 (missing: SDL2_LIBRARY SDL2_INCLUDE_DIR) 
-- Could NOT find SDL (missing: SDL_LIBRARY SDL_INCLUDE_DIR) 
CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (Poppler-glib).  This can
  lead to problems in calling code that expects `find_package` result
  variables (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindPoppler-glib.cmake:2 (INCLUDE)
  CMakeLists.txt:761 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (Poppler-glib).  This can
  lead to problems in calling code that expects `find_package` result
  variables (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindPoppler-glib.cmake:6 (INCLUDE)
  CMakeLists.txt:761 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Checking for module 'cairo'
--   No package 'cairo' found
-- Checking for module 'poppler-glib'
--   No package 'poppler-glib' found
CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (RSVG).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindRSVG.cmake:2 (INCLUDE)
  CMakeLists.txt:762 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (RSVG).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindRSVG.cmake:6 (INCLUDE)
  CMakeLists.txt:762 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Checking for module 'librsvg-2.0>=2.35'
--   No package 'librsvg-2.0' found
-- Checking for module 'cairo'
--   No package 'cairo' found
CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (GtkGl).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindGtkGl.cmake:2 (INCLUDE)
  CMakeLists.txt:763 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (PkgConfig)
  does not match the name of the calling package (GtkGl).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  C:/Program Files/CMake/share/cmake-3.26/Modules/FindPkgConfig.cmake:99 (find_package_handle_standard_args)
  CMakeModules/FindGtkGl.cmake:6 (INCLUDE)
  CMakeLists.txt:763 (FIND_PACKAGE)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Checking for module 'gtk+-2.0'
--   No package 'gtk+-2.0' found
-- Checking for module 'gtkglext-win32-1.0'
--   No package 'gtkglext-win32-1.0' found
-- Could NOT find Fontconfig (missing: FONTCONFIG_LIBRARY FONTCONFIG_INCLUDE_DIR) 
-- osgText will not be linked with FontConfig library
CMake Warning (dev) at C:/Program Files/CMake/share/cmake-3.26/Modules/Documentation.cmake:30 (message):
  Policy CMP0106 is not set: The Documentation module is removed.  Run "cmake
  --help-policy CMP0106" for policy details.  Use the cmake_policy command to
  set the policy and suppress this warning.

  Documentation.cmake is VTK-specific code and should not be used in non-VTK
  projects.  This logic in this module is best shipped with the project using
  it rather than with CMake.
Call Stack (most recent call first):
  CMakeLists.txt:1162 (INCLUDE)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- The following OPTIONAL packages have been found:

 * OpenGL
 * Freetype
 * FBX
 * GDAL
 * CURL
 * GIFLIB
 * JPEG
 * ZLIB
 * PNG
 * TIFF
 * Threads

-- The following OPTIONAL packages have not been found:

 * EGL
 * ilmbase
 * Inventor
 * Jasper
 * OpenEXR
 * OpenCascade
 * LibXml2
 * COLLADA
 * GTA
 * LibVNCServer
 * DCMTK
 * FFmpeg
 * GStreamer
 * GLIB
 * DirectShow
 * SDL2
 * SDL
 * Poppler-glib
 * RSVG
 * RSVG
 * GtkGl
 * DirectInput
 * GtkGl
 * DirectInput
 * NVTT
 * NVTT
 * ZeroConf
 * LIBLAS
 * ZeroConf
 * LIBLAS
 * QuickTime
 * LIBLAS
 * QuickTime
 * QuickTime
 * Fontconfig

-- Configuring done (3.5s)
-- Generating done (15.6s)
-- Build files have been written to: C:/Github/BuildCppDependency/Windows/OpenSceneGraph-OpenSceneGraph-3.6.5/build

看起來非常的繁雜,但是其實沒什麼內容,只要是在說有的依賴庫找不到,有的依賴庫找到了。最後還把找到的依賴庫和沒找到的依賴庫都列出來了。關於這一點,我們只需要重點關心我們需要的依賴庫是否識別成功了即可,以為有的大型庫的依賴項非常多,不太可能一次性就把完整的依賴項準備好。

除此之外,還可以看看程式庫提供的自定義構建選項,暫時用不到的暫時設為OFF不進行構建了,例如一些測試程式或者案例程式。CMake提供的功能非常強大,有的功能還會遠端拉取程式碼,這個時候往往會因為國內網速的原因導致終端構建配置。不過,提供這種功能的模組往往是非必須的構建選項,可以找一找將其取消掉,在重新進行構建。

總之,多看看的構建配置的輸出資訊和選項,熟能生巧,有了經驗以後就能又快又好地構建依賴庫了。

相關文章