@platforma-sdk/r-builder 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@platforma-sdk/r-builder",
3
3
  "description": "Build R run environment for Platforma",
4
4
  "type": "module",
5
- "version": "1.0.0",
5
+ "version": "1.1.0",
6
6
  "files": [
7
7
  "assets/",
8
8
  "scripts/"
@@ -38,42 +38,33 @@ function useCCache(logger) {
38
38
  logger.info("Using ccache as build caching tool...")
39
39
  process.env.CC = `ccache gcc`
40
40
  process.env.CXX = `ccache g++`
41
+ process.env.CXX11 = `ccache g++`
42
+ process.env.CXX14 = `ccache g++`
43
+ process.env.CXX17 = `ccache g++`
44
+ process.env.CXX20 = `ccache g++`
41
45
  }
42
46
 
43
- async function installSystemPackages(logger) {
44
- const originalAptSources = '/etc/apt/sources.list';
45
- logger.info(`Analyzing '${originalAptSources}'`);
46
-
47
- const modifiedAptSources = path.join(os.tmpdir(), 'apt-sources-list');
48
- let srcExists = false;
49
-
50
- const lines = fs.readFileSync(originalAptSources).toString().split('\n');
51
- for (let i = 0; i < lines.length; i++) {
52
- const line = lines[i].trim();
53
- if (/^\s*#\s*(deb-src)\s+.*\s+(universe)\s*$/.test(line)) {
54
- srcExists = true;
55
- lines[i] = line.replace(/^\s*#\s*/, '');
56
- }
57
- if (/^\s*deb-src\s+/.test(line)) {
58
- srcExists = true;
47
+ async function installRockyLinuxPackages(logger) {
48
+ logger.info('Installing packages for Rocky Linux');
49
+ util.runInherit(`sudo dnf -y install dnf-plugins-core`);
50
+ util.runInherit(`sudo dnf -y install epel-release`);
51
+
52
+ // Try to enable powertools or add fallback for different Rocky Linux versions
53
+ try {
54
+ util.runInherit(`sudo dnf config-manager --set-enabled powertools`);
55
+ } catch (error) {
56
+ logger.warn('Failed to enable powertools, trying alternative names');
57
+ try {
58
+ // In Rocky Linux 9, it's called "crb" instead of "powertools"
59
+ util.runInherit(`sudo dnf config-manager --set-enabled crb`);
60
+ } catch (innerError) {
61
+ logger.warn('Could not enable powertools or crb repositories. Some packages might not be available.');
59
62
  }
60
63
  }
61
64
 
62
- if (srcExists) {
63
- logger.info(`Patching '${originalAptSources}'`);
64
- fs.writeFileSync(modifiedAptSources, lines.join('\n'));
65
- util.runInherit(`sudo mv '${modifiedAptSources}' '${originalAptSources}'`);
66
- } else {
67
- logger.warn(
68
- `WARNING! No 'deb-src' records found in '${originalAptSources}'. 'apt-get build-dep' would probably fail.`
69
- );
70
- }
71
-
72
- logger.info('Installing packages');
73
- util.runInherit(`sudo apt-get update`);
74
- util.runInherit(`sudo apt-get install --yes rsync build-essential unzip curl patchelf r-recommended`);
75
- util.runInherit(`sudo apt-get install --yes libssl-dev libcurl4-openssl-dev libpng-dev liblapack-dev libblas-dev libfontconfig1-dev libxml2-dev`);
76
- util.runInherit(`sudo apt-get build-dep --yes r-base`);
65
+ util.runInherit(`sudo dnf -y install R`);
66
+ util.runInherit(`sudo dnf -y builddep R`);
67
+ util.runInherit(`sudo dnf -y install patchelf openssl-devel libcurl-devel libpng-devel lapack-devel blas-devel fontconfig-devel libxml2-devel`);
77
68
  }
78
69
 
79
70
  function getGCCMajorVersion() {
@@ -130,14 +121,38 @@ function configureRBuild(logger, version, sourcesDir, installDir) {
130
121
  return buildDir;
131
122
  }
132
123
 
133
- function buildRDist(logger, buildDir, installRoot, rRoot) {
124
+ async function buildRDist(logger, buildDir, installRoot, rRoot) {
134
125
  util.runInherit(`make`, { cwd: buildDir });
135
126
  util.runInherit(`make install`, { cwd: buildDir });
136
127
 
128
+ const isArm64 = os.arch() === 'arm64';
129
+
130
+ // Determine library path based on architecture
131
+ let rLibPath = isArm64 ?
132
+ path.join(installRoot, 'lib', 'R') :
133
+ path.join(installRoot, 'lib64', 'R');
134
+
135
+ // Ensure the source path exists before attempting to rename
136
+ if (!fs.existsSync(rLibPath)) {
137
+ logger.warn(`R library not found at expected path: ${rLibPath}, trying alternative...`);
138
+
139
+ // Try the alternative paths as fallback
140
+ rLibPath = rLibPath.includes('lib64')
141
+ ? path.join(installRoot, 'lib', 'R') // Try lib if lib64 failed
142
+ : path.join(installRoot, 'lib64', 'R'); // Try lib64 if lib failed
143
+
144
+ if (!fs.existsSync(rLibPath)) {
145
+ throw new Error(`R library not found in either lib or lib64 directories`);
146
+ }
147
+ }
148
+
149
+ logger.info(`Moving R from ${rLibPath} to ${rRoot}`);
150
+ fs.renameSync(rLibPath, rRoot);
151
+
137
152
  // Move core of R installation into desired R root, leaving behind all supporting
138
153
  // (and unnecessary) files.
139
154
  if (fs.existsSync(rRoot)) {
140
- fs.rmSync(rRoot, { recursive: true })
155
+ fs.rmSync(rRoot, { recursive: true });
141
156
  }
142
157
  fs.renameSync(path.join(installRoot, 'lib', 'R'), rRoot);
143
158
 
@@ -277,7 +292,7 @@ export async function buildR(logger, version) {
277
292
  fs.mkdirSync(path.dirname(distDir), { recursive: true });
278
293
  fs.mkdirSync(util.downloadsDir, { recursive: true });
279
294
 
280
- await installSystemPackages(logger);
295
+ await installRockyLinuxPackages(logger);
281
296
 
282
297
  const rSourcesDir = await getRSources(logger, version);
283
298
  const installDir = path.join(util.rDistDir, 'tmp-install');
@@ -1,7 +1,7 @@
1
1
  import child_process from 'node:child_process';
2
2
  import fs from 'node:fs';
3
3
  import path from 'node:path';
4
- import { pipeline } from 'node:stream';
4
+ import { pipeline } from 'node:stream/promises';
5
5
  import { promisify } from 'node:util';
6
6
  import { fetch } from 'undici';
7
7
 
@@ -131,16 +131,7 @@ export async function download(logger, url, destination) {
131
131
 
132
132
  await pump();
133
133
  } else {
134
-
135
- return new Promise((resolve, reject) => {
136
- pipeline(response.body, writer, (err) => {
137
- if (err) {
138
- reject(err);
139
- } else {
140
- resolve();
141
- }
142
- });
143
- });
134
+ await pipeline(response.body, writer);
144
135
  }
145
136
  }
146
137
 
@@ -152,7 +143,7 @@ export async function extractTarXz(archivePath, destination) {
152
143
  }
153
144
 
154
145
  export async function extractTarGz(archivePath, destination) {
155
- await pipelineAsync(
146
+ await pipeline(
156
147
  fs.createReadStream(archivePath),
157
148
  zlib.createUnzip(),
158
149
  tar.extract({ cwd: destination })