1# Copyright (C) 2023 Huawei Device Co., Ltd.
2# Licensed under the Apache License, Version 2.0 (the "License");
3# you may not use this file except in compliance with the License.
4# You may obtain a copy of the License at
5#
6#     http://www.apache.org/licenses/LICENSE-2.0
7#
8# Unless required by applicable law or agreed to in writing, software
9# distributed under the License is distributed on an "AS IS" BASIS,
10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11# See the License for the specific language governing permissions and
12# limitations under the License.
13
14cmake_minimum_required(VERSION 3.10)
15project(LumeShaderCompiler)
16
17if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
18    # enable multi-processor compilation
19    add_compile_options(/MP)
20endif()
21
22#workaround for "PythonInterp" finds old version of python...
23find_package (Python3 COMPONENTS Interpreter)
24set(Python_EXECUTABLE ${Python3_EXECUTABLE} CACHE STRING "" FORCE)
25
26if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
27    #make a staticly linked executable with hidden / gc symbols. (to minimize)
28    #also we use libc++ so build with clang.
29    set(CMAKE_THREAD_PREFER_PTHREAD true)
30    SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
31    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -stdlib=libc++ -Wl,--gc-sections -Wl,--exclude-libs,ALL")
32    add_compile_options(-stdlib=libc++ -fvisibility=hidden -ffunction-sections -fdata-sections)
33    #workaround for spirv-tools forcibly linking LIBRT with out actually needing it (blocks static link)
34    set(LIBRT "" CACHE STRING "" FORCE)
35endif()
36
37include(ExternalProject)
38find_package(PythonInterp 3)
39if(NOT ${PYTHONINTERP_FOUND})
40    message(FATAL_ERROR "Python interpreter required to build shaderc/spirv-tools etc..")
41endif()
42set(CMAKE_CXX_STANDARD 17)
43set(CMAKE_CXX_STANDARD_REQUIRED ON)
44set(CMAKE_CXX_EXTENSIONS OFF)
45set_property(GLOBAL PROPERTY USE_FOLDERS ON)
46
47function(get_all_targets _result _dir)
48    get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
49    foreach(_subdir IN LISTS _subdirs)
50        get_all_targets(${_result} "${_subdir}")
51    endforeach()
52    get_property(_sub_targets DIRECTORY "${_dir}" PROPERTY BUILDSYSTEM_TARGETS)
53    set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
54endfunction()
55
56function(add_subdirectory_with_folder _folder_name _folder)
57    add_subdirectory(${_folder} ${ARGN} EXCLUDE_FROM_ALL)
58
59    get_all_targets(_targets "${_folder}")
60    foreach(_target IN LISTS _targets)
61        set_target_properties(
62            ${_target}
63            PROPERTIES FOLDER "${_folder_name}"
64        )
65    endforeach()
66endfunction()
67
68cmake_policy(SET CMP0077 OLD)
69
70#set default and modified options for glslang
71set(ENABLE_CTEST OFF CACHE BOOL "" FORCE)
72set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
73set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
74set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "" FORCE)
75set(ENABLE_SPVREMAPPER OFF CACHE BOOL "" FORCE)
76set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "" FORCE)
77set(ENABLE_HLSL OFF CACHE BOOL "" FORCE)
78set(ENABLE_OPT OFF CACHE BOOL "" FORCE)
79
80#set default and modified options for spirv-tools
81set(SKIP_SPIRV_TOOLS_INSTALL ON CACHE BOOL "" FORCE)
82set(SPIRV_BUILD_COMPRESSION OFF CACHE BOOL "" FORCE)
83set(SPIRV_WERROR OFF CACHE BOOL "" FORCE)
84set(SPIRV_WARN_EVERYTHING OFF CACHE BOOL "" FORCE)
85set(SPIRV_COLOR_TERMINAL ON CACHE BOOL "" FORCE)
86set(SPIRV_LOG_DEBUG OFF CACHE BOOL "" FORCE)
87set(SPIRV_SKIP_EXECUTABLES ON CACHE BOOL "" FORCE)
88set(SPIRV_SKIP_TESTS ON CACHE BOOL "" FORCE)
89set(SPIRV_CHECK_CONTEXT ON CACHE BOOL "" FORCE)
90set(SPIRV_TOOLS_INSTALL_EMACS_HELPERS OFF CACHE BOOL "" FORCE)
91
92#set default and modified options for spirv-cross
93set(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS OFF CACHE BOOL "")
94set(SPIRV_CROSS_CLI OFF CACHE BOOL "" FORCE)
95set(SPIRV_CROSS_ENABLE_CPP OFF CACHE BOOL "" FORCE)
96set(SPIRV_CROSS_ENABLE_C_API OFF CACHE BOOL "" FORCE)
97set(SPIRV_CROSS_ENABLE_TESTS OFF CACHE BOOL "" FORCE)
98set(SPIRV_CROSS_ENABLE_GLSL ON CACHE BOOL "" FORCE)
99set(SPIRV_CROSS_ENABLE_HLSL OFF CACHE BOOL "" FORCE)
100set(SPIRV_CROSS_ENABLE_MSL OFF CACHE BOOL "" FORCE)
101set(SPIRV_CROSS_ENABLE_REFLECT OFF CACHE BOOL "" FORCE)
102set(SPIRV_CROSS_ENABLE_UTIL OFF CACHE BOOL "" FORCE)
103set(SPIRV_CROSS_SKIP_INSTALL ON CACHE BOOL "" FORCE)
104
105string(REPLACE "/foundation" ";" TEMP_PATH ${CMAKE_CURRENT_LIST_FILE})
106list(GET TEMP_PATH 0 OHOS_ROOT_PATH)
107set(SPIRV_TOOLS_PATH "${OHOS_ROOT_PATH}/third_party/spirv-tools")
108# temp solution
109#set(SPIRV_CROSS_PATH "${OHOS_ROOT_PATH}/third_party/spirv-cross")
110set(SPIRV_CROSS_PATH "${OHOS_ROOT_PATH}/third_party/skia/third_party/externals/spirv-cross")
111set(GLSLANG_PATH "${OHOS_ROOT_PATH}/third_party/glslang")
112set(KHRONOS_GL "${OHOS_ROOT_PATH}/third_party/openGLES/api/GL")
113set(KHRONOS_KHR "${OHOS_ROOT_PATH}/third_party/EGL/api/KHR")
114
115# SPIRV-Headers causes "INTERFACE_LIBRARY targets may only have whitelisted properties.", but we don't need to include is as it's header only
116add_library(SPIRV-Headers INTERFACE)
117target_sources(SPIRV-Headers INTERFACE "${OHOS_ROOT_PATH}/third_party/spirv-headers")
118set(SPIRV-Headers_SOURCE_DIR "${OHOS_ROOT_PATH}/third_party/spirv-headers")
119message(STATUS "spirv-tools: ${SPIRV_TOOLS_PATH} spirv-cross: ${SPIRV_CROSS_PATH} spirv-headers: ${SPIRV-Headers_SOURCE_DIR} glslang: ${GLSLANG_PATH}")
120add_subdirectory(${SPIRV_TOOLS_PATH} "3rdPartyST" EXCLUDE_FROM_ALL)
121add_subdirectory(${GLSLANG_PATH} "3rdPartyGL" EXCLUDE_FROM_ALL)
122add_subdirectory(${SPIRV_CROSS_PATH} "3rdPartCross" EXCLUDE_FROM_ALL )
123#execute_process(COMMAND git describe --all WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/glslang" OUTPUT_VARIABLE GLSLANG_VERSION COMMAND_ERROR_IS_FATAL ANY OUTPUT_STRIP_TRAILING_WHITESPACE)
124#string(REGEX REPLACE "tags/([0-9]+).([0-9]+).([0-9]+)" "(\\1 * 10000) + (\\2 * 100) + (\\3)" GLSLANG_VERSION ${GLSLANG_VERSION})
125set(GLSLANG_VERSION "120000")
126#math(EXPR GLSLANG_VERSION "${GLSLANG_VERSION}")
127
128set(sources
129    src/main.cpp
130    src/shader_type.h
131    src/default_limits.h
132    src/default_limits.cpp
133    src/io/dev/FileMonitor.h
134    src/io/dev/FileMonitor.cpp
135    src/lume/Log.h
136    src/lume/log/Logger.h
137    src/lume/log/Logger.cpp
138    src/lume/log/LoggerOutput.cpp
139    src/array_view.h
140    src/spirv_cross_helpers_gles.cpp
141    src/spirv_cross_helpers_gles.h
142    src/spirv_cross_helper_structs_gles.h
143)
144source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${sources})
145
146set(executable "LumeShaderCompiler")
147add_executable(${executable} ${sources})
148target_include_directories(${executable} PRIVATE
149    include
150    src
151	${KHRONOS_GL}
152	${KHRONOS_KHR}
153)
154
155target_link_libraries(${executable} PRIVATE glslang SPIRV)
156target_link_libraries(${executable} PRIVATE SPIRV-Tools-opt
157    spirv-cross-core
158    spirv-cross-glsl
159    $<$<AND:$<CXX_COMPILER_ID:GNU>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:stdc++fs>
160    $<$<AND:$<CXX_COMPILER_ID:Clang>,$<VERSION_LESS:$<CXX_COMPILER_VERSION>,9.0>>:stdc++fs>
161)
162
163
164if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
165    target_link_libraries(${executable} PRIVATE c++abi)
166    set_target_properties(${executable} PROPERTIES LINK_FLAGS_RELEASE -s)
167endif()
168
169target_compile_definitions(${executable} PRIVATE GLSLANG_VERSION=${GLSLANG_VERSION} )
170target_compile_definitions(${executable} PRIVATE LUME_PUBLIC= WIN32_LEAN_AND_MEAN=1)
171
172# Strip all debug logging code from a release build.
173target_compile_definitions(${executable} PRIVATE
174    "$<$<CONFIG:Release>:LUME_LOG_NO_DEBUG>"
175    "$<$<CONFIG:MinSizeRel>:LUME_LOG_NO_DEBUG>"
176)
177
178# Tool for generating shader from template and snippet blocks.
179set(sources
180    src/json.h
181    $<$<BOOL:${MSVC_IDE}>:src/json.natvis>
182    src/snippet.cpp
183)
184source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${sources})
185