1#############################################################################
2# $Id: CMakeChecks.cmake 620276 2020-11-19 12:59:05Z gouriano $
3#############################################################################
4#
5# Note:
6# This file is included before everything else
7# Anything related to the initial state should go early in this file!
8
9
10if("${CMAKE_GENERATOR}" STREQUAL "Xcode")
11    if(NOT DEFINED XCODE)
12        set(XCODE ON)
13    endif()
14endif()
15
16string(TIMESTAMP NCBI_TIMESTAMP_START "%s")
17string(TIMESTAMP _start)
18message("Started: ${_start}")
19
20#############################################################################
21# Source tree description
22#
23set(NCBI_DIRNAME_RUNTIME bin)
24set(NCBI_DIRNAME_ARCHIVE lib)
25if (WIN32)
26    set(NCBI_DIRNAME_SHARED ${NCBI_DIRNAME_RUNTIME})
27else()
28    set(NCBI_DIRNAME_SHARED ${NCBI_DIRNAME_ARCHIVE})
29endif()
30set(NCBI_DIRNAME_SRC             src)
31set(NCBI_DIRNAME_INCLUDE         include)
32set(NCBI_DIRNAME_COMMON_INCLUDE  common)
33set(NCBI_DIRNAME_CFGINC          inc)
34set(NCBI_DIRNAME_INTERNAL        internal)
35set(NCBI_DIRNAME_EXPORT          cmake)
36set(NCBI_DIRNAME_TESTING         testing)
37set(NCBI_DIRNAME_SCRIPTS         scripts)
38set(NCBI_DIRNAME_COMMON_SCRIPTS  scripts/common)
39set(NCBI_DIRNAME_BUILDCFG ${NCBI_DIRNAME_SRC}/build-system)
40set(NCBI_DIRNAME_CMAKECFG ${NCBI_DIRNAME_SRC}/build-system/cmake)
41
42
43if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/build-system/cmake/CMake.NCBIptb.cmake")
44    set(_this_root     ${CMAKE_CURRENT_SOURCE_DIR}/..)
45else()
46    set(_this_root     ${CMAKE_SOURCE_DIR})
47endif()
48get_filename_component(_this_root  "${_this_root}"     ABSOLUTE)
49get_filename_component(top_src_dir "${CMAKE_CURRENT_LIST_DIR}/../../.."   ABSOLUTE)
50
51set(NCBI_TREE_ROOT    ${_this_root})
52set(NCBI_SRC_ROOT     ${NCBI_TREE_ROOT}/${NCBI_DIRNAME_SRC})
53set(NCBI_INC_ROOT     ${NCBI_TREE_ROOT}/${NCBI_DIRNAME_INCLUDE})
54set(NCBITK_TREE_ROOT  ${top_src_dir})
55set(NCBITK_SRC_ROOT   ${NCBITK_TREE_ROOT}/${NCBI_DIRNAME_SRC})
56set(NCBITK_INC_ROOT   ${NCBITK_TREE_ROOT}/${NCBI_DIRNAME_INCLUDE})
57if (NOT EXISTS "${NCBI_SRC_ROOT}")
58    set(NCBI_SRC_ROOT   ${NCBI_TREE_ROOT})
59endif()
60if (NOT EXISTS "${NCBI_INC_ROOT}")
61    set(NCBI_INC_ROOT   ${NCBI_TREE_ROOT})
62endif()
63
64set(build_root      ${CMAKE_BINARY_DIR})
65set(builddir        ${CMAKE_BINARY_DIR})
66set(includedir0     ${NCBI_INC_ROOT})
67set(includedir      ${NCBI_INC_ROOT})
68set(incdir          ${CMAKE_BINARY_DIR}/${NCBI_DIRNAME_CFGINC})
69set(incinternal     ${NCBI_INC_ROOT}/${NCBI_DIRNAME_INTERNAL})
70
71set(NCBI_DIRNAME_BUILD  build)
72#if (DEFINED NCBI_EXTERNAL_TREE_ROOT)
73if (OFF)
74    string(FIND ${CMAKE_BINARY_DIR} ${NCBI_TREE_ROOT} _pos_root)
75    string(FIND ${CMAKE_BINARY_DIR} ${NCBI_SRC_ROOT}  _pos_src)
76    if(NOT "${_pos_root}" LESS "0" AND "${_pos_src}" LESS "0" AND NOT "${CMAKE_BINARY_DIR}" STREQUAL "${NCBI_TREE_ROOT}")
77        get_filename_component(NCBI_BUILD_ROOT "${CMAKE_BINARY_DIR}/.." ABSOLUTE)
78	    get_filename_component(NCBI_DIRNAME_BUILD ${CMAKE_BINARY_DIR} NAME)
79    else()
80        get_filename_component(NCBI_BUILD_ROOT "${CMAKE_BINARY_DIR}" ABSOLUTE)
81    endif()
82else()
83    get_filename_component(NCBI_BUILD_ROOT "${CMAKE_BINARY_DIR}/.." ABSOLUTE)
84    get_filename_component(NCBI_DIRNAME_BUILD ${CMAKE_BINARY_DIR} NAME)
85endif()
86
87set(NCBI_CFGINC_ROOT   ${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_CFGINC})
88
89get_filename_component(incdir "${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_CFGINC}" ABSOLUTE)
90if(ON)
91    if(WIN32 OR XCODE)
92        set(incdir          ${incdir}/$<CONFIG>)
93    endif()
94else()
95    if (WIN32)
96        set(incdir          ${incdir}/\$\(Configuration\))
97    elseif (XCODE)
98        set(incdir          ${incdir}/\$\(CONFIGURATION\))
99    endif()
100endif()
101
102set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_RUNTIME}")
103set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_SHARED}")
104set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_ARCHIVE}")
105
106set(NCBI_TREE_CMAKECFG "${CMAKE_CURRENT_LIST_DIR}")
107get_filename_component(NCBI_TREE_BUILDCFG "${CMAKE_CURRENT_LIST_DIR}/.."   ABSOLUTE)
108
109if(EXISTS ${NCBI_TREE_ROOT}/CMake.CustomConfig.txt)
110	include(${NCBI_TREE_ROOT}/CMake.CustomConfig.txt)
111endif()
112
113############################################################################
114# OS-specific settings
115include(${NCBI_TREE_CMAKECFG}/CMakeChecks.os.cmake)
116
117#############################################################################
118# Build configurations and compiler definitions
119include(${NCBI_TREE_CMAKECFG}/CMakeChecks.compiler.cmake)
120
121#############################################################################
122if(NOT DEFINED NCBI_DIRNAME_PREBUILT)
123    set(_prebuilt_loc)
124    if ("${NCBI_COMPILER}" STREQUAL "MSVC")
125        set(_prebuilt_loc "CMake-VS")
126        if ("${NCBI_COMPILER_VERSION}" LESS "1900")
127            set(_prebuilt_loc ${_prebuilt_loc}2015)
128        elseif ("${NCBI_COMPILER_VERSION}" LESS "1924")
129            set(_prebuilt_loc ${_prebuilt_loc}2017)
130        else()
131            set(_prebuilt_loc ${_prebuilt_loc}2019)
132        endif()
133        set(_prebuilt_loc ${_prebuilt_loc}${NCBI_PTBCFG_INSTALL_SUFFIX})
134        if (BUILD_SHARED_LIBS)
135            set(_prebuilt_loc ${_prebuilt_loc}-DLL)
136        else()
137            set(_prebuilt_loc ${_prebuilt_loc})
138        endif()
139    elseif(XCODE)
140        set(_prebuilt_loc "CMake-Xcode${NCBI_COMPILER_VERSION}")
141        if (BUILD_SHARED_LIBS)
142            set(_prebuilt_loc ${_prebuilt_loc}-DLL)
143        else()
144            set(_prebuilt_loc ${_prebuilt_loc})
145        endif()
146    else()
147        set(_prebuilt_loc "CMake-${NCBI_COMPILER}${NCBI_COMPILER_VERSION}-${CMAKE_BUILD_TYPE}")
148        set(_prebuilt_loc ${_prebuilt_loc}${NCBI_PTBCFG_INSTALL_SUFFIX})
149        if (BUILD_SHARED_LIBS)
150            set(_prebuilt_loc ${_prebuilt_loc}DLL)
151        endif()
152    endif()
153    set(NCBI_DIRNAME_PREBUILT  ${_prebuilt_loc})
154endif()
155
156set(_tk_includedir      ${NCBITK_INC_ROOT})
157set(_tk_incinternal     ${NCBITK_INC_ROOT}/${NCBI_DIRNAME_INTERNAL})
158set(_inc_dirs)
159foreach( _inc IN ITEMS ${includedir} ${incinternal} ${_tk_includedir} ${_tk_incinternal})
160    if (IS_DIRECTORY ${_inc})
161        list(APPEND _inc_dirs ${_inc})
162    endif()
163endforeach()
164list(REMOVE_DUPLICATES _inc_dirs)
165include_directories(${incdir} ${_inc_dirs})
166include_regular_expression("^.*[.](h|hpp|c|cpp|inl|inc)$")
167if(OFF)
168message("CMAKE_SOURCE_DIR    = ${CMAKE_SOURCE_DIR}")
169message("NCBI_TREE_ROOT      = ${NCBI_TREE_ROOT}")
170message("NCBI_SRC_ROOT       = ${NCBI_SRC_ROOT}")
171message("NCBI_INC_ROOT       = ${NCBI_INC_ROOT}")
172message("NCBITK_TREE_ROOT    = ${NCBITK_TREE_ROOT}")
173message("NCBITK_SRC_ROOT     = ${NCBITK_SRC_ROOT}")
174message("NCBITK_INC_ROOT     = ${NCBITK_INC_ROOT}")
175message("NCBI_BUILD_ROOT     = ${NCBI_BUILD_ROOT}")
176message("NCBI_CFGINC_ROOT    = ${NCBI_CFGINC_ROOT}")
177message("NCBI_TREE_BUILDCFG  = ${NCBI_TREE_BUILDCFG}")
178message("NCBI_TREE_CMAKECFG  = ${NCBI_TREE_CMAKECFG}")
179message("include_directories(${incdir} ${_inc_dirs})")
180endif()
181
182if (DEFINED NCBI_EXTERNAL_TREE_ROOT)
183    set(NCBI_EXTERNAL_BUILD_ROOT  ${NCBI_EXTERNAL_TREE_ROOT}/${NCBI_DIRNAME_PREBUILT})
184    if (NOT EXISTS ${NCBI_EXTERNAL_BUILD_ROOT}/${NCBI_DIRNAME_EXPORT}/${NCBI_PTBCFG_INSTALL_EXPORT}.cmake)
185        message(FATAL_ERROR "${NCBI_PTBCFG_INSTALL_EXPORT} was not found in ${NCBI_EXTERNAL_BUILD_ROOT}/${NCBI_DIRNAME_EXPORT}")
186    endif()
187endif()
188
189#set(CMAKE_MODULE_PATH "${NCBI_SRC_ROOT}/build-system/cmake/" ${CMAKE_MODULE_PATH})
190list(APPEND CMAKE_MODULE_PATH "${NCBI_TREE_CMAKECFG}")
191
192
193#############################################################################
194# Basic checks
195include(${NCBI_TREE_CMAKECFG}/CMakeChecks.basic-checks.cmake)
196
197#############################################################################
198# External libraries
199include(${NCBI_TREE_CMAKECFG}/CMake.NCBIComponents.cmake)
200
201#############################################################################
202# Generation of configuration files
203
204# Stable components
205# This sets a version to be used throughout our config process
206# NOTE: Adjust as needed
207#
208set(NCBI_CPP_TOOLKIT_VERSION_MAJOR 24)
209set(NCBI_CPP_TOOLKIT_VERSION_MINOR 0)
210set(NCBI_CPP_TOOLKIT_VERSION_PATCH 0)
211set(NCBI_CPP_TOOLKIT_VERSION_EXTRA "")
212set(NCBI_CPP_TOOLKIT_VERSION
213    ${NCBI_CPP_TOOLKIT_VERSION_MAJOR}.${NCBI_CPP_TOOLKIT_VERSION_MINOR}.${NCBI_CPP_TOOLKIT_VERSION_PATCH}${NCBI_CPP_TOOLKIT_VERSION_EXTRA})
214
215#############################################################################
216# Subversion
217# This is needed for some use cases
218
219macro(NCBI_util_ToCygwinPath _result _value)
220    set(${_result} "${_value}")
221    if(WIN32)
222        string(FIND ${_value} ":" _pos)
223        if(${_pos} EQUAL 1)
224            string(REPLACE ":" ""  _tmp "${_value}")
225            set(${_result} "/cygdrive/${_tmp}")
226        endif()
227    endif()
228endmacro()
229macro(NCBI_Subversion_WC_INFO _dir _prefix)
230    if(CYGWIN)
231        NCBI_util_ToCygwinPath(_tmp ${_dir})
232        Subversion_WC_INFO(${_tmp} ${_prefix})
233    else()
234        Subversion_WC_INFO(${_dir} ${_prefix})
235    endif()
236endmacro()
237
238include(FindSubversion)
239if (Subversion_FOUND AND EXISTS ${top_src_dir}/.svn)
240    NCBI_Subversion_WC_INFO(${top_src_dir} TOOLKIT)
241elseif(NOT "$ENV{SVNREV}" STREQUAL "")
242    set(TOOLKIT_WC_REVISION "$ENV{SVNREV}")
243    set(TOOLKIT_WC_URL "$ENV{SVNURL}")
244else()
245    set(TOOLKIT_WC_REVISION 0)
246    set(TOOLKIT_WC_URL "")
247endif()
248if(NOT "$ENV{NCBI_SUBVERSION_REVISION}" STREQUAL "")
249    set(TOOLKIT_WC_REVISION "$ENV{NCBI_SUBVERSION_REVISION}")
250endif()
251set(NCBI_SUBVERSION_REVISION ${TOOLKIT_WC_REVISION})
252message(STATUS "SVN revision = ${TOOLKIT_WC_REVISION}")
253message(STATUS "SVN URL = ${TOOLKIT_WC_URL}")
254
255if (Subversion_FOUND AND EXISTS ${top_src_dir}/src/corelib/.svn)
256    NCBI_Subversion_WC_INFO(${top_src_dir}/src/corelib CORELIB)
257else()
258    set(CORELIB_WC_REVISION 0)
259    set(CORELIB_WC_URL "")
260endif()
261
262if(NOT "$ENV{NCBI_SC_VERSION}" STREQUAL "")
263    set(NCBI_SC_VERSION $ENV{NCBI_SC_VERSION})
264else()
265    set(NCBI_SC_VERSION 0)
266    if (NOT "${CORELIB_WC_URL}" STREQUAL "")
267        string(REGEX REPLACE ".*/production/components/core/([0-9]+)\\.[0-9]+/.*" "\\1" _SC_VER "${CORELIB_WC_URL}")
268        string(LENGTH "${_SC_VER}" _SC_VER_LEN)
269        if (${_SC_VER_LEN} LESS 10 AND NOT "${_SC_VER}" STREQUAL "")
270            set(NCBI_SC_VERSION ${_SC_VER})
271            message(STATUS "Stable Components Number = ${NCBI_SC_VERSION}")
272        endif()
273    endif()
274endif()
275
276set(NCBI_TEAMCITY_BUILD_NUMBER 0)
277if (NOT "$ENV{TEAMCITY_VERSION}" STREQUAL "")
278    set(NCBI_TEAMCITY_BUILD_NUMBER   $ENV{BUILD_NUMBER})
279    set(NCBI_TEAMCITY_PROJECT_NAME   $ENV{TEAMCITY_PROJECT_NAME})
280    set(NCBI_TEAMCITY_BUILDCONF_NAME $ENV{TEAMCITY_BUILDCONF_NAME})
281    if(EXISTS "$ENV{TEAMCITY_BUILD_PROPERTIES_FILE}")
282        file(STRINGS "$ENV{TEAMCITY_BUILD_PROPERTIES_FILE}" _list)
283        foreach( _item IN LISTS _list)
284            if ("${_item}" MATCHES "teamcity.build.id")
285                string(REPLACE "teamcity.build.id" "" _item ${_item})
286                string(REPLACE " " "" _item ${_item})
287                string(REPLACE "=" "" _item ${_item})
288                set(NCBI_TEAMCITY_BUILD_ID ${_item})
289                break()
290            endif()
291        endforeach()
292    else()
293        message("$ENV{TEAMCITY_BUILD_PROPERTIES_FILE} DOES NOT EXIST")
294    endif()
295    if ("${NCBI_TEAMCITY_BUILD_ID}" STREQUAL "")
296        string(RANDOM _name)
297        string(UUID NCBI_TEAMCITY_BUILD_ID NAMESPACE "73203eb4-80d3-4957-a110-8aae92c7e615" NAME ${_name} TYPE SHA1)
298    endif()
299    message(STATUS "TeamCity build number = ${NCBI_TEAMCITY_BUILD_NUMBER}")
300    message(STATUS "TeamCity project name = ${NCBI_TEAMCITY_PROJECT_NAME}")
301    message(STATUS "TeamCity build conf   = ${NCBI_TEAMCITY_BUILDCONF_NAME}")
302    message(STATUS "TeamCity build ID     = ${NCBI_TEAMCITY_BUILD_ID}")
303endif()
304
305#############################################################################
306cmake_host_system_information(RESULT _local_host_name  QUERY HOSTNAME)
307if (WIN32 OR XCODE)
308    set(HOST "${HOST_CPU}-${HOST_OS}")
309else()
310#    set(HOST "${HOST_CPU}-unknown-${HOST_OS}")
311    set(HOST "${HOST_CPU}-${HOST_OS}")
312endif()
313string(REPLACE ";" " " FEATURES "${NCBI_ALL_COMPONENTS}")
314
315set(_tk_common_include "${NCBITK_INC_ROOT}/common")
316if (WIN32 OR XCODE)
317    foreach(_cfg ${NCBI_CONFIGURATION_TYPES})
318
319        set(_file "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${_cfg}")
320        if (WIN32)
321            string(REPLACE "/" "\\\\" _file ${_file})
322        endif()
323        set(c_ncbi_runpath "${_file}")
324        if (WIN32)
325            string(REPLACE "/" "\\\\" SYBASE_PATH "${SYBASE_PATH}")
326        endif()
327
328        set(NCBI_SIGNATURE "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-${_cfg}--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
329        set(NCBI_SIGNATURE_CFG "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-\$<CONFIG>--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
330        set(NCBI_SIGNATURE_${_cfg} "${NCBI_SIGNATURE}")
331if(OFF)
332        if (WIN32)
333            configure_file(${NCBI_TREE_CMAKECFG}/ncbiconf_msvc_site.h.in ${NCBI_CFGINC_ROOT}/${_cfg}/common/config/ncbiconf_msvc_site.h)
334        elseif (XCODE)
335            configure_file(${NCBI_TREE_CMAKECFG}/ncbiconf_msvc_site.h.in ${NCBI_CFGINC_ROOT}/${_cfg}/common/config/ncbiconf_xcode_site.h)
336        endif()
337else()
338        if (WIN32)
339            configure_file(${NCBI_TREE_CMAKECFG}/config.cmake.h.in ${NCBI_CFGINC_ROOT}/${_cfg}/common/config/ncbiconf_msvc.h)
340        elseif (XCODE)
341            configure_file(${NCBI_TREE_CMAKECFG}/config.cmake.h.in ${NCBI_CFGINC_ROOT}/${_cfg}/common/config/ncbiconf_xcode.h)
342        endif()
343endif()
344        if (EXISTS ${NCBITK_SRC_ROOT}/corelib/ncbicfg.c.in)
345            configure_file(${NCBITK_SRC_ROOT}/corelib/ncbicfg.c.in ${NCBI_CFGINC_ROOT}/${_cfg}/common/config/ncbicfg.cfg.c)
346        endif()
347        configure_file(${_tk_common_include}/ncbi_build_ver.h.in ${NCBI_CFGINC_ROOT}/${_cfg}/common/ncbi_build_ver.h)
348        if (DEFINED NCBI_EXTERNAL_TREE_ROOT)
349            configure_file(${_tk_common_include}/ncbi_revision.h.in ${NCBI_INC_ROOT}/common/ncbi_revision.h)
350        else()
351            configure_file(${_tk_common_include}/ncbi_revision.h.in ${NCBITK_INC_ROOT}/common/ncbi_revision.h)
352        endif()
353    endforeach()
354    if(NOT EXISTS ${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_BUILD}/corelib/ncbicfg.c)
355        file(WRITE ${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_BUILD}/corelib/ncbicfg.c "#include <common/config/ncbicfg.cfg.c>\n")
356    endif()
357    if (WIN32)
358        if (BUILD_SHARED_LIBS)
359            set(NCBITEST_SIGNATURE "${NCBI_COMPILER_ALT}-\$<CONFIG>MTdll64--${HOST_CPU}-win64-${_local_host_name}")
360        else()
361            set(NCBITEST_SIGNATURE "${NCBI_COMPILER_ALT}-\$<CONFIG>MTstatic64--${HOST_CPU}-win64-${_local_host_name}")
362        endif()
363    elseif (XCODE)
364        if (BUILD_SHARED_LIBS)
365            set(NCBITEST_SIGNATURE "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-\$<CONFIG>MTdll64--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
366        else()
367            set(NCBITEST_SIGNATURE "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-\$<CONFIG>MTstatic64--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
368        endif()
369    endif()
370else()
371#Linux
372    set(c_ncbi_runpath ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
373    set(NCBI_TLS_VAR "__thread")
374
375    set(NCBI_SIGNATURE "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-${NCBI_BUILD_TYPE}--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
376    if (BUILD_SHARED_LIBS)
377        set(NCBITEST_SIGNATURE "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-${CMAKE_BUILD_TYPE}MTdll64--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
378    else()
379        set(NCBITEST_SIGNATURE "${NCBI_COMPILER}_${NCBI_COMPILER_VERSION}-${CMAKE_BUILD_TYPE}MTstatic64--${HOST_CPU}-${HOST_OS_WITH_VERSION}-${_local_host_name}")
380    endif()
381    configure_file(${NCBI_TREE_CMAKECFG}/config.cmake.h.in ${NCBI_CFGINC_ROOT}/ncbiconf_unix.h)
382    if (EXISTS ${NCBITK_SRC_ROOT}/corelib/ncbicfg.c.in)
383        configure_file(${NCBITK_SRC_ROOT}/corelib/ncbicfg.c.in ${NCBI_BUILD_ROOT}/${NCBI_DIRNAME_BUILD}/corelib/ncbicfg.c)
384    endif()
385
386    configure_file(${_tk_common_include}/ncbi_build_ver.h.in ${NCBI_CFGINC_ROOT}/common/ncbi_build_ver.h)
387    if (DEFINED NCBI_EXTERNAL_TREE_ROOT)
388        configure_file(${_tk_common_include}/ncbi_revision.h.in ${NCBI_INC_ROOT}/common/ncbi_revision.h)
389    else()
390        configure_file(${_tk_common_include}/ncbi_revision.h.in ${NCBITK_INC_ROOT}/common/ncbi_revision.h)
391    endif()
392endif()
393