• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1include(FetchContent)
2set(FETCHCONTENT_QUIET OFF)
3
4if(CMAKE_SYSTEM_NAME MATCHES "Windows" AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.17.0)
5    set(CMAKE_FIND_LIBRARY_SUFFIXES .dll ${CMAKE_FIND_LIBRARY_SUFFIXES})
6endif()
7
8function(mindspore_add_submodule_obj des_submodule_objs sub_dir submodule_name_obj)
9
10    add_subdirectory(${sub_dir})
11
12    if(NOT TARGET ${submodule_name_obj})
13        message(FATAL_ERROR "Can not find submodule '${submodule_name_obj}'. in ${CMAKE_CURRENT_LIST_FILE}")
14    endif()
15    if("$<TARGET_OBJECTS:${submodule_name_obj}>" IN_LIST ${des_submodule_objs})
16        message(FATAL_ERROR "submodule '${submodule_name_obj}' added more than once. in ${CMAKE_CURRENT_LIST_FILE}")
17    endif()
18
19    set(${des_submodule_objs} ${${des_submodule_objs}} $<TARGET_OBJECTS:${submodule_name_obj}> PARENT_SCOPE)
20
21endfunction()
22
23if(DEFINED ENV{MSLIBS_CACHE_PATH})
24    set(_MS_LIB_CACHE  $ENV{MSLIBS_CACHE_PATH})
25else()
26    set(_MS_LIB_CACHE ${CMAKE_BINARY_DIR}/.mslib)
27endif()
28message("MS LIBS CACHE PATH:  ${_MS_LIB_CACHE}")
29
30if(NOT EXISTS ${_MS_LIB_CACHE})
31    file(MAKE_DIRECTORY ${_MS_LIB_CACHE})
32endif()
33
34if(DEFINED ENV{MSLIBS_SERVER} AND NOT ENABLE_GITEE)
35    set(LOCAL_LIBS_SERVER  $ENV{MSLIBS_SERVER})
36    message("LOCAL_LIBS_SERVER:  ${LOCAL_LIBS_SERVER}")
37endif()
38
39include(ProcessorCount)
40ProcessorCount(N)
41if(JOBS)
42    set(THNUM ${JOBS})
43else()
44    set(JOBS 8)
45    if(${JOBS} GREATER ${N})
46        set(THNUM ${N})
47    else()
48        set(THNUM ${JOBS})
49    endif()
50endif()
51message("set make thread num: ${THNUM}")
52
53if(LOCAL_LIBS_SERVER)
54    if(NOT ENV{no_proxy})
55        set(ENV{no_proxy} "${LOCAL_LIBS_SERVER}")
56    else()
57        string(FIND $ENV{no_proxy} ${LOCAL_LIBS_SERVER} IP_POS)
58        if(${IP_POS} EQUAL -1)
59            set(ENV{no_proxy} "$ENV{no_proxy},${LOCAL_LIBS_SERVER}")
60        endif()
61    endif()
62endif()
63
64function(__download_pkg pkg_name pkg_url pkg_sha256)
65
66    if(LOCAL_LIBS_SERVER)
67        set(REGEX_IP_ADDRESS "^([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)$")
68        get_filename_component(_URL_FILE_NAME ${pkg_url} NAME)
69        if(${LOCAL_LIBS_SERVER} MATCHES ${REGEX_IP_ADDRESS})
70            set(pkg_url "http://${LOCAL_LIBS_SERVER}:8081/libs/${pkg_name}/${_URL_FILE_NAME}" ${pkg_url})
71        else()
72            set(pkg_url "https://${LOCAL_LIBS_SERVER}/libs/${pkg_name}/${_URL_FILE_NAME}" ${pkg_url})
73        endif()
74    endif()
75
76    FetchContent_Declare(
77            ${pkg_name}
78            URL      ${pkg_url}
79            URL_HASH SHA256=${pkg_sha256}
80    )
81    FetchContent_GetProperties(${pkg_name})
82    message("download: ${${pkg_name}_SOURCE_DIR} , ${pkg_name} , ${pkg_url}")
83    if(NOT ${pkg_name}_POPULATED)
84        FetchContent_Populate(${pkg_name})
85        set(${pkg_name}_SOURCE_DIR ${${pkg_name}_SOURCE_DIR} PARENT_SCOPE)
86    endif()
87
88endfunction()
89
90function(__download_pkg_with_git pkg_name pkg_url pkg_git_commit pkg_sha256)
91
92    if(LOCAL_LIBS_SERVER)
93        set(pkg_url "http://${LOCAL_LIBS_SERVER}:8081/libs/${pkg_name}/${pkg_git_commit}")
94        FetchContent_Declare(
95                ${pkg_name}
96                URL      ${pkg_url}
97                URL_HASH SHA256=${pkg_sha256}
98    )
99    else()
100    FetchContent_Declare(
101            ${pkg_name}
102        GIT_REPOSITORY      ${pkg_url}
103        GIT_TAG             ${pkg_git_commit})
104    endif()
105    FetchContent_GetProperties(${pkg_name})
106    message("download: ${${pkg_name}_SOURCE_DIR} , ${pkg_name} , ${pkg_url}")
107    if(NOT ${pkg_name}_POPULATED)
108        FetchContent_Populate(${pkg_name})
109        set(${pkg_name}_SOURCE_DIR ${${pkg_name}_SOURCE_DIR} PARENT_SCOPE)
110    endif()
111
112endfunction()
113
114
115function(__find_pkg_then_add_target pkg_name pkg_exe lib_path)
116    set(options)
117    set(oneValueArgs PATH)
118    set(multiValueArgs SUFFIXES_PATH NAMES)
119    cmake_parse_arguments(LIB "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
120
121    unset(${pkg_name}_LIBS)
122
123    message("_FIND:${${pkg_name}_BASE_DIR}")
124
125    if(pkg_exe)
126        unset(${pkg_exe}_EXE CACHE)
127        find_program(${pkg_exe}_EXE ${pkg_exe} PATHS ${${pkg_name}_BASE_DIR}/bin NO_DEFAULT_PATH)
128        if(NOT ${pkg_exe}_EXE)
129            return()
130        endif()
131        add_executable(${pkg_name}::${pkg_exe} IMPORTED GLOBAL)
132        set_target_properties(${pkg_name}::${pkg_exe} PROPERTIES
133                IMPORTED_LOCATION ${${pkg_exe}_EXE}
134                )
135        message("found ${${pkg_exe}_EXE}")
136    endif()
137
138    foreach(_LIB_NAME ${LIB_NAMES})
139        set(_LIB_SEARCH_NAME ${_LIB_NAME})
140        if(MSVC AND ${pkg_name}_Debug)
141            set(_LIB_SEARCH_NAME ${_LIB_SEARCH_NAME}d)
142        endif()
143        set(_LIB_TYPE SHARED)
144        if(${pkg_name}_USE_STATIC_LIBS)
145            set(_LIB_SEARCH_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}${_LIB_SEARCH_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}")
146            set(_LIB_TYPE STATIC)
147        endif()
148        set(${_LIB_NAME}_LIB ${_LIB_NAME}_LIB-NOTFOUND)
149        if(APPLE)
150            find_library(${_LIB_NAME}_LIB ${_LIB_SEARCH_NAME} PATHS ${${pkg_name}_BASE_DIR}/${lib_path}
151                    PATH_SUFFIXES ${LIB_SUFFIXES_PATH} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
152        else()
153            find_library(${_LIB_NAME}_LIB ${_LIB_SEARCH_NAME} PATHS ${${pkg_name}_BASE_DIR}/${lib_path}
154                    PATH_SUFFIXES ${LIB_SUFFIXES_PATH} NO_DEFAULT_PATH)
155        endif()
156        if(NOT ${_LIB_NAME}_LIB)
157            message("not find ${_LIB_SEARCH_NAME} in path: ${${pkg_name}_BASE_DIR}/${lib_path}")
158            return()
159        endif()
160
161        add_library(${pkg_name}::${_LIB_NAME} ${_LIB_TYPE} IMPORTED GLOBAL)
162        if(WIN32 AND ${_LIB_TYPE} STREQUAL "SHARED")
163            if(DEBUG_MODE)
164                set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_IMPLIB_DEBUG ${${_LIB_NAME}_LIB})
165            else()
166                set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_IMPLIB_RELEASE ${${_LIB_NAME}_LIB})
167            endif()
168        else()
169            set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${${_LIB_NAME}_LIB})
170        endif()
171
172        if(EXISTS ${${pkg_name}_BASE_DIR}/include)
173            set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES
174                INTERFACE_INCLUDE_DIRECTORIES "${${pkg_name}_BASE_DIR}/include")
175        endif()
176
177        list(APPEND ${pkg_name}_LIBS ${pkg_name}::${_LIB_NAME})
178        message("found ${${_LIB_NAME}_LIB}")
179        STRING(REGEX REPLACE "(.+)/(.+)" "\\1" LIBPATH ${${_LIB_NAME}_LIB})
180        set(${pkg_name}_LIBPATH ${LIBPATH} CACHE STRING INTERNAL)
181    endforeach()
182
183    set(${pkg_name}_LIBS ${${pkg_name}_LIBS} PARENT_SCOPE)
184endfunction()
185
186function(__exec_cmd)
187    set(options)
188    set(oneValueArgs WORKING_DIRECTORY)
189    set(multiValueArgs COMMAND)
190
191    cmake_parse_arguments(EXEC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
192
193    execute_process(COMMAND ${EXEC_COMMAND}
194            WORKING_DIRECTORY ${EXEC_WORKING_DIRECTORY}
195            RESULT_VARIABLE RESULT)
196    if(NOT RESULT EQUAL "0")
197        message(FATAL_ERROR "error! when ${EXEC_COMMAND} in ${EXEC_WORKING_DIRECTORY}")
198    endif()
199endfunction()
200
201function(__check_patches pkg_patches)
202    # check patches
203    if(PKG_PATCHES)
204        file(TOUCH ${_MS_LIB_CACHE}/${pkg_name}_patch.sha256)
205        file(READ ${_MS_LIB_CACHE}/${pkg_name}_patch.sha256 ${pkg_name}_PATCHES_SHA256)
206
207        message("patches sha256:${${pkg_name}_PATCHES_SHA256}")
208
209        set(${pkg_name}_PATCHES_NEW_SHA256)
210        foreach(_PATCH ${PKG_PATCHES})
211            file(SHA256 ${_PATCH} _PF_SHA256)
212            set(${pkg_name}_PATCHES_NEW_SHA256 "${${pkg_name}_PATCHES_NEW_SHA256},${_PF_SHA256}")
213        endforeach()
214
215        if(NOT ${pkg_name}_PATCHES_SHA256 STREQUAL ${pkg_name}_PATCHES_NEW_SHA256)
216            set(${pkg_name}_PATCHES ${PKG_PATCHES})
217            file(REMOVE_RECURSE "${_MS_LIB_CACHE}/${pkg_name}-subbuild")
218            file(WRITE ${_MS_LIB_CACHE}/${pkg_name}_patch.sha256 ${${pkg_name}_PATCHES_NEW_SHA256})
219            message("patches changed : ${${pkg_name}_PATCHES_NEW_SHA256}")
220        endif()
221    endif()
222endfunction()
223
224set(MS_FIND_NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
225                            NO_CMAKE_BUILDS_PATH NO_CMAKE_PACKAGE_REGISTRY NO_CMAKE_SYSTEM_PATH
226                            NO_CMAKE_SYSTEM_PACKAGE_REGISTRY)
227function(mindspore_add_pkg pkg_name)
228
229    set(options)
230    set(oneValueArgs URL SHA256 GIT_REPOSITORY GIT_TAG VER EXE DIR HEAD_ONLY CMAKE_PATH RELEASE
231            LIB_PATH CUSTOM_CMAKE)
232    set(multiValueArgs
233            CMAKE_OPTION LIBS PRE_CONFIGURE_COMMAND CONFIGURE_COMMAND BUILD_OPTION INSTALL_INCS
234            INSTALL_LIBS PATCHES SUBMODULES SOURCEMODULES ONLY_MAKE ONLY_MAKE_INCS ONLY_MAKE_LIBS
235            LIB_SUFFIXES_PATH)
236    cmake_parse_arguments(PKG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
237
238    if(NOT PKG_LIB_PATH)
239        set(PKG_LIB_PATH lib)
240    endif()
241
242    if(NOT PKG_EXE)
243        set(PKG_EXE 0)
244    endif()
245
246    set(__FIND_PKG_NAME ${pkg_name})
247    string(TOLOWER ${pkg_name} pkg_name)
248    message("pkg name:${__FIND_PKG_NAME},${pkg_name}")
249
250    set(${pkg_name}_PATCHES_HASH)
251    foreach(_PATCH ${PKG_PATCHES})
252        file(SHA256 ${_PATCH} _PF_SHA256)
253        set(${pkg_name}_PATCHES_HASH "${${pkg_name}_PATCHES_HASH},${_PF_SHA256}")
254    endforeach()
255
256    # strip directory variables to ensure third party packages are installed in consistent locations
257    string(REPLACE ${TOP_DIR} "" ARGN_STRIPPED ${ARGN})
258    string(REPLACE ${_MS_LIB_CACHE} "" ARGN_STRIPPED ${ARGN_STRIPPED})
259    # check options
260    set(${pkg_name}_CONFIG_TXT
261            "${CMAKE_CXX_COMPILER_VERSION}-${CMAKE_C_COMPILER_VERSION}
262            ${ARGN_STRIPPED}-${${pkg_name}_USE_STATIC_LIBS}-${${pkg_name}_PATCHES_HASH}
263            ${${pkg_name}_CXXFLAGS}-${${pkg_name}_CFLAGS}-${${pkg_name}_LDFLAGS}")
264    if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
265        set(${pkg_name}_CONFIG_TXT "${${pkg_name}_CONFIG_TXT}--${CMAKE_OSX_DEPLOYMENT_TARGET}")
266    endif()
267    string(REPLACE ";" "-" ${pkg_name}_CONFIG_TXT ${${pkg_name}_CONFIG_TXT})
268    string(SHA256 ${pkg_name}_CONFIG_HASH ${${pkg_name}_CONFIG_TXT})
269
270    message("${pkg_name} config hash: ${${pkg_name}_CONFIG_HASH}")
271
272    set(${pkg_name}_BASE_DIR ${_MS_LIB_CACHE}/${pkg_name}_${PKG_VER}_${${pkg_name}_CONFIG_HASH})
273    set(${pkg_name}_DIRPATH ${${pkg_name}_BASE_DIR} CACHE STRING INTERNAL)
274
275    if(EXISTS ${${pkg_name}_BASE_DIR}/options.txt AND PKG_HEAD_ONLY)
276        set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/${PKG_HEAD_ONLY} PARENT_SCOPE)
277        add_library(${pkg_name} INTERFACE)
278        target_include_directories(${pkg_name} INTERFACE ${${pkg_name}_INC})
279        if(${PKG_RELEASE})
280            __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH}
281                    SUFFIXES_PATH ${PKG_LIB_SUFFIXES_PATH}
282                    NAMES ${PKG_LIBS})
283        endif()
284        return()
285    endif()
286
287    set(${__FIND_PKG_NAME}_ROOT ${${pkg_name}_BASE_DIR})
288    set(${__FIND_PKG_NAME}_ROOT ${${pkg_name}_BASE_DIR} PARENT_SCOPE)
289
290    if(PKG_LIBS)
291        __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH}
292                SUFFIXES_PATH ${PKG_LIB_SUFFIXES_PATH}
293                NAMES ${PKG_LIBS})
294        if(${pkg_name}_LIBS)
295            set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
296            message("Found libs: ${${pkg_name}_LIBS}")
297            return()
298        endif()
299    elseif(NOT PKG_HEAD_ONLY)
300        find_package(${__FIND_PKG_NAME} ${PKG_VER} PATHS ${${pkg_name}_BASE_DIR} ${MS_FIND_NO_DEFAULT_PATH})
301        if(${__FIND_PKG_NAME}_FOUND)
302            set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
303            message("Found pkg: ${__FIND_PKG_NAME}")
304            return()
305        endif()
306    endif()
307
308    if(NOT PKG_DIR)
309        if(PKG_GIT_REPOSITORY)
310            __download_pkg_with_git(${pkg_name} ${PKG_GIT_REPOSITORY} ${PKG_GIT_TAG} ${PKG_SHA256})
311        else()
312            __download_pkg(${pkg_name} ${PKG_URL} ${PKG_SHA256})
313        endif()
314        foreach(_SUBMODULE_FILE ${PKG_SUBMODULES})
315            STRING(REGEX REPLACE "(.+)_(.+)" "\\1" _SUBMODEPATH ${_SUBMODULE_FILE})
316            STRING(REGEX REPLACE "(.+)/(.+)" "\\2" _SUBMODENAME ${_SUBMODEPATH})
317            file(GLOB ${pkg_name}_INSTALL_SUBMODULE ${_SUBMODULE_FILE}/*)
318            file(COPY ${${pkg_name}_INSTALL_SUBMODULE} DESTINATION ${${pkg_name}_SOURCE_DIR}/3rdparty/${_SUBMODENAME})
319        endforeach()
320    else()
321        set(${pkg_name}_SOURCE_DIR ${PKG_DIR})
322    endif()
323    file(WRITE ${${pkg_name}_BASE_DIR}/options.txt ${${pkg_name}_CONFIG_TXT})
324    message("${pkg_name}_SOURCE_DIR : ${${pkg_name}_SOURCE_DIR}")
325
326    foreach(_PATCH_FILE ${PKG_PATCHES})
327        get_filename_component(_PATCH_FILE_NAME ${_PATCH_FILE} NAME)
328
329        # convert line-endings of patch file to UNIX LF
330        set(_LF_PATCH_FILE ${CMAKE_BINARY_DIR}/_ms_patch/${_PATCH_FILE_NAME})
331        configure_file(${_PATCH_FILE} ${_LF_PATCH_FILE} NEWLINE_STYLE LF @ONLY)
332
333        # convert line-endings of source file to be patched to UNIX LF
334        file(READ ${_LF_PATCH_FILE} _LF_PATCH_CONTENT)
335        string(REGEX MATCHALL "diff --git a/[/A-Za-z0-9\.\-_]*" _PATCH_SOURCE_LIST "${_LF_PATCH_CONTENT}")
336        list(TRANSFORM _PATCH_SOURCE_LIST REPLACE "diff --git a/" "") # strip prefix of file path
337
338        foreach(_PATCH_SOURCE ${_PATCH_SOURCE_LIST})
339            if(EXISTS ${${pkg_name}_SOURCE_DIR}/${_PATCH_SOURCE})
340                execute_process(COMMAND bash -c "sed -i \'s@\\r@@g\' ${${pkg_name}_SOURCE_DIR}/${_PATCH_SOURCE}"
341                COMMAND_ECHO STDOUT)
342            endif()
343        endforeach()
344
345        # apply patch
346        message("patching ${${pkg_name}_SOURCE_DIR} -p1 < ${_LF_PATCH_FILE}")
347        execute_process(COMMAND ${Patch_EXECUTABLE} -p1 INPUT_FILE ${_LF_PATCH_FILE}
348                WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}
349                RESULT_VARIABLE Result)
350        if(NOT Result EQUAL "0")
351            message(FATAL_ERROR "Failed patch: ${_LF_PATCH_FILE}")
352        endif()
353    endforeach()
354    foreach(_SOURCE_DIR ${PKG_SOURCEMODULES})
355        file(GLOB ${pkg_name}_INSTALL_SOURCE ${${pkg_name}_SOURCE_DIR}/${_SOURCE_DIR}/*)
356        file(COPY ${${pkg_name}_INSTALL_SOURCE} DESTINATION ${${pkg_name}_BASE_DIR}/${_SOURCE_DIR}/)
357    endforeach()
358    file(LOCK ${${pkg_name}_BASE_DIR} DIRECTORY GUARD FUNCTION RESULT_VARIABLE ${pkg_name}_LOCK_RET TIMEOUT 600)
359    if(NOT ${pkg_name}_LOCK_RET EQUAL "0")
360        message(FATAL_ERROR "error! when try lock ${${pkg_name}_BASE_DIR} : ${${pkg_name}_LOCK_RET}")
361    endif()
362
363    if(PKG_CUSTOM_CMAKE)
364        file(GLOB ${pkg_name}_cmake ${PKG_CUSTOM_CMAKE}/CMakeLists.txt)
365        file(COPY ${${pkg_name}_cmake} DESTINATION ${${pkg_name}_SOURCE_DIR})
366    endif()
367
368    if(${pkg_name}_SOURCE_DIR)
369        if(PKG_HEAD_ONLY)
370            file(GLOB ${pkg_name}_SOURCE_SUBDIRS ${${pkg_name}_SOURCE_DIR}/*)
371            file(COPY ${${pkg_name}_SOURCE_SUBDIRS} DESTINATION ${${pkg_name}_BASE_DIR})
372            set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/${PKG_HEAD_ONLY} PARENT_SCOPE)
373            if(NOT PKG_RELEASE)
374                add_library(${pkg_name} INTERFACE)
375                target_include_directories(${pkg_name} INTERFACE ${${pkg_name}_INC})
376            endif()
377
378        elseif(PKG_ONLY_MAKE)
379            __exec_cmd(COMMAND ${CMAKE_MAKE_PROGRAM} ${${pkg_name}_CXXFLAGS} -j${THNUM}
380                    WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR})
381            set(PKG_INSTALL_INCS ${PKG_ONLY_MAKE_INCS})
382            set(PKG_INSTALL_LIBS ${PKG_ONLY_MAKE_LIBS})
383            file(GLOB ${pkg_name}_INSTALL_INCS ${${pkg_name}_SOURCE_DIR}/${PKG_INSTALL_INCS})
384            file(GLOB ${pkg_name}_INSTALL_LIBS ${${pkg_name}_SOURCE_DIR}/${PKG_INSTALL_LIBS})
385            file(COPY ${${pkg_name}_INSTALL_INCS} DESTINATION ${${pkg_name}_BASE_DIR}/include)
386            file(COPY ${${pkg_name}_INSTALL_LIBS} DESTINATION ${${pkg_name}_BASE_DIR}/lib)
387
388        elseif(PKG_CMAKE_OPTION)
389            # in cmake
390            file(MAKE_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
391            if(${pkg_name}_CFLAGS)
392                set(${pkg_name}_CMAKE_CFLAGS "-DCMAKE_C_FLAGS=${${pkg_name}_CFLAGS}")
393            endif()
394            if(${pkg_name}_CXXFLAGS)
395                set(${pkg_name}_CMAKE_CXXFLAGS "-DCMAKE_CXX_FLAGS=${${pkg_name}_CXXFLAGS}")
396            endif()
397
398            if(${pkg_name}_LDFLAGS)
399                if(${pkg_name}_USE_STATIC_LIBS)
400                    #set(${pkg_name}_CMAKE_LDFLAGS "-DCMAKE_STATIC_LINKER_FLAGS=${${pkg_name}_LDFLAGS}")
401                else()
402                    set(${pkg_name}_CMAKE_LDFLAGS "-DCMAKE_SHARED_LINKER_FLAGS=${${pkg_name}_LDFLAGS}")
403                endif()
404            endif()
405            if(APPLE)
406                __exec_cmd(COMMAND ${CMAKE_COMMAND} -DCMAKE_CXX_COMPILER_ARG1=${CMAKE_CXX_COMPILER_ARG1}
407                        -DCMAKE_C_COMPILER_ARG1=${CMAKE_C_COMPILER_ARG1} ${PKG_CMAKE_OPTION}
408                        ${${pkg_name}_CMAKE_CFLAGS} ${${pkg_name}_CMAKE_CXXFLAGS} ${${pkg_name}_CMAKE_LDFLAGS}
409                        -DCMAKE_INSTALL_PREFIX=${${pkg_name}_BASE_DIR} ${${pkg_name}_SOURCE_DIR}/${PKG_CMAKE_PATH}
410                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
411                __exec_cmd(COMMAND ${CMAKE_COMMAND} --build . --target install --
412                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
413            else()
414                __exec_cmd(COMMAND ${CMAKE_COMMAND} -DCMAKE_CXX_COMPILER_ARG1=${CMAKE_CXX_COMPILER_ARG1}
415                        -DCMAKE_C_COMPILER_ARG1=${CMAKE_C_COMPILER_ARG1} ${PKG_CMAKE_OPTION} -G ${CMAKE_GENERATOR}
416                    ${${pkg_name}_CMAKE_CFLAGS} ${${pkg_name}_CMAKE_CXXFLAGS} ${${pkg_name}_CMAKE_LDFLAGS}
417                    -DCMAKE_INSTALL_PREFIX=${${pkg_name}_BASE_DIR} ${${pkg_name}_SOURCE_DIR}/${PKG_CMAKE_PATH}
418                    WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
419                if(MSVC)
420                    set(CONFIG_TYPE Release)
421                    if(DEBUG_MODE)
422                        set(CONFIG_TYPE Debug)
423                    endif()
424                    __exec_cmd(COMMAND ${CMAKE_COMMAND} --build . --config ${CONFIG_TYPE} --target install --
425                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
426                else()
427                    __exec_cmd(COMMAND ${CMAKE_COMMAND} --build . --target install -- -j${THNUM}
428                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
429                endif()
430            endif()
431        else()
432            if(${pkg_name}_CFLAGS)
433                set(${pkg_name}_MAKE_CFLAGS "CFLAGS=${${pkg_name}_CFLAGS}")
434            endif()
435            if(${pkg_name}_CXXFLAGS)
436                set(${pkg_name}_MAKE_CXXFLAGS "CXXFLAGS=${${pkg_name}_CXXFLAGS}")
437            endif()
438            if(${pkg_name}_LDFLAGS)
439                set(${pkg_name}_MAKE_LDFLAGS "LDFLAGS=${${pkg_name}_LDFLAGS}")
440            endif()
441            # in configure && make
442            if(PKG_PRE_CONFIGURE_COMMAND)
443                __exec_cmd(COMMAND ${PKG_PRE_CONFIGURE_COMMAND}
444                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR})
445            endif()
446
447            if(PKG_CONFIGURE_COMMAND)
448                __exec_cmd(COMMAND ${PKG_CONFIGURE_COMMAND}
449                        ${${pkg_name}_MAKE_CFLAGS} ${${pkg_name}_MAKE_CXXFLAGS} ${${pkg_name}_MAKE_LDFLAGS}
450                        --prefix=${${pkg_name}_BASE_DIR}
451                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR})
452            endif()
453            set(${pkg_name}_BUILD_OPTION ${PKG_BUILD_OPTION})
454            if(NOT PKG_CONFIGURE_COMMAND)
455                set(${pkg_name}_BUILD_OPTION ${${pkg_name}_BUILD_OPTION}
456                        ${${pkg_name}_MAKE_CFLAGS} ${${pkg_name}_MAKE_CXXFLAGS} ${${pkg_name}_MAKE_LDFLAGS})
457            endif()
458            # build
459            if(APPLE)
460                __exec_cmd(COMMAND ${CMAKE_MAKE_PROGRAM} ${${pkg_name}_BUILD_OPTION}
461                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR})
462            else()
463                __exec_cmd(COMMAND ${CMAKE_MAKE_PROGRAM} ${${pkg_name}_BUILD_OPTION} -j${THNUM}
464                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR})
465            endif()
466
467            if(PKG_INSTALL_INCS OR PKG_INSTALL_LIBS)
468                file(GLOB ${pkg_name}_INSTALL_INCS ${${pkg_name}_SOURCE_DIR}/${PKG_INSTALL_INCS})
469                file(GLOB ${pkg_name}_INSTALL_LIBS ${${pkg_name}_SOURCE_DIR}/${PKG_INSTALL_LIBS})
470                file(COPY ${${pkg_name}_INSTALL_INCS} DESTINATION ${${pkg_name}_BASE_DIR}/include)
471                file(COPY ${${pkg_name}_INSTALL_LIBS} DESTINATION ${${pkg_name}_BASE_DIR}/lib)
472            else()
473                __exec_cmd(COMMAND ${CMAKE_MAKE_PROGRAM} install WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR})
474            endif()
475        endif()
476    endif()
477
478    if(PKG_LIBS)
479        __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH}
480                SUFFIXES_PATH ${PKG_LIB_SUFFIXES_PATH}
481                NAMES ${PKG_LIBS})
482        set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
483        if(NOT ${pkg_name}_LIBS)
484            message(FATAL_ERROR "Can not find pkg: ${pkg_name}")
485        endif()
486    else()
487        find_package(${__FIND_PKG_NAME} ${PKG_VER} QUIET ${MS_FIND_NO_DEFAULT_PATH})
488        if(${__FIND_PKG_NAME}_FOUND)
489            set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
490            message("Found pkg: ${${__FIND_PKG_NAME}_LIBRARIES}")
491            return()
492        endif()
493    endif()
494endfunction()
495
496function(src_separate_compile)
497    set(options)
498    set(oneValueArgs OBJECT_NAME OBJECT_SIZE)
499    set(multiValueArgs SRC_LIST)
500    cmake_parse_arguments(STUDENT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
501    list(LENGTH STUDENT_SRC_LIST SRC_LIST_SIZE)
502
503    set(SEPARATE_SIZE 100)
504    set(SEPARATE_INDEX 0)
505    set(OBJECT_COUNT 0)
506    math(EXPR SRC_LIST_MAX_INDEX "${SRC_LIST_SIZE} - 1")
507    while(${SRC_LIST_SIZE} GREATER ${SEPARATE_INDEX})
508        math(EXPR SEPARATE_END "${SEPARATE_INDEX} + ${SEPARATE_SIZE} - 1")
509        if(${SEPARATE_END} GREATER ${SRC_LIST_MAX_INDEX})
510            math(EXPR SEPARATE_SIZE "${SRC_LIST_SIZE} - ${SEPARATE_INDEX}")
511        endif()
512        list(SUBLIST STUDENT_SRC_LIST ${SEPARATE_INDEX} ${SEPARATE_SIZE} new_sub_list)
513        math(EXPR OBJECT_COUNT "${OBJECT_COUNT} + 1")
514        math(EXPR SEPARATE_INDEX "${SEPARATE_INDEX} + ${SEPARATE_SIZE}")
515        add_library(${STUDENT_OBJECT_NAME}_${OBJECT_COUNT} OBJECT ${new_sub_list})
516    endwhile()
517    set(${STUDENT_OBJECT_SIZE} "${OBJECT_COUNT}" PARENT_SCOPE)
518    message("${STUDENT_OBJECT_SIZE} object count is ${OBJECT_COUNT}")
519endfunction()
520
521function(enable_target_when_only_build_plugins target)
522    if(ONLY_BUILD_DEVICE_PLUGINS)
523        get_target_property(target_type ${target} TYPE)
524        if(target_type STREQUAL "INTERFACE_LIBRARY")
525            return()
526        endif()
527        set_target_properties(${target} PROPERTIES EXCLUDE_FROM_ALL FALSE)
528    endif()
529endfunction()
530
531function(disable_target_when_only_build_plugins target)
532    if(ONLY_BUILD_DEVICE_PLUGINS)
533        get_target_property(target_type ${target} TYPE)
534        if(target_type STREQUAL "INTERFACE_LIBRARY")
535            return()
536        endif()
537        get_property(is_set TARGET ${target} PROPERTY EXCLUDE_FROM_ALL)
538        if(NOT DEFINED is_set)
539            set_target_properties(${target} PROPERTIES EXCLUDE_FROM_ALL TRUE)
540        endif()
541    endif()
542endfunction()
543
544function(enable_directory_when_only_build_plugins dir)
545    get_property(targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
546    foreach(target ${targets})
547        enable_target_when_only_build_plugins(${target})
548    endforeach()
549    get_property(items DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
550    foreach(item ${items})
551        enable_directory_when_only_build_plugins(${item})
552    endforeach()
553endfunction()
554
555function(disable_directory_when_only_build_plugins dir)
556    get_property(targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
557    foreach(target ${targets})
558        disable_target_when_only_build_plugins(${target})
559    endforeach()
560    get_property(items DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
561    foreach(item ${items})
562        disable_directory_when_only_build_plugins(${item})
563    endforeach()
564endfunction()
565
566function(add_subdirectory_with_faster_option dir)
567    if(ONLY_BUILD_DEVICE_PLUGINS)
568        add_subdirectory(${dir})
569        disable_directory_when_only_build_plugins(${dir})
570    else()
571        add_subdirectory(${dir})
572    endif()
573endfunction()
574
575function(find_and_use_mold)
576    find_program(MOLD_LINKER mold)
577    if(MOLD_LINKER)
578        message(STATUS "using mold to speed linking libraries")
579        get_filename_component(MOLD_LINKER_PATH ${MOLD_LINKER} DIRECTORY)
580        file(GLOB MOLD_LINKER_PATH "${MOLD_LINKER_PATH}/../libexec/mold")
581        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -B${MOLD_LINKER_PATH}")
582        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -B${MOLD_LINKER_PATH}")
583    endif()
584endfunction()