Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(MONGOSH-1808): only build universal macos binaries when creating loadable_library #186

Merged
merged 2 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/docker/Dockerfile.glibc
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ COPY . .

RUN apt-get -qq update && apt-get -qq install -y python3 build-essential libkrb5-dev && ldd --version

RUN npm clean-install --ignore-scripts
RUN npm run prebuild
RUN node .github/scripts/build.mjs

FROM scratch

COPY --from=build /kerberos/prebuilds/ /
COPY --from=build /kerberos/prebuilds/ /
97 changes: 97 additions & 0 deletions .github/scripts/build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// @ts-check

import util from 'node:util';
import process from 'node:process';
import fs from 'node:fs/promises';
import child_process from 'node:child_process';
import events from 'node:events';
import path from 'node:path';
import url from 'node:url';

const __dirname = path.dirname(url.fileURLToPath(import.meta.url));

/** Resolves to the root of this repository */
function resolveRoot(...paths) {
return path.resolve(__dirname, '..', '..', ...paths);
}

async function parseArguments() {
const pkg = JSON.parse(await fs.readFile(resolveRoot('package.json'), 'utf8'));

const options = {
'kerberos_use_rtld': { type: 'boolean', default: false },
help: { short: 'h', type: 'boolean', default: false }
};

const args = util.parseArgs({ args: process.argv.slice(2), options, allowPositionals: false });

if (args.values.help) {
console.log(
`${path.basename(process.argv[1])} ${[...Object.keys(options)]
.filter(k => k !== 'help')
.map(k => `[--${k}=${options[k].type}]`)
.join(' ')}`
);
process.exit(0);
}

return {
kerberos_use_rtld: !!args.values.kerberos_use_rtld,
pkg
};
}

/** `xtrace` style command runner, uses spawn so that stdio is inherited */
async function run(command, args = [], options = {}) {
const commandDetails = `+ ${command} ${args.join(' ')}${options.cwd ? ` (in: ${options.cwd})` : ''}`;
console.error(commandDetails);
const proc = child_process.spawn(command, args, {
shell: process.platform === 'win32',
stdio: 'inherit',
cwd: resolveRoot('.'),
...options
});
await events.once(proc, 'exit');

if (proc.exitCode != 0) throw new Error(`CRASH(${proc.exitCode}): ${commandDetails}`);
}

async function buildBindings(args, pkg) {
await fs.rm(resolveRoot('build'), { force: true, recursive: true });
await fs.rm(resolveRoot('prebuilds'), { force: true, recursive: true });

// install with "ignore-scripts" so that we don't attempt to download a prebuild
await run('npm', ['install', '--ignore-scripts']);
// The prebuild command will make both a .node file in `./build` (local and CI testing will run on current code)
// it will also produce `./prebuilds/kerberos-vVERSION-napi-vNAPI_VERSION-OS-ARCH.tar.gz`.

let gypDefines = process.env.GYP_DEFINES ?? '';
if (args.kerberos_use_rtld) {
gypDefines += ' kerberos_use_rtld=true';
}

gypDefines = gypDefines.trim();
const prebuildOptions =
gypDefines.length > 0
? { env: { ...process.env, GYP_DEFINES: gypDefines } }
: undefined;

await run('npm', ['run', 'prebuild'], prebuildOptions);

await run('npm', ['run', 'prepare']);

if (process.platform === 'darwin' && process.arch === 'arm64') {
// The "arm64" build is actually a universal binary
const armTar = `kerberos-v${pkg.version}-napi-v4-darwin-arm64.tar.gz`;
const x64Tar = `kerberos-v${pkg.version}-napi-v4-darwin-x64.tar.gz`;
await fs.copyFile(resolveRoot('prebuilds', armTar), resolveRoot('prebuilds', x64Tar));
}
}

async function main() {
const { pkg, ...args } = await parseArguments();
console.log(args);
await buildBindings(args, pkg);
}

await main();
6 changes: 2 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ jobs:
- uses: actions/checkout@v4

- name: Build ${{ matrix.os }} Prebuild
run: |
npm clean-install --ignore-scripts
npm run prebuild
run: node .github/scripts/build.mjs

- id: upload
name: Upload prebuild
Expand Down Expand Up @@ -64,4 +62,4 @@ jobs:
path: prebuilds/
if-no-files-found: 'error'
retention-days: 1
compression-level: 0
compression-level: 0
31 changes: 17 additions & 14 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,21 @@
{
'target_name': 'kerberos',
'type': 'loadable_module',
'include_dirs': [ "<!(node -p \"require('node-addon-api').include_dir\")" ],
'include_dirs': [
"<!(node -p \"require('node-addon-api').include_dir\")"
],
'sources': [
'src/kerberos.cc'
],
'variables': {
'ARCH': '<(host_arch)',
'kerberos_use_rtld%': 'false'
},
'xcode_settings': {
'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'CLANG_CXX_LIBRARY': 'libc++',
'MACOSX_DEPLOYMENT_TARGET': '10.12',
"OTHER_CFLAGS": [
"-arch x86_64",
"-arch arm64"
],
"OTHER_LDFLAGS": [
"-arch x86_64",
"-arch arm64"
]
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
},
'cflags!': [ '-fno-exceptions' ],
'cflags_cc!': [ '-fno-exceptions' ],
Expand All @@ -36,11 +32,18 @@
},
},
'conditions': [
['OS=="mac"', {
'cflags+': ['-fvisibility=hidden'],
'xcode_settings': {
'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
}
['OS=="mac"', { 'cflags+': ['-fvisibility=hidden'] }],
['_type!="static_library" and ARCH=="arm64"', {
'xcode_settings': {
"OTHER_CFLAGS": [
"-arch x86_64",
"-arch arm64"
],
"OTHER_LDFLAGS": [
"-arch x86_64",
"-arch arm64"
]
}
}],
['OS=="mac" or OS=="linux"', {
'sources': [
Expand Down
Loading