Reputation: 123
I have a simple batch script that is building a Xamarin forms project. It works when I run it manually on the machine, but it fails when I try to run it as a build step through Jenkins. I get the following error:
Did not find Android SDK
C:\Program Files x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(567,2):
error XA5205: The Android SDK Directory could not be found.
Please set via/p:AndroidSdkDirectory
.
I'm pretty sure I have all of my environment system variables set correctly.
PATH includes C:\Program Files\Android\android-sdk
I also have ANDROID_HOME set to C:\Program Files\Android\android-sdk
as well. I have not set it via /p:AndroidSdkDirectory
(which I plan on doing now) but I am still interested in why it can't find it through PATH or ANDROID_HOME. Any help would be greatly appreciated! Thanks!
EDIT:
My batch file:
SET projectPath=%1
SET projectName=%2
SET keystorePath=%3
SET password=%4
SET alias=%5
SET config=%6
SET apkName=%7
msbuild %projectPath%\%projectName% /p:Configuration=%config% /t:Clean
msbuild %projectPath%\%projectName% /p:Configuration=%config% /t:PackageForAndroid /p:AndroidSdkDirectory="C:\Program Files\Android\android-sdk"
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore %keystorePath% -storepass %password% -signedjar %projectPath%\bin\%config%\com.company.helloworld-signed.apk %projectPath%\bin\%config%\com.company.helloworld.apk %alias%
zipalign -f -v 4 %projectPath%\bin\%config%\com.company.helloworld-signed.apk %projectPath%\bin\%config%\%apkName%.apk
My system variables:
ANDROID_NDK_PATH "C:\Program Files\Android\android-ndk-rl3b"
ANDROID_SDK_HOME "C:\Program Files\Android\android-sdk"
ComSpec C:\Windows\system32\cmd.exe
SDK_HOME C:\Program Files\Java\jdk1.8.0_121
NUMBER_OF_PROCESSORS 4
OS Windows_NT
My system PATH
:
C:\ProgramData\Oracle\Java\javapath
%SystemRoot%\system32
%SystemRoot%
%SystemRoot%\System32\Wbem
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static
C:\Program Files (x86)\Skype\Phone\
%USERPROFILE%\.dnx\bin
C:\Program Files\Microsoft DNX\Dnvm\
C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit
C:\Program Files\Microsoft SQL Server\130\Tools\Binn\
C:\Program Files\Perforce
C:\Program Files\Perforce\DVCS\
C:\Program Files (x86)\MSBuild\14.0\Bin
C:\Program Files\Java\jdk1.8.0_121
C:\Program Files\Android\android-sdk
C:\Program Files\Java\jre1.8.0_121\bin
C:\Program Files\Java\jdk1.8.0_121\bin
C:\Program Files\Android\android-sdk\build-tools\25.0.2
I have installed Jenkins as a Windows service.
Upvotes: 1
Views: 1141
Reputation: 49086
It is interesting that the error message line
C:\Program Files x86)\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(567,2):
Contains a space character instead of an opening parenthesis
(
left of x86
.
The system PATH
environment variable should not have as first directory path
C:\ProgramData\Oracle\Java\javapath
This should be the fifth directory path in the list of directories.
I don't have Android SDK installed ever on one of my Windows computers, but I find it curious that the directory paths of ANDROID_SDK_HOME
and ANDROID_SDK_HOME
are defined with the surrounding double quotes included.
That can be right, but could cause also problems depending on how those two environment variables are referenced by batch files or used in applications.
Directory paths are assigned to environment variables usually without surrounding double quotes.
On the batch file the handling of first and second argument could be a problem.
SET projectPath=%1
SET projectName=%2
msbuild %projectPath%\%projectName% /p:Configuration=%config% /t:Clean
If project path or project name contains a space character or one of these characters &()[]{}^=;!'+,`~
they must be specified being enclosed in double quotes on starting the batch file. It is common practice to pass directory paths, file names and other parameters to batch files enclosed in double quotes.
The first and second argument are assigned to the environment variables projectPath
and projectName
as defined on command line on starting the batch file which means without or with surrounding double quotes. In case of project path and project name are enclosed in double quotes, the third line is expanded before execution for example to:
msbuild "C:\Project Path"\"Project Name" /p:Configuration=xxx /t:Clean
That is not good. It could work depending on how good error correction of Windows command interpreter respectively the kernel functions of Windows are. But it would be definitely better to make sure the double quotes are removed on assigning the batch file arguments to environment variables and enclose the parameter strings in double quotes where it is needed or at least strongly recommended on referencing them in the command lines below.
It would make also sense in a batch file used by Jenkins to avoid dependency of the environment variables PATH
and PATHEXT
as much as possible especially on running Jenkins as service with system account by specifying the applications to execute with full path and with file extension not using environment variables or using system environment variables defined by Windows itself.
Here is a batch code written without having Jenkins, MSBuild, Java SDK, Java JDK or Android SDK installed at all with assuming that the config
parameter is a short word never containing any critical character.
set "projectPath=%~1"
set "projectName=%~2"
set "keystorePath=%~3"
set "password=%~4"
set "alias=%~5"
set "config=%~6"
set "apkName=%~7"
rem Get directory paths of used applications for build task.
for /D %%I in ("%ProgramFiles(x86)%\MSBuild\*") do set "MSBUILD_PATH=%%I\Bin"
for /D %%I in ("%ProgramFiles%\Java\jdk*") do set "JAVA_JDK_PATH=%%I\bin"
"%MSBUILD_PATH%\msbuild.exe" "%projectPath%\%projectName%" /p:Configuration=%config% /t:Clean
"%MSBUILD_PATH%\msbuild.exe" "%projectPath%\%projectName%" /p:Configuration=%config% /t:PackageForAndroid /p:AndroidSdkDirectory="%ProgramFiles%\Android\android-sdk"
"%JAVA_JDK_PATH%\jarsigner.exe" -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore "%keystorePath%" -storepass "%password%" -signedjar "%projectPath%\bin\%config%\com.company.helloworld-signed.apk" "%projectPath%\bin\%config%\com.company.helloworld.apk" "%alias%"
"%JAVA_JDK_PATH%\zipalign.exe" -f -v 4 "%projectPath%\bin\%config%\com.company.helloworld-signed.apk" "%projectPath%\bin\%config%\%apkName%.apk"
I don't know if it is really a good idea to find with the batch file the MSBuild and the Java JDK path or using a system environment variable. The automatic search for MSBuild and Java JDK paths might not be a good idea if having multiple versions of MSBuild and/or Java JDK installed.
However, assigning the batch file arguments to the environment variables with removing enclosing double quotes as done with %~1
, %~2
, ... and later enclose the variable parameter strings in double quotes is highly recommended.
The help output by running in a command prompt window call /?
explains which modifiers can be used on referencing arguments.
Pages found with a www search engine related to this issue:
Those web pages are 4 of top 7 results on searching with my preferred world wide web search engine for the term "Android SDK Directory could not be found"
enclosed in double quotes as posted here to find pages containing exactly this term.
One more hint:
System environment variables defined or edited by the user via Windows Control Panel become effective only for applications and services started after the modification.
All services, processes and applications already running have already their own set of environment variables created by Windows automatically in memory of already running service/process/application derived from parent process on starting the service/process/application.
It is not possible that a parent process manipulates the environment variables of any running child process nor can a child process manipulate the environment variables of its parent process.
Every process has its own environment variables list created by Windows automatically as copy of environment variables list of the process starting the new process.
So for Windows services running in background a modification of a system environment variable needs at least stopping and restarting the service or perhaps even restarting Windows depending on what is the parent process of the running Windows service.
Upvotes: 1