123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /* vim: set expandtab ts=4 sw=4: */
- /*
- * You may redistribute this program and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- var Fs = require('fs');
- var nThen = require('nthen');
- var Codestyle = require('./Codestyle');
- var Cp = require('./Cp');
- var Spawn = require('child_process').spawn;
- var Os = require('os');
- var FindPython2 = require('./FindPython2');
- var CanCompile = require('./CanCompile');
- var Builder = require('./builder');
- var TestRunner = require('./TestRunner');
- // ['linux','darwin','sunos','win32','freebsd','openbsd','netbsd']
- var SYSTEM = process.env['SYSTEM'] || process.platform;
- var GCC = process.env['CC'];
- var CFLAGS = process.env['CFLAGS'];
- var LDFLAGS = process.env['LDFLAGS'];
- var NO_MARCH_FLAG = ['ppc', 'ppc64'];
- if (GCC) {
- // Already specified.
- } else if (SYSTEM === 'openbsd') {
- GCC = 'egcc';
- } else if (SYSTEM === 'freebsd') {
- GCC = 'clang';
- } else {
- GCC = 'gcc';
- }
- Builder.configure({
- systemName: SYSTEM,
- crossCompiling: process.env['CROSS'] !== undefined,
- gcc: GCC,
- tempDir: process.env['CJDNS_BUILD_TMPDIR'] || '/tmp',
- optimizeLevel: '-O3',
- logLevel: process.env['Log_LEVEL'] || 'DEBUG'
- }, function (builder, waitFor) {
- builder.config.cflags.push(
- '-std=c99',
- '-Wall',
- '-Wextra',
- '-Werror',
- '-Wno-pointer-sign',
- '-pedantic',
- '-D', builder.config.systemName + '=1',
- '-D', 'CJD_PACKAGE_VERSION="' + builder.config.version + '"',
- '-Wno-unused-parameter',
- // '-fomit-frame-pointer',
- '-D', 'Log_' + builder.config.logLevel,
- '-g',
- // f4 = 16 peers max, fixed width 4 bit
- // f8 = 241 peers max, fixed width 8 bit
- // v3x5x8 = 256 peers max, variable width, 3, 5 or 8 bits plus 1 or 2 bits of prefix
- // v4x8 = 256 peers max, variable width, 4, or 8 bits plus 1 bit prefix
- '-D', 'NumberCompress_TYPE=v3x5x8',
- // enable for safety (don't worry about speed, profiling shows they add ~nothing)
- '-D', 'Identity_CHECK=1',
- '-D', 'Allocator_USE_CANARIES=1',
- '-D', 'PARANOIA=1'
- );
- if (process.env['SUBNODE']) { builder.config.cflags.push('-DSUBNODE=1'); }
- if (process.env['GCOV']) {
- builder.config.cflags.push('-fprofile-arcs', '-ftest-coverage');
- builder.config.ldflags.push('-fprofile-arcs', '-ftest-coverage');
- }
- var android = /android/i.test(builder.config.gcc);
- if (process.env['TESTING']) {
- builder.config.cflags.push('-D', 'TESTING=1');
- }
- if (process.env['ADDRESS_PREFIX'] !== undefined) {
- builder.config.cflags.push('-D', 'ADDRESS_PREFIX=' + process.env['ADDRESS_PREFIX']);
- }
- if (process.env['ADDRESS_PREFIX_BITS'] !== undefined) {
- builder.config.cflags.push('-D', 'ADDRESS_PREFIX_BITS=' + process.env['ADDRESS_PREFIX_BITS']);
- }
- if (!builder.config.crossCompiling) {
- if (NO_MARCH_FLAG.indexOf(process.arch) == -1) {
- builder.config.cflags.push('-march=native');
- }
- }
- if (builder.config.systemName === 'win32') {
- builder.config.cflags.push('-Wno-format');
- } else if (builder.config.systemName === 'linux') {
- builder.config.ldflags.push('-Wl,-z,relro,-z,now,-z,noexecstack');
- builder.config.cflags.push('-DHAS_ETH_INTERFACE=1');
- } else if (builder.config.systemName === 'darwin') {
- builder.config.cflags.push('-DHAS_ETH_INTERFACE=1');
- }
- if (process.env['NO_PIE'] === undefined && builder.config.systemName !== 'freebsd'
- && builder.config.systemName !== 'win32')
- {
- builder.config.cflags.push('-fPIE');
- // just using `-pie` on OS X >= 10.10 results in this warning:
- // clang: warning: argument unused during compilation: '-pie'
- if (builder.config.systemName !== "darwin")
- {
- builder.config.ldflags.push('-pie');
- } else {
- builder.config.ldflags.push('-Wl,-pie');
- }
- }
- if (builder.config.compilerType.isClang) {
- // blows up when preprocessing before js preprocessor
- builder.config.cflags.push(
- '-Wno-invalid-pp-token',
- '-Wno-dollar-in-identifier-extension',
- '-Wno-newline-eof',
- '-Wno-unused-value',
- // lots of places where depending on preprocessor conditions, a statement might be
- // a case of if (1 == 1)
- '-Wno-tautological-compare',
- '-Wno-error'
- );
- builder.config.cflags.slice(builder.config.cflags.indexOf('-Werror'), 1);
- }
- // Install any user-defined CFLAGS. Necessary if you are messing about with building cnacl
- // with NEON on the BBB, or want to set -Os (OpenWrt)
- // Allow -O0 so while debugging all variables are present.
- if (CFLAGS) {
- var cflags = CFLAGS.split(' ');
- cflags.forEach(function(flag) {
- if (/^\-O[^02s]$/.test(flag)) {
- console.log("Skipping " + flag + ", assuming " +
- builder.config.optimizeLevel + " instead.");
- } else if (/^\-O[02s]$/.test(flag)) {
- builder.config.optimizeLevel = flag;
- } else {
- [].push.apply(builder.config.cflags, cflags);
- }
- });
- }
- if (!/^\-O0$/.test(builder.config.optimizeLevel)) {
- builder.config.cflags.push('-D_FORTIFY_SOURCE=2');
- }
- // We also need to pass various architecture/floating point flags to GCC when invoked as
- // a linker.
- if (LDFLAGS) {
- [].push.apply(builder.config.ldflags, LDFLAGS.split(' '));
- }
- if (android) {
- builder.config.cflags.push('-Dandroid=1');
- }
- CanCompile.check(builder,
- 'int main() { return 0; }',
- [ builder.config.cflags, '-flto', '-x', 'c' ],
- function (err, can) {
- if (can) {
- console.log("Compiler supports link time optimization");
- builder.config.ldflags.push(
- '-flto',
- builder.config.optimizeLevel
- );
- } else {
- console.log("Link time optimization not supported [" + err + "]");
- }
- builder.config.cflags.push(builder.config.optimizeLevel);
- });
- var uclibc = process.env['UCLIBC'] == '1';
- var libssp;
- switch (process.env['SSP_SUPPORT']) {
- case 'y':
- case '1': libssp = true; break;
- case 'n':
- case '' :
- case '0': libssp = false; break;
- case undefined: break;
- default: throw new Error();
- }
- if (libssp === false) {
- console.log("Stack Smashing Protection (security feature) is disabled");
- } else if (builder.config.systemName == 'win32') {
- builder.config.libs.push('-lssp');
- } else if ((!uclibc && builder.config.systemName !== 'sunos') || libssp === true) {
- builder.config.cflags.push(
- // Broken GCC patch makes -fstack-protector-all not work
- // workaround is to give -fno-stack-protector first.
- // see: https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/691722
- '-fno-stack-protector',
- '-fstack-protector-all',
- '-Wstack-protector'
- );
- // Static libssp provides __stack_chk_fail_local, which x86 needs in
- // order to avoid expensively looking up the location of __stack_chk_fail.
- var x86 = process.env['TARGET_ARCH'] == 'i386';
- if (uclibc) {
- if (x86) {
- builder.config.libs.push('-Wl,-Bstatic', '-lssp', '-Wl,-Bdynamic');
- } else {
- builder.config.libs.push('-lssp');
- }
- }
- } else {
- console.log("Stack Smashing Protection (security feature) is disabled");
- }
- if (process.env['Pipe_PREFIX'] !== undefined) {
- builder.config.cflags.push(
- '-D', 'Pipe_PREFIX="' + process.env['Pipe_PREFIX'] + '"'
- );
- }
- var dependencyDir = builder.config.buildDir + '/dependencies';
- var libuvLib = dependencyDir + '/libuv/out/Release/libuv.a';
- if (['win32', 'netbsd'].indexOf(builder.config.systemName) >= 0) {//this might be needed for other BSDs
- libuvLib = dependencyDir + '/libuv/out/Release/obj.target/libuv.a';
- }
- // Build dependencies
- nThen(function (waitFor) {
- Fs.exists(dependencyDir, waitFor(function (exists) {
- if (exists) { return; }
- console.log("Copy dependencies");
- Cp('./node_build/dependencies', dependencyDir, waitFor());
- }));
- }).nThen(function (waitFor) {
- builder.config.libs.push(dependencyDir + '/cnacl/jsbuild/libnacl.a');
- builder.config.includeDirs.push(dependencyDir + '/cnacl/jsbuild/include/');
- // needed for Sign.c which pulls in crypto_int32.h
- builder.config.includeDirs.push(dependencyDir + '/cnacl/jsbuild/include_internal/');
- Fs.exists(dependencyDir + '/cnacl/jsbuild/libnacl.a', waitFor(function (exists) {
- if (exists) { return; }
- console.log("Build NaCl");
- var cwd = process.cwd();
- process.chdir(dependencyDir + '/cnacl/');
- var NaCl = require(process.cwd() + '/node_build/make.js');
- NaCl.build(function (args, callback) {
- if (builder.config.systemName !== 'win32') {
- args.unshift('-fPIC');
- }
- args.unshift(builder.config.optimizeLevel, '-fomit-frame-pointer');
- if (!/^\-O0$/.test(builder.config.optimizeLevel)) {
- args.unshift('-D_FORTIFY_SOURCE=2');
- }
- if (CFLAGS) {
- [].push.apply(args, CFLAGS.split(' '));
- }
- if (!builder.config.crossCompiling) {
- if (NO_MARCH_FLAG.indexOf(process.arch) == -1) {
- args.unshift('-march=native');
- }
- }
- builder.cc(args, callback);
- },
- builder.config,
- waitFor(function () {
- process.chdir(cwd);
- }));
- }));
- }).nThen(function (waitFor) {
- builder.config.libs.push(libuvLib);
- if (!android) {
- builder.config.libs.push('-lpthread');
- }
- if (builder.config.systemName === 'win32') {
- builder.config.libs.push(
- '-lws2_32',
- '-lpsapi', // GetProcessMemoryInfo()
- '-liphlpapi' // GetAdapterAddresses()
- );
- } else if (builder.config.systemName === 'linux' && !android) {
- builder.config.libs.push('-lrt'); // clock_gettime()
- } else if (builder.config.systemName === 'darwin') {
- builder.config.libs.push('-framework', 'CoreServices');
- } else if (['freebsd', 'openbsd', 'netbsd'].indexOf(builder.config.systemName) >= 0) {
- builder.config.cflags.push('-Wno-overlength-strings');
- builder.config.libs.push('-lkvm');
- } else if (builder.config.systemName === 'sunos') {
- builder.config.libs.push(
- '-lsocket',
- '-lsendfile',
- '-lkstat',
- '-lnsl'
- );
- }
- builder.config.includeDirs.push(dependencyDir + '/libuv/include/');
- var libuvBuilt;
- var python;
- nThen(function (waitFor) {
- Fs.exists(libuvLib, waitFor(function (exists) {
- if (exists) { libuvBuilt = true; }
- }));
- }).nThen(function (waitFor) {
- if (libuvBuilt) { return; }
- FindPython2.find(builder.tmpFile(), waitFor(function (err, pythonExec) {
- if (err) { throw err; }
- python = pythonExec;
- }));
- }).nThen(function (waitFor) {
- if (libuvBuilt) { return; }
- console.log("Build Libuv");
- var cwd = process.cwd();
- process.chdir(dependencyDir + '/libuv/');
- var args = ['./gyp_uv.py'];
- var env = process.env;
- env.CC = builder.config.gcc;
- if (env.TARGET_ARCH) {
- args.push('-Dtarget_arch=' + env.TARGET_ARCH);
- }
- //args.push('--root-target=libuv');
- if (android) {
- args.push('-DOS=android');
- }
- if (builder.config.systemName === 'win32') {
- args.push('-DOS=win');
- }
- if (env.GYP_ADDITIONAL_ARGS) {
- args.push.apply(args, env.GYP_ADDITIONAL_ARGS.split(' '));
- }
- if (['freebsd', 'openbsd', 'netbsd'].indexOf(builder.config.systemName) !== -1) {
- // This platform lacks a functioning sem_open implementation, therefore...
- args.push('--no-parallel');
- args.push('-DOS=' + builder.config.systemName);
- }
- var gyp = Spawn(python, args, {env:env, stdio:'inherit'});
- gyp.on('error', function () {
- console.error("couldn't launch gyp [" + python + "]");
- });
- gyp.on('close', waitFor(function () {
- var args = [
- '-j', builder.processors,
- '-C', 'out',
- 'BUILDTYPE=Release',
- 'CC=' + builder.config.gcc,
- 'CXX=' + builder.config.gcc,
- 'V=1'
- ];
- var cflags = [builder.config.optimizeLevel, '-DNO_EMFILE_TRICK=1'];
- if (!/^\-O0$/.test(builder.config.optimizeLevel)) {
- cflags.push('-D_FORTIFY_SOURCE=2');
- }
- if (!(/darwin|win32/i.test(builder.config.systemName))) {
- cflags.push('-fPIC');
- }
- args.push('CFLAGS=' + cflags.join(' '));
- var makeCommand = ['freebsd', 'openbsd', 'netbsd'].indexOf(builder.config.systemName) >= 0 ? 'gmake' : 'make';
- var make = Spawn(makeCommand, args, {stdio: 'inherit'});
- make.on('error', function (err) {
- if (err.code === 'ENOENT') {
- console.error('\033[1;31mError: ' + makeCommand + ' is required!\033[0m');
- } else {
- console.error(
- '\033[1;31mFail run ' + process.cwd() + ': ' + makeCommand + ' '
- + args.join(' ') + '\033[0m'
- );
- console.error('Message:', err);
- }
- waitFor.abort();
- });
- make.on('close', waitFor(function () {
- process.chdir(cwd);
- }));
- }));
- }).nThen(waitFor());
- }).nThen(waitFor());
- }).build(function (builder, waitFor) {
- builder.buildExecutable('client/cjdroute2.c', 'cjdroute');
- builder.buildExecutable('contrib/c/publictoip6.c');
- builder.buildExecutable('contrib/c/privatetopublic.c');
- builder.buildExecutable('contrib/c/sybilsim.c');
- builder.buildExecutable('contrib/c/makekeys.c');
- builder.buildExecutable('contrib/c/mkpasswd.c');
- builder.buildExecutable('crypto/random/randombytes.c');
- builder.lintFiles(function (fileName, file, callback) {
- if (/dependencies/.test(fileName)) {
- callback('', false);
- return;
- }
- Codestyle.lint(fileName, file, callback);
- });
- var testcjdroute = builder.buildTest('test/testcjdroute.c');
- if (builder.config.crossCompiling) {
- console.log("Cross compiling. Building, but not running tests.");
- return;
- }
- var testRunner = TestRunner.local(['all']);
- if (process.env['REMOTE_TEST']) {
- testRunner = TestRunner.remote(process.env['REMOTE_TEST'], ['all']);
- }
- if (!process.env['NO_TEST']) {
- builder.runTest(testcjdroute, testRunner);
- }
- }).success(function (builder, waitFor) {
- console.log('\033[1;32mBuild completed successfully, type ./cjdroute to begin setup.\033[0m');
- }).failure(function (builder, waitFor) {
- console.log('\033[1;31mFailed to build cjdns.\033[0m');
- process.exit(1);
- }).complete(function (builder, waitFor) {
- if (builder.failure) {
- process.exit(1);
- }
- });
|