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

Improve #include handling for JS library files #23449

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
29 changes: 25 additions & 4 deletions src/parseTools.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/

import * as path from 'node:path';
import {existsSync} from 'node:fs';

import {
addToCompileTimeContext,
Expand All @@ -19,6 +20,7 @@ import {
runInMacroContext,
setCurrentFile,
warn,
srcDir,
} from './utility.mjs';

const FOUR_GB = 4 * 1024 * 1024 * 1024;
Expand All @@ -40,6 +42,24 @@ export function processMacros(text, filename) {
});
}

function findIncludeFile(filename, currentDir) {
if (path.isAbsolute(filename)) {
return existsSync(filename) ? filename : null;
}

// Search for include files either relative to the including file,
// or in the src root directory.
const includePath = [currentDir, srcDir];
for (const p of includePath) {
const f = path.join(p, filename);
if (existsSync(f)) {
return f;
}
}

return null;
}

// Simple #if/else/endif preprocessing for a file. Checks if the
// ident checked is true in our global.
// Also handles #include x.js (similar to C #include <file>)
Expand Down Expand Up @@ -125,11 +145,12 @@ export function preprocess(filename) {
if (includeFile.startsWith('"')) {
includeFile = includeFile.substr(1, includeFile.length - 2);
}
// Include files are always relative to the current file being processed
if (!path.isAbsolute(includeFile)) {
includeFile = path.join(path.dirname(filename), includeFile);
const absPath = findIncludeFile(includeFile, path.dirname(filename));
if (!absPath) {
error(`${filename}:${i + 1}: file not found: ${includeFile}`);
continue;
}
const result = preprocess(includeFile);
const result = preprocess(absPath);
if (result) {
ret += `// include: ${includeFile}\n`;
ret += result;
Expand Down
4 changes: 3 additions & 1 deletion src/utility.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -233,11 +233,13 @@ export function read(filename) {
// Use import.meta.dirname here once we drop support for node v18.
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

export const srcDir = __dirname;

// Returns an absolute path for a file, resolving it relative to this script
// (i.e. relative to the src/ directory).
export function localFile(filename) {
assert(!path.isAbsolute(filename));
return path.join(__dirname, filename);
return path.join(srcDir, filename);
}

// Anything needed by the script that we load below must be added to the
Expand Down
16 changes: 16 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -4922,6 +4922,22 @@ def test_jslib_errors(self):
self.assertContained('error_in_js_libraries.js:5: #error This is an error string!', err)
self.assertContained('error_in_js_libraries.js:7: #error This is a second error string!', err)

def test_jslib_include(self):
create_file('inc.js', '''
let MY_VAR = 10;
''')
create_file('foo.js', '''
// Include a file from system directory
#include "arrayUtils.js"
// Include a local file.
#include "inc.js"
''')
self.run_process([EMCC, test_file('hello_world.c'), '--js-library', 'foo.js'])

delete_file('inc.js')
err = self.expect_fail([EMCC, test_file('hello_world.c'), '--js-library', 'foo.js'])
self.assertContained('foo.js:5: file not found: inc.js', err)

def test_postjs_errors(self):
create_file('post.js', '#preprocess\n#error This is an error')
err = self.expect_fail([EMCC, test_file('hello_world.c'), '--post-js', 'post.js'])
Expand Down
Loading