HomeBlogMagic

CMAKE Makro für downloading und extracting

Vor einiger Zeit habe ich in meinem Framework ein download Makro für CMAKE geschrieben, welches mir auch gleich das zip entpackt.

Das Makro ist so gehalten, dass wenn der Ordner existiert, wird nicht noch einmal heruntergeladen. Des weiteren, sollte das herunterladen unterbrochen werden, dann wird das vom Makro beim nächsten durchlauf erkannt, aufgeräumt und neu geladen.

Da die Archive unterschiedliche Algorithmen benutzen lasse ich den Download auf .zipped enden. CMAKE erkennt das Archiv automatisch. Das hat bei mir bisher mit .zip .7z .tar.gz einwandfrei funktioniert.

Wer das Script mal live sehen will, braucht nur cmake in meinem Framework laufen lassen. Das beste Beispiel ist hier das buildSTM32F4Dicovery-Setup im Tools-Ordner, welches auch die Toolchain und einige ThirdParty Bibliotheken nachlädt.

################################################################################
# Download an archive and extract
# If this direcotry exists, the download will be skipped.
# If an error or interruption occured, the download will repeated next time.
# @param TargetName: Name of Package, just for output to commandline
# @param TargetDir:  Target output directory to extract packte to.
#                    This path will also be used for temporary files:  
#                       ${TargetDir}.zipped
#                       ${TargetDir}.progress
# @param SourceUrl: Url to download package from
################################################################################
macro(CcDownloadAndExtract TargetName TargetDir SourceUrl )
  set(TargetZipFile "${TargetDir}.zipped")
  set(TargetProgress "${TargetDir}.progress")
  if(EXISTS ${TargetProgress})
    if(EXISTS ${TargetZipFile})
      file(REMOVE ${TargetZipFile})
    endif()
    if(EXISTS ${TargetDir})
      file(REMOVE_RECURSE ${TargetDir})
    endif()
  elseif(EXISTS ${TargetDir})
    # Do not create progress!
  else()
    file(WRITE ${TargetProgress} "In progress")
  endif()
  if(NOT EXISTS ${TargetDir})
    if(NOT EXISTS ${TargetZipFile})
      message("- Download ${TargetName}")
      file( DOWNLOAD ${SourceUrl} 
            ${TargetZipFile}
            STATUS DOWNLOAD_STATUS)
      list(GET DOWNLOAD_STATUS 0 NUMERIC_STATUS)
      if(NOT ${NUMERIC_STATUS} EQUAL 0)
        file(REMOVE ${TargetZipFile})
        message(FATAL_ERROR "- Download result: ${DOWNLOAD_STATUS}")
      else()
        message("- Download succeeded, extracting")
      endif()    
    endif()

    if(EXISTS ${TargetZipFile})
      file(MAKE_DIRECTORY ${TargetDir})
      execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf ${TargetZipFile}
                      WORKING_DIRECTORY                  ${TargetDir}
                      RESULT_VARIABLE TargetZipFile_EXTRACT_RESULT)
      if(${TargetZipFile_EXTRACT_RESULT} EQUAL 0)
        message("- Extracting succeeded")
        file(REMOVE ${TargetZipFile})
        if(EXISTS ${TargetProgress})
          file(REMOVE ${TargetProgress})
        endif()
      else()
        file(REMOVE ${TargetZipFile})
        file(REMOVE_RECURSE ${TargetDir})
        message(FATAL_ERROR "- Extract error: ${TargetZipFile_EXTRACT_RESULT}")
      endif()
    endif()
  else(NOT EXISTS ${TargetDir})
    message("- Download ${TargetName} not required: ${TargetDir}")       
  endif()
endmacro()