utils.cmake 13.6 KB
Newer Older
C
ckey_Dou 已提交
1 2 3 4 5 6 7
include(FetchContent)
set(FETCHCONTENT_QUIET OFF)

if (CMAKE_SYSTEM_NAME MATCHES "Windows" AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.17.0)
    set(CMAKE_FIND_LIBRARY_SUFFIXES .dll ${CMAKE_FIND_LIBRARY_SUFFIXES})
endif ()

8
function(akg_add_submodule_obj des_submodule_objs sub_dir submodule_name_obj)
C
ckey_Dou 已提交
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200

    add_subdirectory(${sub_dir})

    if(NOT TARGET ${submodule_name_obj})
        message(FATAL_ERROR "Can not find submodule '${submodule_name_obj}'. in ${CMAKE_CURRENT_LIST_FILE}")
    endif()
    if("$<TARGET_OBJECTS:${submodule_name_obj}>" IN_LIST ${des_submodule_objs})
        message(FATAL_ERROR "submodule '${submodule_name_obj}' added more than once. in ${CMAKE_CURRENT_LIST_FILE}")
    endif()

    set(${des_submodule_objs} ${${des_submodule_objs}} $<TARGET_OBJECTS:${submodule_name_obj}> PARENT_SCOPE)

endfunction()

if (DEFINED ENV{MSLIBS_CACHE_PATH})
    set(_MS_LIB_CACHE  $ENV{MSLIBS_CACHE_PATH})
else()
    set(_MS_LIB_CACHE ${CMAKE_BINARY_DIR}/.mslib)
endif ()
message("MS LIBS CACHE PATH:  ${_MS_LIB_CACHE}")

if (NOT EXISTS ${_MS_LIB_CACHE})
    file(MAKE_DIRECTORY ${_MS_LIB_CACHE})
endif ()

if (DEFINED ENV{MSLIBS_SERVER})
    set(LOCAL_LIBS_SERVER  $ENV{MSLIBS_SERVER})
    message("LOCAL_LIBS_SERVER:  ${LOCAL_LIBS_SERVER}")
endif ()

include(ProcessorCount)
ProcessorCount(N)
if (JOBS)
    set(THNUM ${JOBS})
else()
    set(JOBS 8)
    if (${JOBS} GREATER ${N})
        set(THNUM ${N})
    else()
        set(THNUM ${JOBS})
    endif()
endif ()
message("set make thread num: ${THNUM}")

if(LOCAL_LIBS_SERVER)
    if (NOT ENV{no_proxy})
        set(ENV{no_proxy} "${LOCAL_LIBS_SERVER}")
    else()
        string(FIND $ENV{no_proxy} ${LOCAL_LIBS_SERVER} IP_POS)
        if (${IP_POS} EQUAL -1)
            set(ENV{no_proxy} "$ENV{no_proxy},${LOCAL_LIBS_SERVER}")
        endif ()
    endif ()
endif()

function(__download_pkg pkg_name pkg_url pkg_md5)

    if(LOCAL_LIBS_SERVER)
        get_filename_component(_URL_FILE_NAME ${pkg_url} NAME)
        set(pkg_url "http://${LOCAL_LIBS_SERVER}:8081/libs/${pkg_name}/${_URL_FILE_NAME}" ${pkg_url})
    endif()

    FetchContent_Declare(
            ${pkg_name}
            URL      ${pkg_url}
            URL_HASH MD5=${pkg_md5}
    )
    FetchContent_GetProperties(${pkg_name})
    message("download: ${${pkg_name}_SOURCE_DIR} , ${pkg_name} , ${pkg_url}")
    if(NOT ${pkg_name}_POPULATED)
        FetchContent_Populate(${pkg_name})
        set(${pkg_name}_SOURCE_DIR ${${pkg_name}_SOURCE_DIR} PARENT_SCOPE)
    endif()

endfunction()

function(__download_pkg_with_git pkg_name pkg_url pkg_git_commit pkg_md5)

    if(LOCAL_LIBS_SERVER)
        set(pkg_url "http://${LOCAL_LIBS_SERVER}:8081/libs/${pkg_name}/${pkg_git_commit}")
        FetchContent_Declare(
                ${pkg_name}
                URL      ${pkg_url}
                URL_HASH MD5=${pkg_md5}
    )
    else()
	FetchContent_Declare(
            ${pkg_name}
	    GIT_REPOSITORY      ${pkg_url}
	    GIT_TAG             ${pkg_git_commit})
    endif()
    FetchContent_GetProperties(${pkg_name})
    message("download: ${${pkg_name}_SOURCE_DIR} , ${pkg_name} , ${pkg_url}")
    if(NOT ${pkg_name}_POPULATED)
        FetchContent_Populate(${pkg_name})
        set(${pkg_name}_SOURCE_DIR ${${pkg_name}_SOURCE_DIR} PARENT_SCOPE)
    endif()

endfunction()


function(__find_pkg_then_add_target pkg_name pkg_exe lib_path)

    unset(${pkg_name}_LIBS)

    message("_FIND:${${pkg_name}_BASE_DIR}")

    if(pkg_exe)
        find_program(${pkg_exe}_EXE ${pkg_exe} PATHS ${${pkg_name}_BASE_DIR}/bin NO_DEFAULT_PATH)
        if(NOT ${pkg_exe}_EXE)
            return()
        endif()
        add_executable(${pkg_name}::${pkg_exe} IMPORTED GLOBAL)
        set_target_properties(${pkg_name}::${pkg_exe} PROPERTIES
                IMPORTED_LOCATION ${${pkg_exe}_EXE}
                )
        message("found ${${pkg_exe}_EXE}")
    endif()

    foreach(_LIB_NAME ${ARGN})
        set(_LIB_SEARCH_NAME ${_LIB_NAME})
        set(_LIB_TYPE SHARED)
        if (${pkg_name}_USE_STATIC_LIBS)
            set(_LIB_SEARCH_NAME "${CMAKE_STATIC_LIBRARY_PREFIX}${_LIB_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}")
            set(_LIB_TYPE STATIC)
        endif ()
        set(${_LIB_NAME}_LIB ${_LIB_NAME}_LIB-NOTFOUND)
        find_library(${_LIB_NAME}_LIB ${_LIB_SEARCH_NAME} PATHS ${${pkg_name}_BASE_DIR}/${lib_path} NO_DEFAULT_PATH)

        if(NOT ${_LIB_NAME}_LIB)
            return()
        endif()

        add_library(${pkg_name}::${_LIB_NAME} ${_LIB_TYPE} IMPORTED GLOBAL)
        if (WIN32 AND ${_LIB_TYPE} STREQUAL "SHARED")
            set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_IMPLIB_RELEASE ${${_LIB_NAME}_LIB})
        else()
            set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES IMPORTED_LOCATION ${${_LIB_NAME}_LIB})
        endif()

        if (EXISTS ${${pkg_name}_BASE_DIR}/include)
            set_target_properties(${pkg_name}::${_LIB_NAME} PROPERTIES 
                INTERFACE_INCLUDE_DIRECTORIES "${${pkg_name}_BASE_DIR}/include")
        endif ()

        list(APPEND ${pkg_name}_LIBS ${pkg_name}::${_LIB_NAME})
        message("found ${${_LIB_NAME}_LIB}")
        STRING( REGEX REPLACE "(.+)/(.+)" "\\1" LIBPATH ${${_LIB_NAME}_LIB})
        set(${pkg_name}_LIBPATH ${LIBPATH} CACHE STRING INTERNAL)
    endforeach(_LIB_NAME)

    set(${pkg_name}_LIBS ${${pkg_name}_LIBS} PARENT_SCOPE)
endfunction()

function(__exec_cmd)
    set(options )
    set(oneValueArgs WORKING_DIRECTORY)
    set(multiValueArgs COMMAND)

    cmake_parse_arguments(EXEC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

    execute_process(COMMAND ${EXEC_COMMAND}
            WORKING_DIRECTORY ${EXEC_WORKING_DIRECTORY}
            RESULT_VARIABLE RESULT)
    if(NOT RESULT EQUAL "0")
        message(FATAL_ERROR "error! when ${EXEC_COMMAND} in ${EXEC_WORKING_DIRECTORY}")
    endif()
endfunction()

function(__check_patches pkg_patches)
    # check patches
    if (PKG_PATCHES)
        file(TOUCH ${_MS_LIB_CACHE}/${pkg_name}_patch.md5)
        file(READ ${_MS_LIB_CACHE}/${pkg_name}_patch.md5 ${pkg_name}_PATCHES_MD5)

        message("patches md5:${${pkg_name}_PATCHES_MD5}")

        set(${pkg_name}_PATCHES_NEW_MD5 )
        foreach(_PATCH ${PKG_PATCHES})
            file(MD5 ${_PATCH} _PF_MD5)
            set(${pkg_name}_PATCHES_NEW_MD5 "${${pkg_name}_PATCHES_NEW_MD5},${_PF_MD5}")
        endforeach(_PATCH)

        if (NOT ${pkg_name}_PATCHES_MD5 STREQUAL ${pkg_name}_PATCHES_NEW_MD5)
            set(${pkg_name}_PATCHES ${PKG_PATCHES})
            file(REMOVE_RECURSE "${_MS_LIB_CACHE}/${pkg_name}-subbuild")
            file(WRITE ${_MS_LIB_CACHE}/${pkg_name}_patch.md5 ${${pkg_name}_PATCHES_NEW_MD5})
            message("patches changed : ${${pkg_name}_PATCHES_NEW_MD5}")
        endif ()
    endif ()
endfunction()

201
set(AKG_FIND_NO_DEFAULT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH
C
ckey_Dou 已提交
202 203 204
                            NO_CMAKE_BUILDS_PATH NO_CMAKE_PACKAGE_REGISTRY NO_CMAKE_SYSTEM_PATH
                            NO_CMAKE_SYSTEM_PACKAGE_REGISTRY)

205
function(akg_add_pkg pkg_name )
C
ckey_Dou 已提交
206
    set(options )
207 208
    set(oneValueArgs URL MD5 GIT_REPOSITORY GIT_TAG VER EXE DIR CMAKE_PATH CUSTOM_CMAKE)
    set(multiValueArgs CMAKE_OPTION LIBS PATCHES)
C
ckey_Dou 已提交
209 210
    cmake_parse_arguments(PKG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )

211
    if(NOT PKG_LIB_PATH)
212
        set(PKG_LIB_PATH lib)
213
    endif()
214

C
ckey_Dou 已提交
215 216 217 218
    set(__FIND_PKG_NAME ${pkg_name})
    string(TOLOWER ${pkg_name} pkg_name)
    message("pkg name:${__FIND_PKG_NAME},${pkg_name}")

219 220 221 222 223 224 225
    # Generate hash for current pkg
    set(${pkg_name}_CUSTOM_CMAKE_HASH )
    if(PKG_CUSTOM_CMAKE)
        file(MD5 ${PKG_CUSTOM_CMAKE}/CMakeLists.txt _CUSTOM_CMAKE_MD5)
        set(${pkg_name}_CUSTOM_CMAKE_HASH "${_CUSTOM_CMAKE_MD5}")
    endif()

C
ckey_Dou 已提交
226 227 228 229 230 231 232 233
    set(${pkg_name}_PATCHES_HASH )
    foreach(_PATCH ${PKG_PATCHES})
        file(MD5 ${_PATCH} _PF_MD5)
        set(${pkg_name}_PATCHES_HASH "${${pkg_name}_PATCHES_HASH},${_PF_MD5}")
    endforeach(_PATCH)

    set(${pkg_name}_CONFIG_TXT
            "${CMAKE_CXX_COMPILER_VERSION}-${CMAKE_C_COMPILER_VERSION}
234
            ${ARGN} - ${${pkg_name}_USE_STATIC_LIBS}- ${${pkg_name}_PATCHES_HASH}- ${${pkg_name}_CUSTOM_CMAKE_HASH}
C
ckey_Dou 已提交
235 236 237 238 239
            ${${pkg_name}_CXXFLAGS}--${${pkg_name}_CFLAGS}--${${pkg_name}_LDFLAGS}")
    string(REPLACE ";" "-" ${pkg_name}_CONFIG_TXT ${${pkg_name}_CONFIG_TXT})
    string(MD5 ${pkg_name}_CONFIG_HASH ${${pkg_name}_CONFIG_TXT})

    message("${pkg_name} config hash: ${${pkg_name}_CONFIG_HASH}")
240
    # Generate hash for current pkg end
C
ckey_Dou 已提交
241

242
    set(${pkg_name}_BASE_DIR ${_MS_LIB_CACHE}/${pkg_name}_${${pkg_name}_CONFIG_HASH})
C
ckey_Dou 已提交
243 244
    set(${pkg_name}_DIRPATH ${${pkg_name}_BASE_DIR} CACHE STRING INTERNAL)

245 246 247 248 249 250 251
    if(NOT PKG_EXE)
        set(PKG_EXE 0)
    endif()

    set(${__FIND_PKG_NAME}_ROOT ${${pkg_name}_BASE_DIR})
    set(${__FIND_PKG_NAME}_ROOT ${${pkg_name}_BASE_DIR} PARENT_SCOPE)

252
    # Check if pkg exists in cache, if exists, use the cached one
253 254 255 256 257 258 259
    if (PKG_LIBS)
        __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH} ${PKG_LIBS})
        if(${pkg_name}_LIBS)
            set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
            message("Found libs: ${${pkg_name}_LIBS}")
            return()
        endif()
260
    endif()
261

262 263 264
    # Download pkg
    if(NOT PKG_DIR)
        if(PKG_GIT_REPOSITORY)
C
ckey_Dou 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277
            __download_pkg_with_git(${pkg_name} ${PKG_GIT_REPOSITORY} ${PKG_GIT_TAG} ${PKG_MD5})
        else()
            message("--__download_pkg")
	    __download_pkg(${pkg_name} ${PKG_URL} ${PKG_MD5})
        endif()
        foreach(_SUBMODULE_FILE ${PKG_SUBMODULES})
            STRING( REGEX REPLACE "(.+)_(.+)" "\\1" _SUBMODEPATH ${_SUBMODULE_FILE})
            STRING( REGEX REPLACE "(.+)/(.+)" "\\2" _SUBMODENAME ${_SUBMODEPATH})
            file(GLOB ${pkg_name}_INSTALL_SUBMODULE ${_SUBMODULE_FILE}/*)
            file(COPY ${${pkg_name}_INSTALL_SUBMODULE} DESTINATION ${${pkg_name}_SOURCE_DIR}/3rdparty/${_SUBMODENAME})
        endforeach (_SUBMODULE_FILE)
    else()
        set(${pkg_name}_SOURCE_DIR ${PKG_DIR})
278
    endif()
C
ckey_Dou 已提交
279 280
    message("${pkg_name}_SOURCE_DIR : ${${pkg_name}_SOURCE_DIR}")

281
    # Copy pkg to the build directory and uses the copied one
W
wenfangpei 已提交
282 283
    set(${pkg_name}_PATCHED_DIR ${CMAKE_BINARY_DIR}/${pkg_name})
    if(EXISTS ${${pkg_name}_PATCHED_DIR})
284
        file(REMOVE_RECURSE ${${pkg_name}_PATCHED_DIR})
W
wenfangpei 已提交
285
    endif()
286
    file(MAKE_DIRECTORY "${${pkg_name}_PATCHED_DIR}")
W
wenfangpei 已提交
287
    file(COPY ${${pkg_name}_SOURCE_DIR}/ DESTINATION ${${pkg_name}_PATCHED_DIR})
288 289
    set(${pkg_name}_SOURCE_DIR ${${pkg_name}_PATCHED_DIR})
    message("${pkg_name}_SOURCE_DIR : ${${pkg_name}_SOURCE_DIR}")
W
wenfangpei 已提交
290

291
    # Apply patches on pkg
C
ckey_Dou 已提交
292 293 294 295
    foreach(_PATCH_FILE ${PKG_PATCHES})
        get_filename_component(_PATCH_FILE_NAME ${_PATCH_FILE} NAME)
        set(_LF_PATCH_FILE ${CMAKE_BINARY_DIR}/_ms_patch/${_PATCH_FILE_NAME})
        configure_file(${_PATCH_FILE} ${_LF_PATCH_FILE} NEWLINE_STYLE LF)
296
        message("patching ${${pkg_name}_SOURCE_DIR} -p1 < ${_LF_PATCH_FILE}")
C
ckey_Dou 已提交
297
        execute_process(COMMAND patch -p1 INPUT_FILE ${_LF_PATCH_FILE}
298
                        WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}
W
wenfangpei 已提交
299
                        RESULT_VARIABLE Result)
C
ckey_Dou 已提交
300 301
        if(NOT Result EQUAL "0")
            message(FATAL_ERROR "Failed patch: ${_LF_PATCH_FILE}")
302
        endif()
C
ckey_Dou 已提交
303 304 305 306 307 308 309
    endforeach(_PATCH_FILE)
 
    file(LOCK ${${pkg_name}_BASE_DIR} DIRECTORY GUARD FUNCTION RESULT_VARIABLE ${pkg_name}_LOCK_RET TIMEOUT 600)
    if(NOT ${pkg_name}_LOCK_RET EQUAL "0")
        message(FATAL_ERROR "error! when try lock ${${pkg_name}_BASE_DIR} : ${${pkg_name}_LOCK_RET}")
    endif()

310
    if(PKG_CUSTOM_CMAKE)
311 312
        file(GLOB ${pkg_name}_cmake ${PKG_CUSTOM_CMAKE}/CMakeLists.txt)
        file(COPY ${${pkg_name}_cmake} DESTINATION ${${pkg_name}_SOURCE_DIR})
313
    endif()
314 315

    if(${pkg_name}_SOURCE_DIR)
316
        if(PKG_CMAKE_OPTION)
317 318
            # in cmake
            file(MAKE_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
319
            if(${pkg_name}_CFLAGS)
320
                set(${pkg_name}_CMAKE_CFLAGS "-DCMAKE_C_FLAGS=${${pkg_name}_CFLAGS}")
321
            endif()
322 323
            if (${pkg_name}_CXXFLAGS)
                set(${pkg_name}_CMAKE_CXXFLAGS "-DCMAKE_CXX_FLAGS=${${pkg_name}_CXXFLAGS}")
324
            endif()
325 326 327 328 329 330

            if (${pkg_name}_LDFLAGS)
                if (${pkg_name}_USE_STATIC_LIBS)
                    set(${pkg_name}_CMAKE_LDFLAGS "-DCMAKE_STATIC_LINKER_FLAGS=${${pkg_name}_LDFLAGS}")
                else()
                    set(${pkg_name}_CMAKE_LDFLAGS "-DCMAKE_SHARED_LINKER_FLAGS=${${pkg_name}_LDFLAGS}")
331 332
                endif()
            endif()
333 334 335

            __exec_cmd(COMMAND ${CMAKE_COMMAND} ${PKG_CMAKE_OPTION} -G ${CMAKE_GENERATOR}
                    ${${pkg_name}_CMAKE_CFLAGS} ${${pkg_name}_CMAKE_CXXFLAGS} ${${pkg_name}_CMAKE_LDFLAGS}
336
                    ${${pkg_name}_CONFIG_FILE_DIR} ${${pkg_name}_DEPEND_INCLUDE_DIR} ${${pkg_name}_DEPEND_LIB_DIR}
337 338 339 340 341
                    -DCMAKE_INSTALL_PREFIX=${${pkg_name}_BASE_DIR} ${${pkg_name}_SOURCE_DIR}/${PKG_CMAKE_PATH}
                    WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)

            __exec_cmd(COMMAND ${CMAKE_COMMAND} --build . --target install -- -j${THNUM}
                    WORKING_DIRECTORY ${${pkg_name}_SOURCE_DIR}/_build)
342
        endif()
343 344 345 346 347 348 349 350 351 352 353 354 355 356
    endif()

    if (PKG_LIBS)
        __find_pkg_then_add_target(${pkg_name} ${PKG_EXE} ${PKG_LIB_PATH} ${PKG_LIBS})
        set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
        if(NOT ${pkg_name}_LIBS)
            message(FATAL_ERROR "Can not find pkg: ${pkg_name}")
        endif()
    else()
        find_package(${__FIND_PKG_NAME} ${PKG_VER} QUIET)
        if (${__FIND_PKG_NAME}_FOUND)
            set(${pkg_name}_INC ${${pkg_name}_BASE_DIR}/include PARENT_SCOPE)
            message("Found pkg: ${${__FIND_PKG_NAME}_LIBRARIES}")
            return()
357 358
        endif()
    endif()
C
ckey_Dou 已提交
359
endfunction()