152 lines
6.8 KiB
JavaScript
152 lines
6.8 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.CompilerCommandsExporter = void 0;
|
|
const fs = require("kmake/fsextra");
|
|
const path = require("path");
|
|
const Platform_1 = require("kmake/Platform");
|
|
const log = require("kmake/log");
|
|
const os = require("os");
|
|
const child_process = require("child_process");
|
|
const Exporter_1 = require("kmake/Exporters/Exporter");
|
|
class CompilerCommandsExporter extends Exporter_1.Exporter {
|
|
constructor(options) {
|
|
super(options);
|
|
}
|
|
async exportSolution(project, _from, to, platform, vrApi, options) {
|
|
var _a;
|
|
let from = path.resolve(process.cwd(), _from);
|
|
this.writeFile(path.resolve(to, 'compile_commands.json'));
|
|
let includes = [];
|
|
for (let inc of project.getIncludeDirs()) {
|
|
includes.push('-I');
|
|
includes.push(path.resolve(from, inc));
|
|
}
|
|
let defines = [];
|
|
for (let def of project.getDefines()) {
|
|
defines.push('-D');
|
|
defines.push(def.value.replace(/\"/g, '\\"'));
|
|
}
|
|
let objects = {};
|
|
let ofiles = {};
|
|
for (let fileobject of project.getFiles()) {
|
|
let file = fileobject.file;
|
|
if (file.endsWith('.cpp') || file.endsWith('.c') || file.endsWith('.cc') || file.endsWith('.s') || file.endsWith('.S')) {
|
|
if (fileobject.options && fileobject.options.nocompile) {
|
|
continue;
|
|
}
|
|
let name = file.toLowerCase();
|
|
if (name.indexOf('/') >= 0)
|
|
name = name.substr(name.lastIndexOf('/') + 1);
|
|
name = name.substr(0, name.lastIndexOf('.'));
|
|
if (!objects[name]) {
|
|
objects[name] = true;
|
|
ofiles[file] = name;
|
|
}
|
|
else {
|
|
while (objects[name]) {
|
|
name = name + '_';
|
|
}
|
|
objects[name] = true;
|
|
ofiles[file] = name;
|
|
}
|
|
}
|
|
}
|
|
let defaultArgs = [];
|
|
// TODO: same for MacOS, Windows, etc...
|
|
if (platform === Platform_1.Platform.Android) {
|
|
defaultArgs.push('--target=aarch64-none-linux-android21');
|
|
defaultArgs.push('-DANDROID');
|
|
// take a guess at where the ndk could be
|
|
function ndkFromSdkRoot() {
|
|
var _a;
|
|
let sdkEnv = (_a = process.env['ANDROID_HOME']) !== null && _a !== void 0 ? _a : process.env['ANDROID_SDK_ROOT'];
|
|
if (!sdkEnv)
|
|
return null;
|
|
let ndk_dir = path.join(sdkEnv, 'ndk');
|
|
if (!fs.existsSync(ndk_dir)) {
|
|
return null;
|
|
}
|
|
let ndks = fs.readdirSync(ndk_dir);
|
|
ndks = ndks.filter(item => !item.startsWith("."));
|
|
if (ndks.length < 1) {
|
|
return null;
|
|
}
|
|
return path.join(ndk_dir, ndks[0]);
|
|
}
|
|
let android_ndk = (_a = process.env['ANDROID_NDK']) !== null && _a !== void 0 ? _a : ndkFromSdkRoot();
|
|
if (android_ndk) {
|
|
let host_tag = '';
|
|
switch (os.platform()) {
|
|
// known host tags
|
|
// TODO: figure out the host tag for aarch64 darwin/linux/windows
|
|
case 'linux':
|
|
host_tag = 'linux-x86_64';
|
|
break;
|
|
case 'darwin':
|
|
host_tag = 'darwin-x86_64';
|
|
break;
|
|
case 'win32':
|
|
host_tag = 'windows-x86_64';
|
|
break;
|
|
}
|
|
let ndk_toolchain = path.join(android_ndk, `toolchains/llvm/prebuilt/${host_tag}`);
|
|
if (host_tag !== '' && fs.existsSync(ndk_toolchain)) {
|
|
defaultArgs.push(`--gcc-toolchain=${ndk_toolchain}`);
|
|
defaultArgs.push(`--sysroot=${ndk_toolchain}/sysroot`);
|
|
}
|
|
else {
|
|
// fallback to the first found toolchain
|
|
let toolchains = fs.readdirSync(path.join(android_ndk, `toolchains/llvm/prebuilt/`));
|
|
if (toolchains.length > 0) {
|
|
let host_tag = toolchains[0];
|
|
let ndk_toolchain = path.join(android_ndk, `toolchains/llvm/prebuilt/${host_tag}`);
|
|
defaultArgs.push(`--gcc-toolchain=${ndk_toolchain}`);
|
|
defaultArgs.push(`--sysroot=${ndk_toolchain}/sysroot`);
|
|
log.info(`Found android ndk toolchain in ${ndk_toolchain}.`);
|
|
}
|
|
else {
|
|
log.error('Platform is set to Android, but android toolchain not found.');
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
log.error('Platform is set to Android, but android toolchain not found.\nPlease set the ANDROID_NDK environment variable if you need a compile_commands.json for your IDE.');
|
|
}
|
|
}
|
|
else if (platform === Platform_1.Platform.Emscripten) {
|
|
const emcc_bin = (process.platform === 'win32') ? 'emcc.bat' : 'emcc';
|
|
let emcc = child_process.spawnSync(emcc_bin, ['--cflags']);
|
|
// log.info(emcc.status);
|
|
if (emcc.status === 0) {
|
|
let flags = emcc.output.toString().split(' ');
|
|
defaultArgs.push(...flags);
|
|
}
|
|
else {
|
|
log.error('Platform is set to Emscripten, but emcc could not be found. Please add it to your PATH environment variable if you need a compile_commands.json for your IDE.');
|
|
}
|
|
}
|
|
let commands = [];
|
|
for (let fileobject of project.getFiles()) {
|
|
let file = fileobject.file;
|
|
if (file.endsWith('.c') || file.endsWith('.cpp') || file.endsWith('.cc')) {
|
|
let args = ['/usr/bin/clang', '-c', '-o', (options.debug ? 'debug' : 'release') + ofiles[file] + '.o'];
|
|
if (file.endsWith('.c')) {
|
|
args.push('-std=c99');
|
|
}
|
|
args.push(...defaultArgs);
|
|
args.push(path.resolve(from, file));
|
|
let command = {
|
|
directory: from,
|
|
file: path.resolve(from, file),
|
|
output: path.resolve(to, ofiles[file] + '.o'),
|
|
arguments: args.concat(includes).concat(defines)
|
|
};
|
|
commands.push(command);
|
|
}
|
|
}
|
|
this.p(JSON.stringify(commands));
|
|
this.closeFile();
|
|
}
|
|
}
|
|
exports.CompilerCommandsExporter = CompilerCommandsExporter;
|
|
//# sourceMappingURL=CompileCommandsExporter.js.map
|