windeps.bat 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. :: MIT License
  2. :: Copyright (c) 2023 SineStriker
  3. :: Description: This script calls `qmcorecmd` to deploy dependencies on Windows.
  4. @echo off
  5. setlocal enabledelayedexpansion
  6. :: Initialize arguments
  7. set "INPUT_DIR="
  8. set "PLUGIN_DIR="
  9. set "LIB_DIR="
  10. set "QML_DIR="
  11. set "QMAKE_PATH="
  12. set "CORECMD_PATH="
  13. set "VERBOSE="
  14. set "FILES="
  15. set "EXTRA_PLUGIN_PATHS="
  16. set "PLUGINS=" & set /a "PLUGIN_COUNT=0"
  17. set "QML_REL_PATHS="
  18. set "ARGS="
  19. :: Parse command line
  20. :parse_args
  21. if "%~1"=="" goto :end_parse_args
  22. if "%1"=="-i" set "INPUT_DIR=%~2" & shift & shift & goto :parse_args
  23. if "%1"=="-m" set "CORECMD_PATH=%~2" & shift & shift & goto :parse_args
  24. if "%1"=="--plugindir" set "PLUGIN_DIR=%~2" & shift & shift & goto :parse_args
  25. if "%1"=="--libdir" set "LIB_DIR=%~2" & shift & shift & goto :parse_args
  26. if "%1"=="--qmldir" set "QML_DIR=%~2" & shift & shift & goto :parse_args
  27. if "%1"=="--qmake" set "QMAKE_PATH=%~2" & shift & shift & goto :parse_args
  28. if "%1"=="--extra" set "EXTRA_PLUGIN_PATHS=!EXTRA_PLUGIN_PATHS! %~2" & shift & shift & goto :parse_args
  29. if "%1"=="--plugin" set /a "PLUGIN_COUNT+=1" & set "PLUGINS[!PLUGIN_COUNT!]=%~2" & shift & shift & goto :parse_args
  30. if "%1"=="--qml" set "QML_REL_PATHS=!QML_REL_PATHS! %~2" & shift & shift & goto :parse_args
  31. if "%1"=="--copy" set "ARGS=!ARGS! -c %~2 %~3" & shift & shift & shift & goto :parse_args
  32. if "%1"=="-f" set "ARGS=!ARGS! -f" & shift & goto :parse_args
  33. if "%1"=="-s" set "ARGS=!ARGS! -s" & shift & goto :parse_args
  34. if "%1"=="-V" set "VERBOSE=-V" & shift & goto :parse_args
  35. if "%1"=="-h" call :usage & exit /b
  36. if "%1"=="-@" set "ARGS=!ARGS! -@ %~2" & shift & shift & goto :parse_args
  37. if "%1"=="-L" set "ARGS=!ARGS! -L %~2" & shift & shift & goto :parse_args
  38. shift
  39. goto :parse_args
  40. :end_parse_args
  41. :: Check required arguments
  42. if not defined INPUT_DIR echo Error: Missing required argument 'INPUT_DIR' & call :usage & exit /b
  43. if not defined PLUGIN_DIR echo Error: Missing required argument 'PLUGIN_DIR' & call :usage & exit /b
  44. if not defined LIB_DIR echo Error: Missing required argument 'LIB_DIR' & call :usage & exit /b
  45. if not defined QML_DIR echo Error: Missing required argument 'QML_DIR' & call :usage & exit /b
  46. if not defined CORECMD_PATH echo Error: Missing required argument 'CORECMD_PATH' & call :usage & exit /b
  47. :: Normalize
  48. set "INPUT_DIR=!INPUT_DIR:/=\!"
  49. set "PLUGIN_DIR=!PLUGIN_DIR:/=\!"
  50. set "LIB_DIR=!LIB_DIR:/=\!"
  51. set "QML_DIR=!QML_DIR:/=\!"
  52. set "CORECMD_PATH=!CORECMD_PATH:/=\!"
  53. :: Get Qt plugin and QML paths
  54. set "PLUGIN_PATHS="
  55. set "QML_PATH="
  56. if defined QMAKE_PATH (
  57. for /f "tokens=*" %%a in ('!QMAKE_PATH! -query QT_INSTALL_PLUGINS') do set "QMAKE_PLUGIN_PATH=%%a"
  58. set "PLUGIN_PATHS=!QMAKE_PLUGIN_PATH!"
  59. for /f "tokens=*" %%a in ('!QMAKE_PATH! -query QT_INSTALL_QML') do set "QML_PATH=%%a"
  60. set "QML_PATH=!QML_PATH:/=\!"
  61. :: Add Qt bin directory
  62. for /f "tokens=*" %%a in ('!QMAKE_PATH! -query QT_INSTALL_BINS') do set "QT_BIN_PATH=%%a"
  63. set "ARGS=!ARGS! -L !QT_BIN_PATH!"
  64. )
  65. :: Add extra plugin searching paths
  66. set "PLUGIN_PATHS=!PLUGIN_PATHS! !EXTRA_PLUGIN_PATHS!"
  67. :: Ensure that the QML search path is not empty
  68. :: when the QML related path is specified (qmake needs to be specified)
  69. if not "%QML_REL_PATHS%"=="" (
  70. if "%QML_PATH%"=="" (
  71. echo Error: qmake path must be specified when QML paths are provided
  72. exit /b
  73. )
  74. )
  75. :: The type of file to be searched depends on the operating system
  76. :: On Windows, search for.exe and.dll files
  77. for /r "%INPUT_DIR%" %%f in (*.exe *.dll) do (
  78. set "FILES=!FILES! %%f"
  79. )
  80. :: Find the full path to the Qt plugin
  81. for /L %%i in (1,1,%PLUGIN_COUNT%) do (
  82. set "plugin_path=!PLUGINS[%%i]!"
  83. :: Check format
  84. echo !plugin_path! | findstr /R "[^/]*\/[^/]*" >nul
  85. if errorlevel 1 (
  86. echo Error: Invalid plugin format '!plugin_path!'. Expected format: ^<category^>/^<name^>
  87. exit /b
  88. )
  89. :: Extracts the category and name
  90. for /f "tokens=1,2 delims=/" %%a in ("!plugin_path!") do (
  91. set "category=%%a"
  92. set "name=%%b"
  93. :: Calculate destination directory
  94. set "DESTINATION_DIR=!PLUGIN_DIR!\!category!"
  95. set "DESTINATION_DIR=!DESTINATION_DIR:/=\!"
  96. :: Traverse the path and find the specific plug-in file
  97. set "FOUND_PLUGINS="
  98. call :search_plugin
  99. if not defined FOUND_PLUGINS (
  100. echo Error: Plugin '!plugin_path!' not found in any search paths.
  101. exit /b
  102. )
  103. )
  104. )
  105. :: Process QML directories
  106. for %%q in (%QML_REL_PATHS%) do (
  107. call :search_qml_dir "%%q"
  108. )
  109. :: Build and execute the deploy command
  110. set "DEPLOY_CMD=!CORECMD_PATH! deploy !FILES! !ARGS! -o !LIB_DIR! !VERBOSE!"
  111. if "!VERBOSE!"=="-V" echo Executing: !DEPLOY_CMD!
  112. call !DEPLOY_CMD!
  113. :: Check the deployment result
  114. if %errorlevel% neq 0 exit /b
  115. exit /b
  116. :: ----------------------------------------------------------------------------------
  117. :: Search plugins
  118. :search_plugin
  119. for %%d in (!PLUGIN_PATHS!) do (
  120. for %%f in ("%%d\!category!\!name!.dll") do (
  121. if exist "%%f" (
  122. call :check_debug "%%f"
  123. if "!ok!"=="0" (
  124. call :add_plugin "%%f"
  125. )
  126. )
  127. )
  128. )
  129. exit /b
  130. :: ----------------------------------------------------------------------------------
  131. :: ----------------------------------------------------------------------------------
  132. :: Add plugin if not already found
  133. :add_plugin
  134. set "plugin=%~1"
  135. set "plugin_name=%~nx1"
  136. for %%i in (!FOUND_PLUGINS!) do (
  137. if "%%i"=="!plugin_name!" (
  138. exit /b
  139. )
  140. )
  141. set "FOUND_PLUGINS=!FOUND_PLUGINS! !plugin_name!"
  142. set "ARGS=!ARGS! -c !plugin! !DESTINATION_DIR!"
  143. exit /b
  144. :: ----------------------------------------------------------------------------------
  145. :: ----------------------------------------------------------------------------------
  146. :: Search QML directory
  147. :search_qml_dir
  148. set "full_path=%QML_PATH%\%~1"
  149. if exist "%full_path%\" (
  150. :: Directory
  151. for /r "%full_path%" %%f in (*) do (
  152. call :handle_qml_file "%%f"
  153. )
  154. ) else if exist "%full_path%" (
  155. :: File
  156. call :handle_qml_file "%full_path%"
  157. )
  158. exit /b
  159. :: ----------------------------------------------------------------------------------
  160. :: ----------------------------------------------------------------------------------
  161. :: Check debug version of a dll
  162. :check_debug
  163. set "ok=1"
  164. set "file_path=%~1"
  165. if "!file_path:~-4!"==".pdb" exit /b
  166. if "!file_path:~-10!"==".dll.debug" exit /b
  167. if "!file_path:~-5!" == "d.dll" (
  168. set "prefix=!file_path:~0,-5!"
  169. if exist "!prefix!.dll" (
  170. exit /b
  171. )
  172. )
  173. set "ok=0"
  174. exit /b
  175. :: ----------------------------------------------------------------------------------
  176. :: ----------------------------------------------------------------------------------
  177. :: Copy or add to a deployment command
  178. :handle_qml_file
  179. set "file=%~1"
  180. set "file=!file:/=\!"
  181. :: Ignore specific files (example)
  182. call :check_debug "%file%"
  183. if "!ok!"=="1" (
  184. exit /b
  185. )
  186. :: Computes target file and folder in a very stupid way
  187. set "rel_path=!file:%QML_PATH%\=!"
  188. set "target=%QML_DIR%\%rel_path%"
  189. for %%I in ("!file!") do (
  190. set "file_dir=%%~dpI"
  191. )
  192. set "rel_dir_path=!file_dir:%QML_PATH%\=!"
  193. set "target_dir=%QML_DIR%\%rel_dir_path%"
  194. :: Determine whether it is an executable binary file and handle it accordingly
  195. if "%file:~-4%"==".dll" (
  196. set "ARGS=!ARGS! -c !file! !target_dir!"
  197. ) else if "%file:~-4%"==".exe" (
  198. set "ARGS=!ARGS! -c !file! !target_dir!"
  199. ) else (
  200. if not exist "%target%" (
  201. mkdir "%target_dir%" >nul 2>&1
  202. )
  203. copy /Y "%file%" "%target%" >nul 2>&1
  204. )
  205. exit /b
  206. :: ----------------------------------------------------------------------------------
  207. :: ----------------------------------------------------------------------------------
  208. :: Show usage
  209. :usage
  210. echo Usage: %~n0 -i ^<dir^> -m ^<path^>
  211. echo --plugindir ^<plugin_dir^> --libdir ^<lib_dir^> --qmldir ^<qml_dir^>
  212. echo [--qmake ^<qmake_path^>] [--extra ^<extra_path^>]...
  213. echo [--qml ^<qml_module^>]... [--plugin ^<plugin^>]... [--copy ^<src^> ^<dest^>]...
  214. echo [-@ ^<file^>]... [-L ^<path^>]...
  215. echo [-f] [-s] [-V] [-h]
  216. exit /b
  217. :: ----------------------------------------------------------------------------------