CMakeLists.txt 9.2 KB

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