2022-05-18 11:58:54 +03:00
|
|
|
<?php
|
|
|
|
namespace taskman;
|
|
|
|
use Exception;
|
|
|
|
|
|
|
|
task('unity', function()
|
|
|
|
{
|
|
|
|
$unity_path = guess_unity_app_dir();
|
2022-05-31 15:08:31 +03:00
|
|
|
$proj_path = normalize_path(get("UNITY_ASSETS_DIR") . '/../');
|
2022-05-18 11:58:54 +03:00
|
|
|
if(is_win())
|
|
|
|
{
|
|
|
|
$unity_app_path = "'$unity_path/Editor/Unity.exe'";
|
2022-08-09 11:02:35 +03:00
|
|
|
run_background_proc($unity_app_path, ['-projectPath', "$proj_path"]);
|
2022-05-18 11:58:54 +03:00
|
|
|
}
|
2023-07-06 22:19:58 +03:00
|
|
|
else if(is_linux())
|
|
|
|
{
|
|
|
|
$unity_path = get('UNITY_APP_DIR');
|
|
|
|
$unity_app_path = "'$unity_path/Editor/Unity'";
|
|
|
|
run_background_proc($unity_app_path, ['-projectPath', "$proj_path"]);
|
|
|
|
}
|
2022-05-18 11:58:54 +03:00
|
|
|
else
|
|
|
|
{
|
2022-05-31 15:28:32 +03:00
|
|
|
$cmd = guess_unity_app_dir()."'Unity.app/Contents/MacOS/Unity' -projectPath '$proj_path' > /dev/null 2>&1&";
|
2022-05-18 11:58:54 +03:00
|
|
|
system($cmd, $res);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
task('unity_kill', function()
|
|
|
|
{
|
2023-03-21 18:39:27 +03:00
|
|
|
unity_kill();
|
2022-05-18 11:58:54 +03:00
|
|
|
});
|
|
|
|
|
|
|
|
function unity_exec($func, $build_target = "", $quit = true, $batchmode = true)
|
|
|
|
{
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
2022-06-01 15:01:42 +03:00
|
|
|
$proj_path = normalize_path(get("UNITY_ASSETS_DIR") . '/../');
|
2022-05-18 11:58:54 +03:00
|
|
|
|
|
|
|
$log_file = "$GAME_ROOT/build/unity.log";
|
|
|
|
ensure_rm($log_file);
|
|
|
|
|
|
|
|
$pid_file = "$GAME_ROOT/build/unity.pid";
|
|
|
|
|
|
|
|
$username = getor('UNITY_ACCOUNT_USERNAME', null);
|
|
|
|
$password = getor('UNITY_ACCOUNT_PASSWORD', null);
|
|
|
|
|
|
|
|
$shared_cmd = "-projectPath $proj_path -logFile $log_file "
|
|
|
|
. ($batchmode ? "-batchmode" : "")
|
|
|
|
. " -accept-apiupdate"
|
|
|
|
. ($quit ? " -quit" : "")
|
|
|
|
. ($build_target ? " -buildTarget $build_target" : "")
|
|
|
|
. ($func != "" ? " -executeMethod $func" : "");
|
|
|
|
|
|
|
|
if($username !== null && $password !== null)
|
|
|
|
$shared_cmd .= " -username \"$username\" -password \"$password\"";
|
|
|
|
|
|
|
|
$pid = unity_run_proc($shared_cmd);
|
|
|
|
if(!$pid)
|
|
|
|
throw new Exception("Error starting cmd: $shared_cmd");
|
|
|
|
|
|
|
|
while(!is_file($log_file))
|
|
|
|
usleep(200000);
|
|
|
|
|
|
|
|
return array($log_file, $pid);
|
|
|
|
}
|
|
|
|
|
2023-03-21 18:39:27 +03:00
|
|
|
function unity_batch_exec($func, $build_target = "")
|
2022-05-18 11:58:54 +03:00
|
|
|
{
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
2023-03-21 18:39:27 +03:00
|
|
|
unity_kill();
|
|
|
|
|
|
|
|
list($log_file, $pid) = unity_exec($func, $build_target, /*$quit = */ true, /*$batchmode = */ true);
|
|
|
|
|
|
|
|
watch_running_process(
|
|
|
|
$pid,
|
|
|
|
$log_file,
|
|
|
|
array(
|
|
|
|
'Exiting batchmode successfully',
|
|
|
|
'Batchmode quit successfully invoked - shutting down!'
|
|
|
|
),
|
|
|
|
array(
|
|
|
|
'Build Finished, Result: Failure',
|
|
|
|
'UnityException:',
|
|
|
|
'Aborting batchmode due to failure',
|
|
|
|
'Launching bug reporter',
|
|
|
|
'Unrecognized assets cannot be included in AssetBundles:'
|
|
|
|
),
|
|
|
|
true,
|
|
|
|
-1,
|
|
|
|
//ignored errors:
|
|
|
|
array(
|
|
|
|
//NOTE: weird editor crash, sometimes happens on exit after batch task is actually done
|
|
|
|
// seems like it's never been fixed though issue tracker says otherwise (https://vk.cc/bYpyUS)
|
|
|
|
"Fatal Error! GetManagerFromContext: pointer to object of manager 'MonoManager' is NULL (table index 5)"
|
|
|
|
),
|
|
|
|
|
|
|
|
//noted warnings: they don't abort execution but show up at the end of the log if command fails
|
|
|
|
array(
|
2022-05-18 11:58:54 +03:00
|
|
|
': error CS',
|
2023-03-21 18:39:27 +03:00
|
|
|
)
|
|
|
|
);
|
2022-05-18 11:58:54 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function unity_run_proc($shared_cmd)
|
|
|
|
{
|
|
|
|
$app_dir = get('UNITY_APP_DIR');
|
|
|
|
echo "Unity App dir: $app_dir\n";
|
|
|
|
|
|
|
|
if(is_win())
|
|
|
|
{
|
|
|
|
$unity_app_path = $app_dir . "Editor/Unity.exe";
|
|
|
|
$cmd = "powershell.exe (Start-Process '$unity_app_path'-ArgumentList '$shared_cmd' -passthru).Id";
|
|
|
|
}
|
2024-09-17 17:34:50 +03:00
|
|
|
else if(is_linux())
|
|
|
|
{
|
|
|
|
$cmd = "'$app_dir/Editor/Unity' $shared_cmd > /dev/null & echo $!";
|
|
|
|
}
|
2022-05-18 11:58:54 +03:00
|
|
|
else
|
|
|
|
{
|
|
|
|
$cmd = "'$app_dir/Unity.app/Contents/MacOS/Unity' $shared_cmd > /dev/null & echo $!";
|
|
|
|
}
|
|
|
|
|
|
|
|
exec($cmd, $out, $ret);
|
|
|
|
if($ret !== 0)
|
|
|
|
throw new Exception("Error starting Unity: $cmd ($ret)");
|
|
|
|
return trim($out[0]);
|
|
|
|
}
|
|
|
|
|
2023-03-21 18:39:27 +03:00
|
|
|
function unity_kill()
|
|
|
|
{
|
|
|
|
$proc_id = unity_find_proc_id();
|
|
|
|
if($proc_id)
|
|
|
|
{
|
|
|
|
echo "Found Unity process '$proc_id', killing it...\n";
|
|
|
|
system("kill -9 $proc_id");
|
|
|
|
sleep(5);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
echo "No Unity process found to kill\n";
|
|
|
|
}
|
|
|
|
|
2022-05-18 11:58:54 +03:00
|
|
|
function unity_find_proc_id()
|
|
|
|
{
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
exec("ps aux | grep 'Unity' | grep -i 'projectpath' | grep -v grep", $out);
|
|
|
|
foreach($out as $line)
|
|
|
|
if(preg_match('~.*?\s+(\d+).*-projectpath\s+(.*?)\s+-~i', $line, $ms))
|
|
|
|
if(strpos(realpath($ms[2]), realpath($GAME_ROOT)) === 0)
|
|
|
|
return $ms[1];
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function guess_unity_app_dir()
|
|
|
|
{
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
if(getenv("UNITY_APP_DIR"))
|
|
|
|
return getenv("UNITY_APP_DIR");
|
|
|
|
|
|
|
|
$path = "/Applications/Unity/";
|
|
|
|
if(is_win())
|
|
|
|
$path = getenv("ProgramFiles")."/Unity/";
|
|
|
|
|
|
|
|
$proj_version_file = $GAME_ROOT.'/unity/ProjectSettings/ProjectVersion.txt';
|
|
|
|
if(is_file($proj_version_file))
|
|
|
|
{
|
|
|
|
list($_, $unity_version) = array_map('trim', explode(":", file($proj_version_file)[0]));
|
2023-04-14 11:34:45 +03:00
|
|
|
$path .= "Hub/Editor/$unity_version/";
|
2022-05-18 11:58:54 +03:00
|
|
|
}
|
|
|
|
return $path;
|
|
|
|
}
|
|
|
|
|
|
|
|
function get_unity_dir()
|
|
|
|
{
|
|
|
|
$app_dir = get('UNITY_APP_DIR');
|
|
|
|
|
2023-07-06 21:46:00 +03:00
|
|
|
if(is_win() || is_linux())
|
2022-05-18 11:58:54 +03:00
|
|
|
return "$app_dir/Editor/Data";
|
|
|
|
else
|
|
|
|
return "$app_dir/Unity.app/Contents/";
|
|
|
|
}
|
|
|
|
|
2022-05-19 18:50:30 +03:00
|
|
|
function mono_mcs_bin()
|
|
|
|
{
|
|
|
|
if(!get("USE_UNITY_MONO"))
|
|
|
|
return 'mcs';
|
|
|
|
|
|
|
|
$unity_dir = get_unity_dir();
|
|
|
|
|
|
|
|
if(!is_dir($unity_dir))
|
|
|
|
throw new Exception("Unity directory doesn't exist: $unity_dir");
|
|
|
|
|
|
|
|
$canidates = array(
|
|
|
|
"$unity_dir/Mono/bin/gmcs",
|
|
|
|
"$unity_dir/MonoBleedingEdge/bin/mcs",
|
|
|
|
"$unity_dir/Frameworks/Mono/bin/gmcs",
|
|
|
|
"$unity_dir/Mono/bin/gmcs",
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach($canidates as $mcs_bin)
|
|
|
|
{
|
|
|
|
if(is_file($mcs_bin))
|
|
|
|
{
|
|
|
|
if(is_win())
|
|
|
|
return '"' . normalize_path($mcs_bin, false) . '"';
|
|
|
|
else
|
|
|
|
return $mcs_bin;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Exception("Mono compiler binary not found");
|
|
|
|
}
|
|
|
|
|
|
|
|
function mono_try_override_path()
|
|
|
|
{
|
|
|
|
if(!get("USE_UNITY_MONO"))
|
|
|
|
return '';
|
|
|
|
|
|
|
|
$mono_dir = dirname(trim(mono_mcs_bin(), '"'));
|
|
|
|
$prev_path = getenv('PATH');
|
|
|
|
echo "UNITY MONO PATH=$mono_dir\n";
|
|
|
|
putenv("PATH=$mono_dir".(is_win() ? ";" : ":")."$prev_path");
|
|
|
|
return $prev_path;
|
|
|
|
}
|
|
|
|
|
|
|
|
function mono_try_restore_path($prev_path)
|
|
|
|
{
|
|
|
|
if(!get("USE_UNITY_MONO"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
putenv("PATH=$prev_path");
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_mono_dll($src_spec, $out_file, $ref_dlls = array(), $mcs_opts = "")
|
|
|
|
{
|
|
|
|
build_mono($src_spec, $out_file, $ref_dlls, "$mcs_opts -target:library");
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_mono($src_spec, $out_file, $ref_dlls = array(), $mcs_opts = "")
|
|
|
|
{
|
|
|
|
global $GAME_ROOT;
|
|
|
|
|
|
|
|
$unity_dir = get_unity_dir();
|
|
|
|
$mcs_bin = mono_mcs_bin();
|
|
|
|
|
|
|
|
if(is_array($src_spec))
|
|
|
|
$sources = $src_spec;
|
|
|
|
else if(is_dir($src_spec))
|
|
|
|
$sources = scan_files_rec(array($src_spec), array('.cs'));
|
|
|
|
else
|
|
|
|
$sources = glob($src_spec);
|
|
|
|
|
|
|
|
$sources_str = '';
|
|
|
|
foreach($sources as $src)
|
|
|
|
{
|
|
|
|
if(is_win())
|
2023-08-16 14:06:31 +03:00
|
|
|
$sources_str .= '"'.normalize_path($src).'" ';
|
2022-05-19 18:50:30 +03:00
|
|
|
else
|
2023-08-16 14:06:31 +03:00
|
|
|
$sources_str .= '\''.normalize_path($src).'\' ';
|
2022-05-19 18:50:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
$deps = $sources;
|
|
|
|
|
|
|
|
$refs_str = "";
|
|
|
|
foreach($ref_dlls as $ref_dll)
|
|
|
|
{
|
|
|
|
if($ref_dll === "UnityEngine.dll")
|
|
|
|
{
|
|
|
|
$ref_dll = "$unity_dir/Managed/UnityEngine.dll";
|
|
|
|
if(!is_file($ref_dll))
|
|
|
|
$ref_dll = "$unity_dir/Frameworks/Managed/UnityEngine.dll";
|
|
|
|
}
|
|
|
|
|
|
|
|
$ref_dll = normalize_path($ref_dll, !is_win());
|
|
|
|
$refs_str .= "-r:\"$ref_dll\" ";
|
|
|
|
$deps[] = $ref_dll;
|
|
|
|
}
|
|
|
|
|
|
|
|
$out_file = normalize_path($out_file, !is_win());
|
|
|
|
$cmd = "$mcs_bin $mcs_opts $refs_str -out:$out_file $sources_str";
|
|
|
|
if(is_string($src_spec) && is_dir($src_spec))
|
|
|
|
$cmd = "cd $src_spec && $cmd";
|
|
|
|
|
|
|
|
$cmd_hash = crc32($cmd);
|
|
|
|
$cmd_hash_file = "$GAME_ROOT/build/" . crc32($out_file) . ".mhash";
|
|
|
|
if(!is_file($cmd_hash_file) || file_get_contents($cmd_hash_file) != "$cmd_hash")
|
|
|
|
file_put_contents($cmd_hash_file, "$cmd_hash");
|
|
|
|
$deps[] = $cmd_hash_file;
|
|
|
|
|
|
|
|
if(need_to_regen($out_file, $deps))
|
|
|
|
{
|
|
|
|
ensure_mkdir(dirname($out_file));
|
|
|
|
shell($cmd);
|
|
|
|
echo "> $out_file " . round(filesize($out_file)/1024, 2) . "kb\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function run_mono($exe_file)
|
|
|
|
{
|
|
|
|
$app_dir = get('UNITY_APP_DIR');
|
|
|
|
|
|
|
|
if(is_win())
|
|
|
|
{
|
|
|
|
$unity_dir = "$app_dir/Editor/Data";
|
2023-08-16 14:06:31 +03:00
|
|
|
$mono_bin = '"' . normalize_path("$unity_dir/Mono/bin/mono") . '"';
|
2022-05-19 18:50:30 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
$unity_dir = "$app_dir/Unity.app/Contents/";
|
|
|
|
|
|
|
|
if(is_dir("$unity_dir/Frameworks/Mono"))
|
|
|
|
$mono_bin = "$unity_dir/Frameworks/Mono/bin/mono";
|
|
|
|
else
|
|
|
|
$mono_bin = "$unity_dir/Mono/bin/mono";
|
|
|
|
}
|
|
|
|
|
|
|
|
$exe_file = normalize_path($exe_file, !is_win());
|
|
|
|
$mono_path = realpath(dirname($mono_bin) . '/../lib/mono/unity');
|
2023-03-21 18:39:27 +03:00
|
|
|
putenv("MONO_PATH=$mono_path");
|
2022-05-19 18:50:30 +03:00
|
|
|
$cmd = "$mono_bin $exe_file";
|
|
|
|
shell($cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_option_exists($option)
|
|
|
|
{
|
|
|
|
return strpos(getor("BUILD_CLIENT_OPTS", ""), $option) !== FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
function build_option_add($option)
|
|
|
|
{
|
|
|
|
if(build_option_exists($option))
|
|
|
|
return;
|
|
|
|
|
|
|
|
$propname = "BUILD_CLIENT_OPTS";
|
|
|
|
|
|
|
|
$opts = getor($propname, "");
|
|
|
|
if(strlen($opts) > 0)
|
|
|
|
$opts .= ",$option";
|
|
|
|
else
|
|
|
|
$opts = $option;
|
|
|
|
|
|
|
|
set($propname, $opts);
|
|
|
|
}
|
|
|
|
|
|
|
|
function is_gradle_project_export()
|
|
|
|
{
|
|
|
|
return build_option_exists("AcceptExternalModificationsToPlayer");
|
|
|
|
}
|
|
|
|
|