diff --git a/.dockerignore b/.dockerignore
index f5d6cbc4e..69375ec74 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -4,6 +4,7 @@ ci/coverage-report
!package.json
!binding.gyp
!lib
+!install
!test
!cc
!data/got.jpg
diff --git a/.travis.yml b/.travis.yml
index e20295f98..8bb676aa3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -199,7 +199,7 @@ script:
fi
after_success:
- - if [ $BUILD_TASK = 'cover' ]; then
+ - if [ "$BUILD_TASK" == "cover" ]; then
npm install;
npm run codecov -- -t $CODECOV_TOKEN;
fi
diff --git a/README.md b/README.md
index 5ae297011..13ba9a0e1 100644
--- a/README.md
+++ b/README.md
@@ -174,9 +174,40 @@ You can specify the Version of OpenCV you want to install via the script by sett
If you only want to build a subset of the OpenCV modules you can pass the *-DBUILD_LIST* cmake flag via the *OPENCV4NODEJS_AUTOBUILD_FLAGS* environment variable. For example `export OPENCV4NODEJS_AUTOBUILD_FLAGS=-DBUILD_LIST=dnn` will build only modules required for `dnn` and reduces the size and compilation time of the OpenCV package.
+## Configuring Environments via package.json
+
+It's possible to specify build environment variables by inserting them into the `package.json` as follows:
+
+```json
+{
+ "name": "my-project",
+ "version": "0.0.0",
+ "dependencies": {
+ "opencv4nodejs": "^X.X.X"
+ },
+ "opencv4nodejs": {
+ "disableAutoBuild": 1,
+ "opencvIncludeDir": "C:\\tools\\opencv\\build\\include",
+ "opencvLibDir": "C:\\tools\\opencv\\build\\x64\\vc14\\lib",
+ "opencvBinDir": "C:\\tools\\opencv\\build\\x64\\vc14\\bin"
+ }
+}
+```
+
+The following environment variables can be passed:
+
+- autoBuildBuildCuda
+- autoBuildFlags
+- autoBuildOpencvVersion
+- autoBuildWithoutContrib
+- disableAutoBuild
+- opencvIncludeDir
+- opencvLibDir
+- opencvBinDir
+
-## Usage with Docker
+# Usage with Docker
### [opencv-express](https://github.com/justadudewhohacks/opencv-express) - example for opencv4nodejs with express.js and docker
@@ -192,7 +223,7 @@ Different OpenCV 3.x base images can be found here: https://hub.docker.com/r/jus
-## Usage with Electron
+# Usage with Electron
### [opencv-electron](https://github.com/justadudewhohacks/opencv-electron) - example for opencv4nodejs with electron
@@ -213,7 +244,7 @@ const cv = require('opencv4nodejs');
-## Usage with NW.js
+# Usage with NW.js
Any native modules, including opencv4nodejs, must be recompiled to be used with [NW.js](https://nwjs.io/). Instructions on how to do this are available in the **[Use Native Modules](http://docs.nwjs.io/en/latest/For%20Users/Advanced/Use%20Native%20Node%20Modules/)** section of the the NW.js documentation.
diff --git a/appveyor.yml b/appveyor.yml
index 6d1321fad..7ad8b9a2c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -43,26 +43,33 @@ environment:
- nodejs_version: 6
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
OPENCV_VERSION: "%OPENCV4_LATEST%"
+ - nodejs_version: 12
+ APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ OPENCV_VERSION: "%OPENCV4_LATEST%"
+ BUILD_TASK: "ENVS"
install:
- cmd: choco install OpenCV -y -version %OPENCV_VERSION%
- - IF EXIST c:\tools\opencv* CD c:\tools\opencv*
- - SET OPENCV_INCLUDE_DIR=%CD%\build\include
- - SET OPENCV_LIB_DIR=%CD%\build\x64\vc14\lib
- - SET OPENCV_BIN_DIR=%CD%\build\x64\vc14\bin
- - SET PATH=%PATH%;%OPENCV_BIN_DIR%;
-
+ - if not "%BUILD_TASK%" == "ENVS" SET OPENCV_INCLUDE_DIR=c:\tools\opencv\build\include
+ - if not "%BUILD_TASK%" == "ENVS" SET OPENCV_LIB_DIR=c:\tools\opencv\build\x64\vc14\lib
+ - if not "%BUILD_TASK%" == "ENVS" SET OPENCV_BIN_DIR=c:\tools\opencv\build\x64\vc14\bin
+ - if not "%BUILD_TASK%" == "ENVS" SET PATH=%PATH%;%OPENCV_BIN_DIR%;
- ps: Install-Product node $env:nodejs_version x64
- node --version
- - npm install -g node-gyp
- - cd c:\projects\opencv4nodejs
- - npm install
build: off
test_script:
- node --version
- - cmd: cd c:\projects\opencv4nodejs\test
- - npm install
- - npm run test-appveyor
- - npm run test-externalMemTracking
\ No newline at end of file
+ - if "%BUILD_TASK%" == "ENVS" (
+ cd c:\projects\opencv4nodejs\ci\envs &&
+ npm install &&
+ npm test
+ ) else (
+ cd c:\projects\opencv4nodejs &&
+ npm install &&
+ cd c:\projects\opencv4nodejs\test &&
+ npm install &&
+ npm run test-appveyor &&
+ npm run test-externalMemTracking
+ )
\ No newline at end of file
diff --git a/binding.gyp b/binding.gyp
index de2d46b84..a19da5993 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -2,17 +2,17 @@
"targets": [{
"target_name": "opencv4nodejs",
"defines": [
- " lib.libPath)
+
+if (!libsFoundInDir.length) {
+ throw new Error('no OpenCV libraries found in lib dir: ' + libDir)
+}
+
+log.info('install', 'found the following libs:')
+libsFoundInDir.forEach(lib => log.info('install', lib.opencvModule + ' : ' + lib.libPath))
+
+const defines = libsFoundInDir
+ .map(lib => `OPENCV4NODEJS_FOUND_LIBRARY_${lib.opencvModule.toUpperCase()}`)
+
+const explicitIncludeDir = resolvePath(process.env.OPENCV_INCLUDE_DIR)
+const includes = opencvBuild.isAutoBuildDisabled()
+ ? (explicitIncludeDir ? [explicitIncludeDir] : getDefaultIncludeDirs())
+ : [resolvePath(opencvBuild.opencvInclude), resolvePath(opencvBuild.opencv4Include)]
+
+const libs = opencvBuild.isWin()
+ ? libsFoundInDir.map(lib => resolvePath(lib.libPath))
+ // dynamically link libs if not on windows
+ : ['-L' + libDir]
+ .concat(libsFoundInDir.map(lib => '-lopencv_' + lib.opencvModule))
+ .concat('-Wl,-rpath,' + libDir)
+
+console.log()
+log.info('install', 'setting the following defines:')
+defines.forEach(def => log.info('defines', def))
+console.log()
+log.info('install', 'setting the following includes:')
+includes.forEach(inc => log.info('includes', inc))
+console.log()
+log.info('install', 'setting the following libs:')
+libs.forEach(lib => log.info('libs', lib))
+
+process.env['OPENCV4NODEJS_DEFINES'] = defines.join('\n')
+process.env['OPENCV4NODEJS_INCLUDES'] = includes.join('\n')
+process.env['OPENCV4NODEJS_LIBRARIES'] = libs.join('\n')
+
+const flags = process.env.BINDINGS_DEBUG ? '--jobs max --debug' : '--jobs max'
+const nodegypCmd = 'node-gyp rebuild ' + flags
+log.info('install', `spawning node gyp process: ${nodegypCmd}`)
+const child = child_process.exec(nodegypCmd, {}, function(err, stdout, stderr) {
+ const _err = err || stderr
+ if (_err) log.error(_err)
+})
+child.stdout.pipe(process.stdout)
+child.stderr.pipe(process.stderr)
\ No newline at end of file
diff --git a/install/parseEnv.js b/install/parseEnv.js
new file mode 100644
index 000000000..8861cf686
--- /dev/null
+++ b/install/parseEnv.js
@@ -0,0 +1,7 @@
+const envName = process.argv[2]
+
+if (!envName) {
+ throw new Error('no env name passed to parseEnv')
+}
+const outputs = (process.env[envName] || '').split('\n')
+outputs.forEach(o => console.log(o))
\ No newline at end of file
diff --git a/lib/commons.js b/lib/commons.js
index 9da59b2f0..3ee60bc67 100644
--- a/lib/commons.js
+++ b/lib/commons.js
@@ -1,29 +1,13 @@
-const fs = require('fs');
-const path = require('path');
+const fs = require('fs')
+const path = require('path')
function resolvePath(filePath, file) {
if (!filePath) {
- return undefined;
+ return undefined
}
- return (file ? path.resolve(filePath, file) : path.resolve(filePath)).replace(/\\/g, '/');
-}
-
-const defaultDir = '/usr/local';
-const defaultIncludeDir = `${defaultDir}/include`;
-const defaultIncludeDirOpenCV4 = `${defaultIncludeDir}/opencv4`;
-
-function getLibDir() {
- const libPath = resolvePath(process.env.OPENCV_LIB_DIR)
- if (process.platform === 'win32' && !libPath) {
- throw new Error('OPENCV_LIB_DIR is not defined')
- }
- return libPath || `${defaultDir}/lib`;
+ return (file ? path.resolve(filePath, file) : path.resolve(filePath)).replace(/\\/g, '/')
}
module.exports = {
- resolvePath,
- defaultDir,
- defaultIncludeDir,
- defaultIncludeDirOpenCV4,
- getLibDir
-};
+ resolvePath
+}
diff --git a/lib/cv.js b/lib/cv.js
index 44e24dd96..1bfac377f 100644
--- a/lib/cv.js
+++ b/lib/cv.js
@@ -2,19 +2,60 @@ const path = require('path');
const opencvBuild = require('opencv-build');
const { resolvePath } = require('./commons');
-// ensure binaries are added to path on windows
-if (!opencvBuild.isAutoBuildDisabled() && process.platform === 'win32') {
- // append opencv binary path to node process
- if (!process.env.path.includes(opencvBuild.opencvBinDir)) {
- process.env.path = `${process.env.path};${opencvBuild.opencvBinDir};`
+const requirePath = path.join(__dirname, process.env.BINDINGS_DEBUG ? '../build/Debug/opencv4nodejs' : '../build/Release/opencv4nodejs')
+
+const logDebug = process.env.OPENCV4NODES_DEBUG_REQUIRE ? require('npmlog').info : () => {}
+
+function tryGetOpencvBinDir() {
+ if (process.env.OPENCV_BIN_DIR) {
+ logDebug('tryGetOpencvBinDir', 'OPENCV_BIN_DIR environment variable is set')
+ return process.env.OPENCV_BIN_DIR
}
+ // if the auto build is not disabled via environment do not even attempt
+ // to read package.json
+ if (!opencvBuild.isAutoBuildDisabled()) {
+ logDebug('tryGetOpencvBinDir', 'auto build has not been disabled via environment variable, using opencv bin dir of opencv-build')
+ return opencvBuild.opencvBinDir
+ }
+
+ logDebug('tryGetOpencvBinDir', 'auto build has not been explicitly disabled via environment variable, attempting to read envs from package.json...')
+ const envs = opencvBuild.readEnvsFromPackageJson()
+
+ if (!envs.disableAutoBuild) {
+ logDebug('tryGetOpencvBinDir', 'auto build has not been disabled via package.json, using opencv bin dir of opencv-build')
+ return opencvBuild.opencvBinDir
+ }
+
+ if (envs.opencvBinDir) {
+ logDebug('tryGetOpencvBinDir', 'found opencv binary environment variable in package.json')
+ return envs.opencvBinDir
+ }
+ logDebug('tryGetOpencvBinDir', 'failed to find opencv binary environment variable in package.json')
+ return null
}
-let cv;
-if (process.env.BINDINGS_DEBUG) {
- cv = require(path.join(__dirname, '../build/Debug/opencv4nodejs'));
-} else {
- cv = require(path.join(__dirname, '../build/Release/opencv4nodejs'));
+let cv = null
+try {
+ logDebug('require', 'require path is ' + requirePath)
+ cv = require(requirePath);
+} catch (err) {
+ logDebug('require', 'failed to require cv with exception: ' + err.toString())
+ logDebug('require', 'attempting to add opencv binaries to path')
+
+ if (!process.env.path) {
+ logDebug('require', 'there is no path environment variable, skipping...')
+ throw err
+ }
+
+ const opencvBinDir = tryGetOpencvBinDir()
+ logDebug('require', 'adding opencv binary dir to path: ' + opencvBinDir)
+
+ // ensure binaries are added to path on windows
+ if (!process.env.path.includes(opencvBinDir)) {
+ process.env.path = `${process.env.path};${opencvBinDir};`
+ }
+ logDebug('require', 'process.env.path: ' + process.env.path)
+ cv = require(requirePath);
}
// resolve haarcascade files
diff --git a/lib/defines.js b/lib/defines.js
deleted file mode 100644
index 01c8c0973..000000000
--- a/lib/defines.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const opencvBuild = require('opencv-build');
-const { getLibDir } = require('./commons');
-
-if (opencvBuild.isAutoBuildDisabled()) {
- opencvBuild.getLibs(getLibDir())
- .filter(lib => lib.libPath)
- .map(lib => lib.opencvModule)
- .forEach(opencvModule => console.log(`OPENCV4NODEJS_FOUND_LIBRARY_${opencvModule.toUpperCase()}`));
-
- return;
-}
-
-// set defines from auto build
-opencvBuild.opencvModules.forEach(m => console.log(`OPENCV4NODEJS_FOUND_LIBRARY_${m.toUpperCase()}`));
\ No newline at end of file
diff --git a/lib/includes.js b/lib/includes.js
deleted file mode 100644
index ffdc10b6d..000000000
--- a/lib/includes.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const opencvBuild = require('opencv-build');
-const { resolvePath, defaultIncludeDir, defaultIncludeDirOpenCV4 } = require('./commons');
-
-if (opencvBuild.isAutoBuildDisabled()) {
- const explicitIncludeDir = resolvePath(process.env.OPENCV_INCLUDE_DIR);
- if (explicitIncludeDir) {
- console.log(explicitIncludeDir);
- return;
- }
- console.log(defaultIncludeDir);
- console.log(defaultIncludeDirOpenCV4);
- return;
-}
-
-// set include dir from auto build
-console.log(resolvePath(opencvBuild.opencvInclude));
-console.log(resolvePath(opencvBuild.opencv4Include));
diff --git a/lib/libs.js b/lib/libs.js
deleted file mode 100644
index 90cdefaed..000000000
--- a/lib/libs.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const opencvBuild = require('opencv-build');
-const { resolvePath, getLibDir } = require('./commons');
-
-function linkLibs(libs) {
- libs
- .map(lib => lib.libPath)
- .filter(libPath => libPath)
- .forEach(libPath => console.log(resolvePath(libPath)));
-}
-
-if (opencvBuild.isAutoBuildDisabled()) {
- linkLibs(opencvBuild.getLibs(getLibDir()));
- return;
-}
-
-// get libs from auto build
-if (process.platform === 'win32') {
- linkLibs(opencvBuild.getLibs(resolvePath(opencvBuild.opencvLibDir)));
- return;
-}
-
-// if not windows, link libs dynamically
-console.log('-L' + resolvePath(opencvBuild.opencvLibDir));
-opencvBuild.opencvModules.forEach(lib => console.log('-lopencv_' + lib));
-console.log('-Wl,-rpath,' + resolvePath(opencvBuild.opencvLibDir));
diff --git a/package-lock.json b/package-lock.json
index db67b0595..aa2654ddc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -122,19 +122,11 @@
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"opencv-build": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/opencv-build/-/opencv-build-0.1.5.tgz",
- "integrity": "sha512-KcK3+EwgPowTMogTxC5+iZgn8EraQlof339EIV3dupbMqBWe2ZgWzQDEGlt00DgMPmcFkn0+bSm4ifuQSevGow==",
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/opencv-build/-/opencv-build-0.1.9.tgz",
+ "integrity": "sha512-tgT/bnJAcYROen9yaPynfK98IMl62mPSgMLmTx41911m5bczlq21xtE5r+UWLB/xEo/0hKk6tl5zHyxV/JS5Rg==",
"requires": {
- "@types/node": "^11.10.5",
"npmlog": "^4.1.2"
- },
- "dependencies": {
- "@types/node": {
- "version": "11.13.19",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.19.tgz",
- "integrity": "sha512-tLRDU1hmcWamtgRT2iVRdraAQVGFQGgtcqracSo9XyMN1VeZLSVGb8RJJxVqab7UGbijoUijGPVFMjmqzyZIUw=="
- }
}
},
"process-nextick-args": {
diff --git a/package.json b/package.json
index cc9f3bf90..7ded66460 100644
--- a/package.json
+++ b/package.json
@@ -29,18 +29,19 @@
"main": "./lib/opencv4nodejs.js",
"typings": "./lib/index.d.ts",
"scripts": {
- "install": "node-gyp rebuild --jobs max",
+ "install": "node ./install/install.js",
"configure": "node-gyp configure",
"build": "node-gyp configure build --jobs max",
"rebuild": "node-gyp rebuild --jobs max",
"clean": "node-gyp clean",
- "build-debug": "node-gyp rebuild --debug --jobs max"
+ "build-debug": "BINDINGS_DEBUG=true node ./install/install.js"
},
"gypfile": true,
"dependencies": {
"nan": "^2.14.0",
"native-node-utils": "^0.2.7",
- "opencv-build": "^0.1.5"
+ "npmlog": "^4.1.2",
+ "opencv-build": "^0.1.9"
},
"optionalDependencies": {
"@types/node": ">6"
diff --git a/test/tests/index.test.js b/test/tests/index.test.js
index ebd2b9d36..46c45ef44 100644
--- a/test/tests/index.test.js
+++ b/test/tests/index.test.js
@@ -64,9 +64,25 @@ describe('cv', () => {
builtModules = builtModules.filter(m => m !== 'dnn')
}
+ const opencvVersionString = `${cv.version.major}.${cv.version.minor}.${cv.version.revision}`
+
+ console.log('envs are:')
+ console.log('OPENCV_VERSION:', process.env.OPENCV_VERSION)
+ console.log('TEST_MODULE_LIST:', process.env.TEST_MODULE_LIST)
+ console.log('APPVEYOR_BUILD:', process.env.APPVEYOR_BUILD)
+ console.log('process.platform:', process.platform)
+ console.log()
+ console.log('OpenCV version is:', opencvVersionString)
console.log('compiled with the following modules:', cv.modules)
console.log('expected modules to be built:', builtModules)
+ it('OpenCV version should match', () => {
+ expect((process.env.OPENCV_VERSION || '').substr(0, 5)).to.equal(
+ // on osx latest opencv package for major version is installed via brew
+ process.platform === 'darwin' ? `${cv.version.major}` : opencvVersionString
+ )
+ })
+
it('all modules should be built', () => {
builtModules.forEach(m => expect(cv.modules).to.have.property(m));
})