CMakeLists.txt 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. cmake_minimum_required(VERSION 3.16)
  2. project(stable-diffusion.cpp-rest
  3. VERSION 1.0.0
  4. DESCRIPTION "REST API server for stable-diffusion.cpp"
  5. LANGUAGES CXX
  6. )
  7. # Set C++ standard
  8. set(CMAKE_CXX_STANDARD 17)
  9. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  10. set(CMAKE_CXX_EXTENSIONS OFF)
  11. set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
  12. # Set build type if not specified
  13. if(NOT CMAKE_BUILD_TYPE)
  14. set(CMAKE_BUILD_TYPE Release)
  15. endif()
  16. find_program(CCACHE_FOUND ccache)
  17. if(CCACHE_FOUND)
  18. set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
  19. set(ENV{CCACHE_SLOPPINESS} time_macros)
  20. message(STATUS "ccache found, compilation results will be cached")
  21. endif()
  22. # Add cmake modules path
  23. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
  24. # Include dependencies
  25. include(FindDependencies)
  26. # Version detection from git
  27. find_package(Git QUIET)
  28. if(GIT_FOUND)
  29. # Get current git commit hash (short)
  30. execute_process(
  31. COMMAND ${GIT_EXECUTABLE} rev-parse --short=8 HEAD
  32. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  33. OUTPUT_VARIABLE GIT_COMMIT_HASH
  34. OUTPUT_STRIP_TRAILING_WHITESPACE
  35. ERROR_QUIET
  36. )
  37. # Get full git commit hash
  38. execute_process(
  39. COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
  40. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  41. OUTPUT_VARIABLE GIT_COMMIT_HASH_FULL
  42. OUTPUT_STRIP_TRAILING_WHITESPACE
  43. ERROR_QUIET
  44. )
  45. # Get current git tag (prefer annotated tags)
  46. execute_process(
  47. COMMAND ${GIT_EXECUTABLE} describe --tags --exact-match --abbrev=0
  48. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  49. OUTPUT_VARIABLE GIT_TAG
  50. OUTPUT_STRIP_TRAILING_WHITESPACE
  51. ERROR_QUIET
  52. )
  53. # Get git describe for fallback (e.g., v1.0.0-5-g12345678)
  54. execute_process(
  55. COMMAND ${GIT_EXECUTABLE} describe --tags --always --abbrev=8
  56. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  57. OUTPUT_VARIABLE GIT_DESCRIBE
  58. OUTPUT_STRIP_TRAILING_WHITESPACE
  59. ERROR_QUIET
  60. )
  61. # Get git branch
  62. execute_process(
  63. COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
  64. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  65. OUTPUT_VARIABLE GIT_BRANCH
  66. OUTPUT_STRIP_TRAILING_WHITESPACE
  67. ERROR_QUIET
  68. )
  69. # Check if working directory is clean
  70. execute_process(
  71. COMMAND ${GIT_EXECUTABLE} status --porcelain
  72. WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  73. OUTPUT_VARIABLE GIT_STATUS
  74. OUTPUT_STRIP_TRAILING_WHITESPACE
  75. ERROR_QUIET
  76. )
  77. if(NOT GIT_COMMIT_HASH)
  78. set(GIT_COMMIT_HASH "unknown")
  79. endif()
  80. if(NOT GIT_COMMIT_HASH_FULL)
  81. set(GIT_COMMIT_HASH_FULL "unknown")
  82. endif()
  83. if(NOT GIT_DESCRIBE)
  84. set(GIT_DESCRIBE "unknown")
  85. endif()
  86. if(NOT GIT_BRANCH)
  87. set(GIT_BRANCH "unknown")
  88. endif()
  89. # Determine if working directory is clean
  90. if(GIT_STATUS STREQUAL "")
  91. set(GIT_CLEAN "true")
  92. else()
  93. set(GIT_CLEAN "false")
  94. endif()
  95. else()
  96. set(GIT_COMMIT_HASH "unknown")
  97. set(GIT_COMMIT_HASH_FULL "unknown")
  98. set(GIT_TAG "")
  99. set(GIT_DESCRIBE "unknown")
  100. set(GIT_BRANCH "unknown")
  101. set(GIT_CLEAN "false")
  102. endif()
  103. # Determine version string
  104. if(GIT_TAG)
  105. # Release build with tag
  106. set(PROJECT_VERSION_FULL "${GIT_TAG}")
  107. set(PROJECT_VERSION_TYPE "release")
  108. elseif(GIT_DESCRIBE AND NOT GIT_DESCRIBE STREQUAL "unknown")
  109. # Development build with git describe
  110. set(PROJECT_VERSION_FULL "${GIT_DESCRIBE}")
  111. set(PROJECT_VERSION_TYPE "development")
  112. else()
  113. # Fallback to commit hash
  114. set(PROJECT_VERSION_FULL "g${GIT_COMMIT_HASH}")
  115. set(PROJECT_VERSION_TYPE "development")
  116. endif()
  117. # Add dirty suffix if working directory is not clean
  118. if(GIT_CLEAN STREQUAL "false")
  119. set(PROJECT_VERSION_FULL "${PROJECT_VERSION_FULL}-dirty")
  120. endif()
  121. # Build timestamp
  122. string(TIMESTAMP BUILD_TIMESTAMP "%Y-%m-%dT%H:%M:%SZ" UTC)
  123. # Set project variables
  124. set(PROJECT_VERSION_COMMIT "${GIT_COMMIT_HASH}")
  125. set(PROJECT_VERSION_COMMIT_FULL "${GIT_COMMIT_HASH_FULL}")
  126. set(PROJECT_VERSION_BRANCH "${GIT_BRANCH}")
  127. set(PROJECT_VERSION_CLEAN "${GIT_CLEAN}")
  128. set(PROJECT_VERSION_BUILD_TIME "${BUILD_TIMESTAMP}")
  129. # Display version information
  130. message(STATUS "Version Information:")
  131. message(STATUS " Version: ${PROJECT_VERSION_FULL}")
  132. message(STATUS " Type: ${PROJECT_VERSION_TYPE}")
  133. message(STATUS " Commit: ${GIT_COMMIT_HASH}")
  134. message(STATUS " Branch: ${GIT_BRANCH}")
  135. message(STATUS " Clean: ${GIT_CLEAN}")
  136. message(STATUS " Build Time: ${BUILD_TIMESTAMP}")
  137. # Generate version header file
  138. configure_file(
  139. "${CMAKE_CURRENT_SOURCE_DIR}/include/version.h.in"
  140. "${CMAKE_CURRENT_BINARY_DIR}/include/version.h"
  141. @ONLY
  142. )
  143. # Option for CUDA support
  144. option(SD_CUDA_SUPPORT "Enable CUDA support in stable-diffusion.cpp" ON)
  145. # Option for building Web UI
  146. option(BUILD_WEBUI "Build the web UI and bundle it with the server" ON)
  147. # Option for PAM authentication support
  148. option(ENABLE_PAM_AUTH "Enable PAM (Pluggable Authentication Modules) support" ON)
  149. # Find CUDA if support is enabled
  150. if(SD_CUDA_SUPPORT)
  151. find_package(CUDAToolkit REQUIRED)
  152. message(STATUS "CUDA Toolkit found: ${CUDAToolkit_VERSION}")
  153. endif()
  154. # ExternalProject for stable-diffusion.cpp
  155. include(ExternalProject)
  156. # Set up external project for stable-diffusion.cpp
  157. ExternalProject_Add(stable-diffusion.cpp
  158. GIT_REPOSITORY https://github.com/leejet/stable-diffusion.cpp.git
  159. GIT_TAG master-347-6103d86
  160. SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/stable-diffusion.cpp-src"
  161. BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/stable-diffusion.cpp-build"
  162. CMAKE_ARGS
  163. -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
  164. -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/stable-diffusion.cpp-install
  165. -DSD_CUDA=${SD_CUDA_SUPPORT}
  166. -DSD_BUILD_EXAMPLES=OFF
  167. BUILD_COMMAND ${CMAKE_COMMAND} --build . --config ${CMAKE_BUILD_TYPE}
  168. INSTALL_COMMAND ${CMAKE_COMMAND} --install . --config ${CMAKE_BUILD_TYPE}
  169. LOG_DOWNLOAD ON
  170. LOG_CONFIGURE ON
  171. LOG_BUILD ON
  172. LOG_INSTALL ON
  173. )
  174. # Get the include directories and libraries from the external project
  175. ExternalProject_Get_Property(stable-diffusion.cpp SOURCE_DIR BINARY_DIR)
  176. # Set include directories for the external project
  177. set(SD_CPP_INCLUDE_DIRS
  178. ${CMAKE_CURRENT_BINARY_DIR}/stable-diffusion.cpp-install/include
  179. ${SOURCE_DIR}
  180. ${SOURCE_DIR}/ggml/include
  181. )
  182. # Set library directories
  183. set(SD_CPP_LIB_DIR ${CMAKE_CURRENT_BINARY_DIR}/stable-diffusion.cpp-install/lib)
  184. # Build Web UI if enabled
  185. if(BUILD_WEBUI)
  186. # Check if Node.js and npm are available
  187. find_program(NPM_EXECUTABLE npm)
  188. if(NPM_EXECUTABLE)
  189. message(STATUS "npm found: ${NPM_EXECUTABLE}")
  190. message(STATUS "Web UI will be built and bundled")
  191. # Set the output directory for the web UI
  192. set(WEBUI_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/webui)
  193. set(WEBUI_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/webui)
  194. message(STATUS "Git commit hash for UI versioning: ${PROJECT_VERSION_FULL}")
  195. # Get build timestamp
  196. string(TIMESTAMP BUILD_TIMESTAMP "%Y-%m-%dT%H:%M:%SZ" UTC)
  197. # Create custom target for building the web UI
  198. add_custom_target(webui-build
  199. COMMAND ${CMAKE_COMMAND} -E echo "Building Web UI..."
  200. # Clean build/webui directory before building
  201. COMMAND ${CMAKE_COMMAND} -E remove_directory ${WEBUI_OUTPUT_DIR}
  202. COMMAND ${CMAKE_COMMAND} -E make_directory ${WEBUI_OUTPUT_DIR}
  203. # Generate version file
  204. COMMAND ${CMAKE_COMMAND} -E echo "{\"version\":\"${PROJECT_VERSION_FULL}\",\"commit\":\"${PROJECT_VERSION_COMMIT}\",\"branch\":\"${PROJECT_VERSION_BRANCH}\",\"buildTime\":\"${BUILD_TIMESTAMP}\",\"type\":\"${PROJECT_VERSION_TYPE}\",\"clean\":${PROJECT_VERSION_CLEAN}}" > ${WEBUI_SOURCE_DIR}/public/version.json
  205. COMMAND ${NPM_EXECUTABLE} install
  206. COMMAND ${NPM_EXECUTABLE} run build-static
  207. WORKING_DIRECTORY ${WEBUI_SOURCE_DIR}
  208. COMMENT "Building Web UI with npm (version: ${PROJECT_VERSION_FULL})"
  209. VERBATIM
  210. )
  211. # Set a variable that can be used by the server
  212. set(WEBUI_BUILT ON)
  213. set(WEBUI_PATH ${WEBUI_OUTPUT_DIR} CACHE PATH "Path to built web UI files")
  214. message(STATUS "Web UI output directory: ${WEBUI_OUTPUT_DIR}")
  215. else()
  216. message(WARNING "npm not found. Web UI will not be built. Install Node.js to enable Web UI building.")
  217. set(BUILD_WEBUI OFF)
  218. endif()
  219. else()
  220. message(STATUS "Web UI building is disabled")
  221. endif()
  222. # Add subdirectories
  223. add_subdirectory(src)
  224. # Create an interface target for stable-diffusion.cpp
  225. add_library(sd-cpp INTERFACE)
  226. add_dependencies(sd-cpp stable-diffusion.cpp)
  227. target_include_directories(sd-cpp INTERFACE ${SD_CPP_INCLUDE_DIRS})
  228. target_link_directories(sd-cpp INTERFACE ${SD_CPP_LIB_DIR})
  229. # Set up libraries list based on CUDA support
  230. set(SD_LIBS
  231. stable-diffusion
  232. ggml
  233. ggml-base
  234. ggml-cpu
  235. )
  236. if(SD_CUDA_SUPPORT)
  237. list(APPEND SD_LIBS ggml-cuda)
  238. list(APPEND SD_LIBS CUDA::cudart CUDA::cublas CUDA::cuda_driver)
  239. endif()
  240. target_link_libraries(sd-cpp INTERFACE ${SD_LIBS})
  241. # Print configuration summary
  242. message(STATUS "Configuration Summary:")
  243. message(STATUS " Build Type: ${CMAKE_BUILD_TYPE}")
  244. message(STATUS " C++ Standard: ${CMAKE_CXX_STANDARD}")
  245. message(STATUS " CUDA Support: ${SD_CUDA_SUPPORT}")
  246. message(STATUS " Build Web UI: ${BUILD_WEBUI}")
  247. message(STATUS " PAM Authentication: ${ENABLE_PAM_AUTH}")
  248. if(BUILD_WEBUI AND WEBUI_BUILT)
  249. message(STATUS " Web UI Path: ${WEBUI_PATH}")
  250. endif()