aboutsummaryrefslogtreecommitdiffstats
path: root/qt-cpp/src/util/get-qt-paths.ts
blob: 2fc4f080b98c610b5010b51e2a56c4a650d8b64b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only

import * as path from 'path';
import * as fs from 'fs/promises';

import * as fsutil from '@util/fs';
import { OSExeSuffix, IsMacOS } from 'qt-lib';

const QtToolchainCMakeFileName = 'qt.toolchain.cmake';
const NinjaFileName = 'ninja' + OSExeSuffix;

async function pathOfDirectoryIfExists(
  dirPath: string
): Promise<string | undefined> {
  try {
    await fs.access(dirPath);
    return path.normalize(dirPath);
  } catch (error) {
    return undefined;
  }
}

function qtToolsDirByQtRootDir(qtRootDir: string): string {
  return path.normalize(path.join(qtRootDir, 'Tools'));
}

export function mangleQtInstallation(
  qtInsRoot: string,
  installation: string
): string {
  const relativeInstallationPath = path.relative(qtInsRoot, installation);
  const pathParts = relativeInstallationPath.split(path.sep).filter(String);
  pathParts.unshift(path.basename(qtInsRoot));
  return pathParts.slice().join('-');
}

export function mangleMsvcKitName(installation: string): string {
  const pathParts = installation.split(/[/\\:]+/).filter((n) => n);
  const qtIdx = Math.max(
    0,
    pathParts.findIndex((s) => s.toLowerCase() == 'qt')
  );
  return pathParts.slice(qtIdx).join('_');
}

export async function locateNinjaExecutable(qtRootDir: string) {
  const pathsToCheck = [
    path.join(qtToolsDirByQtRootDir(qtRootDir), 'Ninja', NinjaFileName)
  ];
  const vs2022dir = process.env.VS2022INSTALLDIR;
  if (vs2022dir) {
    pathsToCheck.push(
      path.join(
        vs2022dir,
        'Common7',
        'IDE',
        'CommonExtensions',
        'Microsoft',
        'CMake',
        'Ninja',
        NinjaFileName
      ),
      path.join(vs2022dir, 'MSBuild', 'Google', 'Android', 'bin', NinjaFileName)
    );
  }
  for (const checkPath of pathsToCheck) {
    if (await fsutil.exists(checkPath)) {
      return checkPath;
    }
  }

  return '';
}

export async function locateMingwBinDirPath(qtRootDir: string) {
  // TODO: check if g++ exists in PATH already
  const qtToolsDir = qtToolsDirByQtRootDir(qtRootDir);
  const items = await fs.readdir(qtToolsDir, { withFileTypes: true });
  const mingws = items.filter((item) =>
    item.name.toLowerCase().startsWith('mingw')
  );
  const promiseMingwsWithBinDirs = mingws.map(async (item) =>
    pathOfDirectoryIfExists(path.join(qtToolsDir, item.name, 'bin'))
  );
  const mingwsWithBins = (await Promise.all(promiseMingwsWithBinDirs)).filter(
    Boolean
  ) as string[];
  const mingwVersions = new Map<number, string>(
    mingwsWithBins.map((item) => {
      const m = item.match(/mingw(\d+)_\d+/);
      let v = 0;
      if (m?.[1] !== undefined) {
        v = parseInt(m[1], 10);
      }
      return [v, item];
    })
  );

  const highestMingWVersion = Math.max(...mingwVersions.keys());
  return mingwVersions.get(highestMingWVersion);
}

export async function locateCMakeQtToolchainFile(installation: string) {
  const libCMakePath = path.join(installation, 'lib', 'cmake');
  const qtVersion = 'Qt6';

  const cmakeQtToolchainFilePath = path.join(
    libCMakePath,
    qtVersion,
    QtToolchainCMakeFileName
  );
  if (await fsutil.exists(cmakeQtToolchainFilePath)) {
    return cmakeQtToolchainFilePath;
  }

  return '';
}

export async function locateCMakeExecutable(rootIns: string) {
  const cmakeExePath = path.join(
    rootIns,
    `Tools`,
    'CMake',
    IsMacOS ? path.join('CMake.app', 'Contents') : '',
    'bin',
    `cmake${OSExeSuffix}`
  );
  if (await fsutil.exists(cmakeExePath)) {
    return cmakeExePath;
  }
  return undefined;
}