Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/toyobayashi/cgen
https://github.com/toyobayashi/cgen
Last synced: 28 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/toyobayashi/cgen
- Owner: toyobayashi
- Created: 2020-12-30T11:00:28.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2022-12-10T13:19:21.000Z (almost 2 years ago)
- Last Synced: 2024-09-21T13:25:29.461Z (about 2 months ago)
- Language: JavaScript
- Size: 141 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# cgen
Node.js CLI tool based on CMake for generating C/C++ project.
## Requirements
* Node.js >= 12.10
* CMake >= 3.9
* Non-Windows: gcc / clang, gdb / lldb, make
* Windows: Visual Studio 2017+ & [Desktop development with C++] workload
* Building webassembly
* emsdk
* Emscripten 2.x* `$EMSDK` system environment variable set to emsdk root path
* `$EMSDK/upstream/emscripten` in `$PATH`
* make / nmake## Usage
Quick start:
```bash
npm install -g @tybys/cgen
cgen init demo
cd ./demo
cgen rebuild
```Install in local project:
```bash
npm install -D @tybys/cgen
# Additionally if use TypeScript
# npm install -D @types/node
```Configuration example:
```js
// cgen.config.js// for TypeScript intellisense
// const { defineFunctionConfig, defineObjectConfig } = require('@tybys/cgen')
// module.exports = defineObjectConfig({ ... })
// module.exports = defineFunctionConfig(function (options, ctx) { ... })module.exports = function (options, { isDebug }) {
return {
project: 'example',
targets: [
{
name: 'mylib',
type: !!(options.DLL) ? 'dll' : 'lib',
sources: [
'./src/mysource.c'
],
defines: [
...(!!(options.DLL) ? ['MYLIB_BUILD_DLL'] : [])
],
publicIncludePaths: ['./include'],
staticVCRuntime: !!(options.MT)
},
{
name: 'myexe',
type: 'exe',
sources: [
'./src/main.c'
],
libs: ['mylib'],
staticVCRuntime: !!(options.MT)
}
]
}
}
```Build command example: `cgen rebuild -sDLL -sMT --debug`
WebAssembly example:
```js
// cgen.config.js
module.exports = function (_options, { isDebug }) {
const debugFlags = [
'-sDISABLE_EXCEPTION_CATCHING=0',
'-sSAFE_HEAP=1'
]const commonFlags = [
'--bind',
// '-sDYNCALLS=1', v2.0.13+ if you need dynCall_xxx()
// '-sERROR_ON_UNDEFINED_SYMBOLS=0', if add js function to imports.env
'-sALLOW_MEMORY_GROWTH=1',
...(isDebug ? debugFlags : [])
]return {
project: 'example',
targets: [
{
name: 'mywasm',
type: 'exe',
sources: [
'./src/*.cpp'
],
emwrap: { // compatible webpack
script: './export.js'
}
compileOptions: [...commonFlags],
linkOptions: [...commonFlags]
}
]
}
}
``````js
/**
* export.js
*/exports.myfunction = function () {
return Module.myfunction.apply(Module, arguments)
}
```Build command: `cgen rebuild --emscripten` or `cgen rebuild -e`
Use webassembly:
```html
(function () {
window.mywasm.default().then(function (emctx) {
// emscriptenModule === emctx.Module
emctx.Module.myfunction();
});// or use custom instatiating to add js function to native world
var emscriptenModule = {
// Custom instantiating
instantiateWasm: function (imports, receiveInstance) {
fetch('mywasm.wasm', {
credentials: 'same-origin'
})
.then(function (res) {
return res.arrayBuffer();
})
.then(function (arrayBuffer) {
// imports.env.js_fn = xxx
return WebAssembly.instantiate(arrayBuffer, imports);
})
.then(({ instance, module }) => {
receiveInstance(instance, module);
});
return {};
}
};
window.mywasm.default(emscriptenModule).then(function (emctx) {
// emscriptenModule === emctx.Module
emctx.Module.myfunction();
});
})();```
or with bundler
```js
import init from './.cgenbuild/mywasm.js'
// const init = require('./.cgenbuild/mywasm.js').default
init().then((emctx) => { emctx.Module.myfunction() })
```or
```js
import init, { myfunction } from './.cgenbuild/mywasm.js'// typeof myfunction === 'undefined'
init().then((emctx) => {
// typeof myfunction === 'function'
// myfunction === emctx.Module.myfunction
emctx.myfunction()
})
```See more help: `cgen -h` or `cgen -h`
## TypeScript typings
```ts
///declare interface WrapOptions {
module?: 'umd' | 'esm' | 'cjs' | 'mjs'
/** Library name for UMD module */
name?: string
/** Wrap script */
script?: string
/** Extra runtime variables to be added on init() promise result */
exports?: string[]
}/** Build target options */
export declare interface Target {
/** Target name */
name: string;/** Build target type */
type: 'exe' | 'lib' | 'dll' | 'node' | 'interface';/** Glob patterns */
sources?: string[];/** Whether to use node-addon-api */
nodeAddonApi?: boolean;/** Defines NAPI_VERSION */
napiVersion?: string;/** set_target_properties() */
properties?: Record;/** target_link_options(${name}, PRIVATE, ...) */
linkOptions?: string[];/** target_link_options(${name}, INTERFACE, ...) */
interfaceLinkOptions?: string[];/** target_link_options(${name}, PUBLIC, ...) */
publicLinkOptions?: string[];/** target_compile_options(${name}, PRIVATE, ...) */
compileOptions?: string[];/** target_compile_options(${name}, INTERFACE, ...) */
interfaceCompileOptions?: string[];/** target_compile_options(${name}, PUBLIC, ...) */
publicCompileOptions?: string[];/** target_compile_definitions(${name}, PRIVATE, ...) */
defines?: string[];/** target_compile_definitions(${name}, INTERFACE, ...) */
interfaceDefines?: string[];/** target_compile_definitions(${name}, PUBLIC, ...) */
publicDefines?: string[];/** target_include_directories(${name}, PRIVATE, ...) */
includePaths?: string[];/** target_include_directories(${name}, INTERFACE, ...) */
interfaceIncludePaths?: string[];/** target_include_directories(${name}, PUBLIC, ...) */
publicIncludePaths?: string[];/** target_link_directories(${name}, PRIVATE, ...) */
libPaths?: string[];/** target_link_directories(${name}, INTERFACE, ...) */
interfaceLibPaths?: string[];/** target_link_directories(${name}, PUBLIC, ...) */
publicLibPaths?: string[];/** target_link_libraries(${name}, ...) */
libs?: string[];/** Use VC /MT for release while /MTd for debug */
staticVCRuntime?: boolean;/** Wrap JavaScript glue code generated by emscripten for supporting webpack */
emwrap?: WrapOptions/** Windows specific options */
windows?: Partial>;/** Linux specific options */
linux?: Partial>;/** macOS specific options */
macos?: Partial>;
}/** Build configuration */
export declare interface Configuration {
/** Project name */
project: string;
/** Project targets */
targets: Target[];
/** Minimum required cmake version */
minimumVersion?: string;
/** add_compile_definitions */
defines?: string[];
/** add_compile_options */
compileOptions?: string[];
/** include_directories */
includePaths?: string[];
/** link_directories */
libPaths?: string[];
/** add_link_options */
linkOptions?: string[];
/** The Node.js script run after build */
postScript?: string;
/** Replace `%VAR%` in configuration */
variables?: Record;
/** Target default options */
targetDefault?: Partial>;
/** Generate subdir CMakeLists.txt and add_subdirectory() */
dependencies?: Record>
}/** Building context */
export declare interface BuildingContext {
/** Parent project root directory */
parentRootDir: string | null;
/** `true` if run `cgen clean` */
isClean: boolean;
/** `true` if run `cgen --debug` */
isDebug: boolean;
}export declare type FunctionConfiguration = (options: O, ctx: BuildingContext) => Configuration;
/** Node.js related configuration */
export declare interface NodeConfig {
/** @see [node-gyp](https://www.npmjs.com/package/node-gyp#command-options) */
target?: string;
/** @see [node-gyp](https://www.npmjs.com/package/node-gyp#command-options) */
arch?: string;
/** @see [node-gyp](https://www.npmjs.com/package/node-gyp#command-options) */
devdir?: string;
/** @see [node-gyp](https://www.npmjs.com/package/node-gyp#command-options) */
nodedir?: string;
}/** @internal */
export declare interface GenerateOptions {
config?: Configuration;
configPath?: string;
globalOptions?: Record;
options?: Record;
isEmscripten?: boolean;
parentPath?: string | null;
nodeConfig?: NodeConfig;
defines?: Record;
isDebug?: boolean;
}export declare interface EmwrapOptions extends WrapOptions {
minify?: boolean
output?: string
}/** @internal */
export declare function generateCMakeLists (options?: GenerateOptions): void;
/** @internal */
export declare function getCMakeInclude (key: 'vcruntime' | 'require' | 'embuild' | 'napi'): string;
/** @internal */
export declare function findProjectRoot (start?: string): string;
/** @internal */
export declare function resolve (dirname: string, requireFunction: NodeRequire, request: string): string;
/** @internal */
export declare function loadConfig (root: string, options: Record, ctx: BuildingContext): Configuration;
/** @internal */
export declare function cleanBuild (configRoot: string, buildDirName: string, parentRootDir?: string | null): void;
/** Do nothing, just for TypeScript intellisense */
export declare function defineObjectConfig (config: Configuration): Configuration;
/** Do nothing, just for TypeScript intellisense */
export declare function defineFunctionConfig (config: FunctionConfiguration): FunctionConfiguration;
/** Wrap JavaScript glue code generated by emscripten for supporting webpack */
export declare function emwrap (filePath: string, options?: EmwrapOptions): Promise;
```