2023-03-18 17:32:21 +08:00
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
|
|
namespace SPC\builder\traits;
|
|
|
|
|
|
|
2023-03-29 21:39:36 +08:00
|
|
|
|
use SPC\store\FileSystem;
|
|
|
|
|
|
|
2023-03-18 17:32:21 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Unix 系统的工具函数 Trait,适用于 Linux、macOS
|
|
|
|
|
|
*/
|
|
|
|
|
|
trait UnixSystemUtilTrait
|
|
|
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 生成 toolchain.cmake,用于 cmake 构建
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param string $os 操作系统代号
|
|
|
|
|
|
* @param string $target_arch 目标架构
|
|
|
|
|
|
* @param string $cflags CFLAGS 参数
|
|
|
|
|
|
* @param null|string $cc CC 参数(默认空)
|
|
|
|
|
|
* @param null|string $cxx CXX 参数(默认空)
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function makeCmakeToolchainFile(
|
|
|
|
|
|
string $os,
|
|
|
|
|
|
string $target_arch,
|
|
|
|
|
|
string $cflags,
|
|
|
|
|
|
?string $cc = null,
|
|
|
|
|
|
?string $cxx = null
|
|
|
|
|
|
): string {
|
|
|
|
|
|
logger()->debug("making cmake tool chain file for {$os} {$target_arch} with CFLAGS='{$cflags}'");
|
|
|
|
|
|
$root = BUILD_ROOT_PATH;
|
|
|
|
|
|
$ccLine = '';
|
|
|
|
|
|
if ($cc) {
|
|
|
|
|
|
$ccLine = 'SET(CMAKE_C_COMPILER ' . self::findCommand($cc) . ')';
|
|
|
|
|
|
}
|
|
|
|
|
|
$cxxLine = '';
|
|
|
|
|
|
if ($cxx) {
|
|
|
|
|
|
$cxxLine = 'SET(CMAKE_CXX_COMPILER ' . self::findCommand($cxx) . ')';
|
|
|
|
|
|
}
|
|
|
|
|
|
$toolchain = <<<CMAKE
|
|
|
|
|
|
SET(CMAKE_SYSTEM_NAME {$os})
|
|
|
|
|
|
SET(CMAKE_SYSTEM_PROCESSOR {$target_arch})
|
|
|
|
|
|
{$ccLine}
|
|
|
|
|
|
{$cxxLine}
|
|
|
|
|
|
SET(CMAKE_C_FLAGS "{$cflags}")
|
|
|
|
|
|
SET(CMAKE_CXX_FLAGS "{$cflags}")
|
|
|
|
|
|
SET(CMAKE_FIND_ROOT_PATH "{$root}")
|
2023-04-29 18:59:47 +08:00
|
|
|
|
SET(CMAKE_PREFIX_PATH "{$root}")
|
|
|
|
|
|
|
|
|
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
|
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
|
|
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
|
|
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
2023-03-18 17:32:21 +08:00
|
|
|
|
CMAKE;
|
2023-03-21 00:25:46 +08:00
|
|
|
|
// 有时候系统的 cmake 找不到 ar 命令,真奇怪
|
|
|
|
|
|
if (PHP_OS_FAMILY === 'Linux') {
|
|
|
|
|
|
$toolchain .= "\nSET(CMAKE_AR \"ar\")";
|
|
|
|
|
|
}
|
2023-03-29 21:39:36 +08:00
|
|
|
|
FileSystem::writeFile(SOURCE_PATH . '/toolchain.cmake', $toolchain);
|
2023-03-18 17:32:21 +08:00
|
|
|
|
return realpath(SOURCE_PATH . '/toolchain.cmake');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @param string $name 命令名称
|
|
|
|
|
|
* @param array $paths 寻找的目标路径(如果不传入,则使用环境变量 PATH)
|
|
|
|
|
|
* @return null|string 找到了返回命令路径,找不到返回 null
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static function findCommand(string $name, array $paths = []): ?string
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!$paths) {
|
|
|
|
|
|
$paths = explode(PATH_SEPARATOR, getenv('PATH'));
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach ($paths as $path) {
|
|
|
|
|
|
if (file_exists($path . DIRECTORY_SEPARATOR . $name)) {
|
|
|
|
|
|
return $path . DIRECTORY_SEPARATOR . $name;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|