From 3047a1c419fde8d728ccbb769ca703ea9f5fc037 Mon Sep 17 00:00:00 2001 From: Roger Butler Date: Sun, 29 Nov 2015 13:54:25 -0500 Subject: [PATCH] Added Encryption --- .gitignore | 1 + CHANGES | 5 + CMakeLists.txt | 72 + OpenVEILAddon.cpp | 188 - OpenVEILAddon.h | 136 - Samples/tokenList.js | 71 + addon.js | 5 +- binding.gyp | 32 - build.cmd | 2 - cmakemodules/FindBZ2.cmake | 117 + cmakemodules/FindGMock.cmake | 87 + cmakemodules/FindGTest.cmake | 86 + cmakemodules/FindHaru.cmake | 121 + cmakemodules/FindPCSC.cmake | 54 + cmakemodules/FindZLIB.cmake | 130 + cmakemodules/compiler_tecsec_darwin.cmake | 59 + cmakemodules/compiler_tecsec_gnucc.cmake | 109 + cmakemodules/compiler_tecsec_msvc.cmake | 109 + .../compiler_tecsec_msvc.noWarnings.cmake | 32 + cmakemodules/cotire.cmake | 3629 +++++++++++++++++ cmakemodules/machineBitSize.cmake | 72 + cmakemodules/precompiled.header.cmake | 166 + cmakemodules/summary.cmake | 119 + cmakemodules/tecsec_base_macros.cmake | 678 +++ cmakemodules/tecsec_installdirs.cmake | 78 + cmakemodules/tecsec_top.cmake | 279 ++ cmakemodules/uninstall.cmake.in | 54 + configure.cmd | 3 + package.json | 12 +- src/Favorite.cpp | 271 ++ src/Favorite.h | 249 ++ addon.cc => src/GenericConnector.cpp | 11 +- src/GenericConnector.h | 245 ++ src/KeyVEILConnector.cpp | 265 ++ src/KeyVEILConnector.h | 479 +++ src/Session.cpp | 53 + src/Session.h | 502 +++ src/Token.cpp | 65 + src/Token.h | 216 + src/addon.cc | 116 + 40 files changed, 8613 insertions(+), 365 deletions(-) create mode 100644 CMakeLists.txt delete mode 100644 OpenVEILAddon.cpp delete mode 100644 OpenVEILAddon.h create mode 100644 Samples/tokenList.js delete mode 100644 binding.gyp delete mode 100644 build.cmd create mode 100644 cmakemodules/FindBZ2.cmake create mode 100644 cmakemodules/FindGMock.cmake create mode 100644 cmakemodules/FindGTest.cmake create mode 100644 cmakemodules/FindHaru.cmake create mode 100644 cmakemodules/FindPCSC.cmake create mode 100644 cmakemodules/FindZLIB.cmake create mode 100644 cmakemodules/compiler_tecsec_darwin.cmake create mode 100644 cmakemodules/compiler_tecsec_gnucc.cmake create mode 100644 cmakemodules/compiler_tecsec_msvc.cmake create mode 100644 cmakemodules/compiler_tecsec_msvc.noWarnings.cmake create mode 100644 cmakemodules/cotire.cmake create mode 100644 cmakemodules/machineBitSize.cmake create mode 100644 cmakemodules/precompiled.header.cmake create mode 100644 cmakemodules/summary.cmake create mode 100644 cmakemodules/tecsec_base_macros.cmake create mode 100644 cmakemodules/tecsec_installdirs.cmake create mode 100644 cmakemodules/tecsec_top.cmake create mode 100644 cmakemodules/uninstall.cmake.in create mode 100644 configure.cmd create mode 100644 src/Favorite.cpp create mode 100644 src/Favorite.h rename addon.cc => src/GenericConnector.cpp (89%) create mode 100644 src/GenericConnector.h create mode 100644 src/KeyVEILConnector.cpp create mode 100644 src/KeyVEILConnector.h create mode 100644 src/Session.cpp create mode 100644 src/Session.h create mode 100644 src/Token.cpp create mode 100644 src/Token.h create mode 100644 src/addon.cc diff --git a/.gitignore b/.gitignore index 4aedc2a..3c86d5a 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ build/ *.sdf *.opensdf *.log +node_modules \ No newline at end of file diff --git a/CHANGES b/CHANGES index 3a02ad4..c70ce2f 100644 --- a/CHANGES +++ b/CHANGES @@ -1 +1,6 @@ Initial release of the Node.JS language bindings to OpenVEIL (7.0.18) + +11/27/2015 - Changed to use cmake-js + npm install -g cmake-js + cmake-js configure + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..510293c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,72 @@ +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmakemodules) + +set(TS_VS_CONFIG ${CMAKE_BUILD_TYPE}) +IF(WIN32) + cmake_minimum_required(VERSION 3.1.3) + set_property(GLOBAL PROPERTY USE_FOLDERS On) +ELSE() + cmake_minimum_required(VERSION 3.1.3) +ENDIF() + +project (OpenVEILnodeJS C CXX) + +IF(WIN32) + if(MSVC_IDE) + set(TS_INSTALL_PREFIX "c:/TecSec/OpenVEIL_7-0") + else(MSVC_IDE) + set(TS_INSTALL_PREFIX "c:/TecSec/OpenVEIL_7-0") + endif(MSVC_IDE) + set(TS_INSTALL_PREFIX_DEBUG "c:/TecSec/OpenVEIL_7-0") + set(TS_INSTALL_PREFIX_RELEASE "c:/TecSec/OpenVEIL_7-0") +ELSE(WIN32) + SET(TS_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/../local" CACHE STRING "The install path to use for Linux") +ENDIF(WIN32) + +set(TS_MODULE OpenVEILnodeJs) + +include(tecsec_top) +include(precompiled.header) +set(TS_INSTALL_PREFIX ${TS_INSTALL_PREFIX}/${TS_TOOLSET}) +include (tecsec_installdirs) + +include(summary) +include(${ALLBIN_DIR}/OpenVEILVersion.cmake) +set(CMAKE_DEBUG_POSTFIX "") + +message(STATUS "ALLBIN_DIR = ${ALLBIN_DIR}") +message(STATUS "OPENVEIL_INSTALL_BASE_DIR = ${OPENVEIL_INSTALL_BASE_DIR}") +message(STATUS "OPENVEIL_INSTALL_BIN_DIR = ${OPENVEIL_INSTALL_BIN_DIR}") +message(STATUS "OPENVEIL_INSTALL_INCLUDE_DIR = ${OPENVEIL_INSTALL_INCLUDE_DIR}") +message(STATUS "OPENVEIL_INSTALL_LIB_DIR = ${OPENVEIL_INSTALL_LIB_DIR}") +message(STATUS "OPENVEIL_INSTALL_SHLIB_DIR = ${OPENVEIL_INSTALL_SHLIB_DIR}") + + +ImportTarget(OpenVEILCore) +ImportTarget(CmsHeader) +ImportTarget(FileVEILSupport) + +set(CMAKE_BUILD_TYPE ${TS_VS_CONFIG} CACHE STRING "The configuration build type") +if (CMAKE_CONFIGURATION_TYPES) + set (CMAKE_CONFIGURATION_TYPES ${TS_VS_CONFIG}) + set (CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "Reset the configurations for ${VEILCORENAME}" ) +endif() + +set(VEIL_COPYRIGHT "Copyright (C) 2015 TecSec, Inc. All Rights Reserved Worldwide.") + +include_directories(${CMAKE_JS_INC}) + +add_uninstall() + +add_library(OpenVEIL SHARED "src/KeyVEILConnector.cpp" "src/KeyVEILConnector.h" "src/GenericConnector.cpp" "src/GenericConnector.h" "src/Favorite.cpp" "src/Favorite.h" "src/Session.cpp" "src/Session.h" "src/Token.cpp" "src/Token.h" "src/addon.cc") +set_target_properties(OpenVEIL PROPERTIES PREFIX "" SUFFIX ".node") +target_link_libraries(OpenVEIL ${CMAKE_JS_LIB} OpenVEILCore CmsHeader FileVEILSupport) + +summary() + +CopyImportTargetBinaries(OpenVEILCore ${BIN_DIR}) +CopyImportTargetBinaries(CmsHeader ${BIN_DIR}) +CopyImportTargetBinaries(FileVEILSupport ${BIN_DIR}) + +install(TARGETS OpenVEIL ARCHIVE DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${SHLIB_DIR} RUNTIME DESTINATION ${BIN_DIR} ) +install(FILES Samples/tokenList.js DESTINATION ${BIN_DIR}/Samples) +# DumpAllVariables() diff --git a/OpenVEILAddon.cpp b/OpenVEILAddon.cpp deleted file mode 100644 index e25d0f1..0000000 --- a/OpenVEILAddon.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) 2015, TecSec, Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of TecSec nor the names of the contributors may be -// used to endorse or promote products derived from this software -// without specific prior written permission. -// -// ALTERNATIVELY, provided that this notice is retained in full, this product -// may be distributed under the terms of the GNU General Public License (GPL), -// in which case the provisions of the GPL apply INSTEAD OF those given above. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#include "OpenVEILAddon.h" - -using namespace v8; - -Persistent OpenVEILAddon::constructor; - -OpenVEILAddon::OpenVEILAddon() { - _value = ::ServiceLocator()->try_get_instance("/KeyVEILConnector"); -} - -OpenVEILAddon::~OpenVEILAddon() { -} - -void OpenVEILAddon::Init(Handle exports) { - Isolate* isolate = Isolate::GetCurrent(); - - // Prepare constructor template - Local tpl = FunctionTemplate::New(isolate, New); - tpl->SetClassName(String::NewFromUtf8(isolate, "OpenVEIL")); - tpl->InstanceTemplate()->SetInternalFieldCount(1); - - // Prototype - NODE_SET_PROTOTYPE_METHOD(tpl, "genericConnect", GenericConnect); - NODE_SET_PROTOTYPE_METHOD(tpl, "kvConnect", KvConnect); - NODE_SET_PROTOTYPE_METHOD(tpl, "disconnect", Disconnect); - NODE_SET_PROTOTYPE_METHOD(tpl, "isConnected", IsConnected); - NODE_SET_PROTOTYPE_METHOD(tpl, "sendJsonRequest", SendJsonRequest); - NODE_SET_PROTOTYPE_METHOD(tpl, "sendRequest", SendRequest); - - constructor.Reset(isolate, tpl->GetFunction()); - exports->Set(String::NewFromUtf8(isolate, "OpenVEIL"), - tpl->GetFunction()); -} - -void OpenVEILAddon::New(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - - if (args.IsConstructCall()) { - // Invoked as constructor: `new MyObject(...)` - //double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); - OpenVEILAddon* obj = new OpenVEILAddon(/*value*/); - obj->Wrap(args.This()); - args.GetReturnValue().Set(args.This()); - } - else { - // Invoked as plain function `MyObject(...)`, turn into construct call. - const int argc = 1; - Local argv[argc] = { args[0] }; - Local cons = Local::New(isolate, constructor); - args.GetReturnValue().Set(cons->NewInstance(argc, argv)); - } -} - -static tsAscii StringToTsAscii(v8::Local& string) -{ - tsAscii tmp; - const int length = string->Utf8Length() + 1; // Add one for trailing zero byte. - tmp.resize(length); - string->WriteOneByte((uint8_t*)tmp.rawData(), /* start */ 0, length); - return tmp; -} - -void OpenVEILAddon::GenericConnect(const v8::FunctionCallbackInfo& args) -{ - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - OpenVEILAddon* obj = ObjectWrap::Unwrap(args.Holder()); - - if (args.Length() < 3) - { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Wrong number of arguments"))); - return; - } - - int retVal = obj->genericConnect(StringToTsAscii(args[0]->ToString()), StringToTsAscii(args[1]->ToString()), StringToTsAscii(args[2]->ToString())); - args.GetReturnValue().Set(Number::New(isolate, retVal)); -} -void OpenVEILAddon::KvConnect(const v8::FunctionCallbackInfo& args) -{ - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - OpenVEILAddon* obj = ObjectWrap::Unwrap(args.Holder()); - - if (args.Length() < 3) - { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Wrong number of arguments"))); - return; - } - - int retVal = obj->kvConnect(StringToTsAscii(args[0]->ToString()), StringToTsAscii(args[1]->ToString()), StringToTsAscii(args[2]->ToString())); - args.GetReturnValue().Set(Number::New(isolate, retVal)); -} -void OpenVEILAddon::Disconnect(const v8::FunctionCallbackInfo& args) -{ - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - OpenVEILAddon* obj = ObjectWrap::Unwrap(args.Holder()); - obj->disconnect(); -} -void OpenVEILAddon::IsConnected(const v8::FunctionCallbackInfo& args) -{ - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - OpenVEILAddon* obj = ObjectWrap::Unwrap(args.Holder()); - args.GetReturnValue().Set(Boolean::New(isolate, obj->isConnected())); -} -void OpenVEILAddon::SendJsonRequest(const v8::FunctionCallbackInfo& args) -{ - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - OpenVEILAddon* obj = ObjectWrap::Unwrap(args.Holder()); - - if (args.Length() < 3) - { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Wrong number of arguments"))); - return; - } - - tsAscii outData; - int status = 0; - bool retVal = obj->sendJsonRequest(StringToTsAscii(args[0]->ToString()), StringToTsAscii(args[1]->ToString()), StringToTsAscii(args[2]->ToString()), outData, status); - - Local outObj = Object::New(isolate); - outObj->Set(String::NewFromUtf8(isolate, "status"), Number::New(isolate, status)); - outObj->Set(String::NewFromUtf8(isolate, "retVal"), Boolean::New(isolate, retVal)); - outObj->Set(String::NewFromUtf8(isolate, "outData"), String::NewFromUtf8(isolate, outData.c_str())); - - args.GetReturnValue().Set(outObj); -} -void OpenVEILAddon::SendRequest(const v8::FunctionCallbackInfo& args) -{ - Isolate* isolate = Isolate::GetCurrent(); - HandleScope scope(isolate); - OpenVEILAddon* obj = ObjectWrap::Unwrap(args.Holder()); - - if (args.Length() < 3) - { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Wrong number of arguments"))); - return; - } - - tsAscii outData; - int status = 0; - bool retVal = obj->sendRequest(StringToTsAscii(args[0]->ToString()), StringToTsAscii(args[1]->ToString()), StringToTsAscii(args[2]->ToString()), outData, status); - - Local outObj = Object::New(isolate); - outObj->Set(String::NewFromUtf8(isolate, "status"), Number::New(isolate, status)); - outObj->Set(String::NewFromUtf8(isolate, "retVal"), Boolean::New(isolate, retVal)); - outObj->Set(String::NewFromUtf8(isolate, "outData"), String::NewFromUtf8(isolate, outData.c_str())); - - args.GetReturnValue().Set(outObj); -} - diff --git a/OpenVEILAddon.h b/OpenVEILAddon.h deleted file mode 100644 index 7dbb582..0000000 --- a/OpenVEILAddon.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (c) 2015, TecSec, Inc. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of TecSec nor the names of the contributors may be -// used to endorse or promote products derived from this software -// without specific prior written permission. -// -// ALTERNATIVELY, provided that this notice is retained in full, this product -// may be distributed under the terms of the GNU General Public License (GPL), -// in which case the provisions of the GPL apply INSTEAD OF those given above. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#ifndef __OPENVEILADDON_H__ -#define __OPENVEILADDON_H__ - -#include "OpenVEIL.h" -#include -#include - -class OpenVEILAddon : public node::ObjectWrap -{ -public: - static void Init(v8::Handle exports); - -private: - explicit OpenVEILAddon(); - ~OpenVEILAddon(); - - std::shared_ptr _value; - int genericConnect(const tsAscii& url, const tsAscii& username, const tsAscii& password) - { - if (!isReady()) - { - return connStatus_NoServer; - } - - return _value->genericConnectToServer(url, username, password); - } - int kvConnect(const tsAscii& url, const tsAscii& username, const tsAscii& password) - { - if (!isReady()) - { - return connStatus_NoServer; - } - - return _value->connect(url, username, password); - } - void disconnect() - { - if (isConnected()) - { - _value->disconnect(); - } - } - bool isConnected() - { - if (isReady()) - { - return _value->isConnected(); - } - else - { - return false; - } - } - bool sendJsonRequest(const tsAscii& verb, const tsAscii& cmd, const tsAscii& inData, tsAscii& outData, int& status) - { - if (isReady()) - { - JSONObject inObj, outObj; - - if (inObj.FromJSON(inData.c_str()) <= 0) - return false; - - bool retVal = _value->sendJsonRequest(verb, cmd, inObj, outObj, status); - outData = outObj.ToJSON(); - return retVal; - } - else - { - return false; - } - } - bool sendRequest(const tsAscii& verb, const tsAscii& cmd, const tsAscii& inData, tsAscii& outData, int& status) - { - if (isReady()) - { - tsData inObj, outObj; - - inObj = inData.Base64ToData(); - - bool retVal = _value->sendRequest(verb, cmd, inObj, outObj, status); - outData = outObj.ToBase64(); - return retVal; - } - else - { - return false; - } - } - bool isReady() - { - return !!_value; - } - - - static void New(const v8::FunctionCallbackInfo& args); - static void GenericConnect(const v8::FunctionCallbackInfo& args); - static void KvConnect(const v8::FunctionCallbackInfo& args); - static void Disconnect(const v8::FunctionCallbackInfo& args); - static void IsConnected(const v8::FunctionCallbackInfo& args); - static void SendJsonRequest(const v8::FunctionCallbackInfo& args); - static void SendRequest(const v8::FunctionCallbackInfo& args); - static v8::Persistent constructor; - -}; - -#endif // __OPENVEILADDON_H__ \ No newline at end of file diff --git a/Samples/tokenList.js b/Samples/tokenList.js new file mode 100644 index 0000000..e05e1c0 --- /dev/null +++ b/Samples/tokenList.js @@ -0,0 +1,71 @@ +var addon = require('../OpenVEIL'), + kvConn = new addon.KeyVEILConnector(), + token, + fav, + session, + inData, + outData, + newSrc, + origBuff, + encBuff, + newBuff; + +kvConn.connect('http://localhost:8125', 'user1', '11111111'); + +for (i = 0; i < kvConn.tokenCount; i++) { + token = kvConn.tokenByIndex(i); + console.log(); + console.log("Token"); + console.log(" Name: " + token.tokenName); + console.log(" Type: " + token.tokenType); + console.log(" serialNumber: " + token.serialNumber); + console.log(" id: " + token.id); + console.log(" Enterprise name: " + token.enterpriseName); + console.log(" Enterprise ID: " + token.enterpriseId); + console.log(" Member Name: " + token.memberName); + console.log(" Member ID: " + token.memberId); +} + +for (i = 0; i < kvConn.favoriteCount; i++) { + fav = kvConn.favoriteByIndex(i); + console.log(); + console.log("Favorite"); + console.log(" Name: " + fav.favoriteName); + console.log(" ID: " + fav.favoriteId); + console.log(" Enterprise: " + fav.enterpriseId); + console.log(" Token Serial: " + fav.tokenSerialNumber); +} + +session = kvConn.tokenBySerialNumber('906845AEC554109D').openSession(); + +console.log("SESSION"); +console.log("Is Valid: " + session.isValid); +console.log("Is logged in: " + session.isLoggedIn); + +if (!session.isLoggedIn) { + console.log(" login returned: " + session.login('11111111')); + console.log(" Is logged in: " + session.isLoggedIn); +} + +// String encryption to base 64 +inData = '1234'; +console.log("Original data: " + inData); +outData = kvConn.favoriteByName("Staff").encryptString(session, inData, true) +console.log("Encrypted data: " + outData) +newSrc = session.decryptString(outData) +console.log("Decrypted data: " + newSrc) + +// buffer encryption +origBuff = new Buffer([1, 2, 3, 4]); +console.log("Original buffer data: " + origBuff.toString('hex')); +encBuff = kvConn.favoriteByName("Staff").encryptData(session, origBuff, true) +console.log("Encrypted data: " + encBuff.toString('hex')) +newBuff = session.decryptData(encBuff) +console.log("Decrypted data: " + newBuff.toString('hex')) + + +// +// Now try file encryption using the same encryption information +// +console.log("File encrypt returned " + kvConn.favoriteByName("Staff").encryptFile(session, 'tokenList.js', true, 'tokenList.js.ckm')) +console.log("File decrypt returned " + session.decryptFile('tokenList.js.ckm', 'tokenList2.js')) diff --git a/addon.js b/addon.js index 7bfd826..eef185f 100644 --- a/addon.js +++ b/addon.js @@ -1,6 +1,9 @@ var addon = require('bindings')('OpenVEIL'); -var obj = new addon.OpenVEIL(); +console.log(addon); +var obj = new addon.KeyVEILConnector(); + +console.log(obj); console.log( obj.isConnected() ); obj.disconnect(); \ No newline at end of file diff --git a/binding.gyp b/binding.gyp deleted file mode 100644 index 126912e..0000000 --- a/binding.gyp +++ /dev/null @@ -1,32 +0,0 @@ -{ - "targets" : [{ - "target_name" : "OpenVEIL", - "sources" : ["OpenVEILAddon.cpp", "OpenVEILAddon.h", "addon.cc"], - "include_dirs" : ["c:/tecsec/OpenVEIL_7-0/vc14/include"], - 'conditions' : [ - ['OS=="win"', { - 'cflags' : [ - '/EHsc', - '/GR', - ], - 'cflags_cc!': [ '-fno-rtti' ], - 'link_settings': { - 'libraries': ['c:/tecsec/OpenVEIL_7-0/vc14/lib/OpenVEILCore.lib'], - }, - 'msvs_settings': { - 'VCCLCompilerTool': { - 'ExceptionHandling': '2', - 'DisableSpecificWarnings': [ '4530', '4506' ], - }, - }, - }, { - # OS != "win" - 'cflags' : [ - '-Werror', - ] - } - ] - ] - } - ] -} diff --git a/build.cmd b/build.cmd deleted file mode 100644 index d6c9d24..0000000 --- a/build.cmd +++ /dev/null @@ -1,2 +0,0 @@ -call node-gyp configure --python c:\python2.7 -call node-gyp build --python c:\python2.7 diff --git a/cmakemodules/FindBZ2.cmake b/cmakemodules/FindBZ2.cmake new file mode 100644 index 0000000..854f1f0 --- /dev/null +++ b/cmakemodules/FindBZ2.cmake @@ -0,0 +1,117 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include (CheckIncludeFiles) +include (CheckLibraryExists) +include (CheckSymbolExists) + +find_path(BZ2_INCLUDE_DIR bzlib.h + HINTS + $ENV{BZ2_ROOT}/include + $ENV{BZ2_ROOT}/include/bz2 + ${BZ2_ROOT}/include + ${BZ2_ROOT}/include/bz2 +) +mark_as_advanced(BZ2_INCLUDE_DIR) + +# if (NOT BZ2_LIBRARIES) + find_library(BZ2_SHARED_LIBRARY_RELEASE NAMES bz2 bzip2 HINTS $ENV{BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} /lib${TS_LIB_DIR_SUFFIX}) + find_library(BZ2_SHARED_LIBRARY_RELWITHDEBINFO NAMES bz2 bzip2 HINTS $ENV{BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} /lib${TS_LIB_DIR_SUFFIX}) + find_library(BZ2_STATIC_LIBRARY_RELEASE NAMES bz2Static bzip2Static HINTS $ENV{BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} /lib${TS_LIB_DIR_SUFFIX}) + find_library(BZ2_STATIC_LIBRARY_RELWITHDEBINFO NAMES bz2Static bzip2Static HINTS $ENV{BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} /lib${TS_LIB_DIR_SUFFIX}) + find_library(BZ2_SHARED_LIBRARY_DEBUG NAMES bz2d bzip2d HINTS $ENV{BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} /lib${TS_LIB_DIR_SUFFIX}) + find_library(BZ2_STATIC_LIBRARY_DEBUG NAMES bz2Staticd bzip2Staticd HINTS $ENV{BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${BZ2_ROOT}/lib${TS_LIB_DIR_SUFFIX} /lib${TS_LIB_DIR_SUFFIX}) +IF(WIN32) + SET(_tmp ${CMAKE_FIND_LIBRARY_SUFFIXES}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(BZ2_SHARED_SO_RELEASE NAMES bz2 bzip2 HINTS $ENV{BZ2_ROOT}/bin ${BZ2_ROOT}/bin) + find_library(BZ2_SHARED_SO_RELWITHDEBINFO NAMES bz2 bzip2 HINTS $ENV{BZ2_ROOT}/bin ${BZ2_ROOT}/bin) + find_library(BZ2_SHARED_SO_DEBUG NAMES bz2d bzip2d HINTS $ENV{BZ2_ROOT}/bin ${BZ2_ROOT}/bin) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_tmp}) +endif(WIN32) +# endif () + +if (BZ2_INCLUDE_DIR AND EXISTS "${BZ2_INCLUDE_DIR}/bzlib.h") + file(STRINGS "${BZ2_INCLUDE_DIR}/bzlib.h" BZLIB_H REGEX "bzip2/libbzip2 version [0-9]+\\.[^ ]+ of [0-9]+ ") + string(REGEX REPLACE ".* bzip2/libbzip2 version ([0-9]+\\.[^ ]+) of [0-9]+ .*" "\\1" BZIP2_VERSION_STRING "${BZLIB_H}") +endif () + +# handle the QUIETLY and REQUIRED arguments and set BZip2_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +IF(WIN32) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZ2 + REQUIRED_VARS BZ2_SHARED_LIBRARY_RELEASE BZ2_STATIC_LIBRARY_RELEASE BZ2_SHARED_LIBRARY_DEBUG BZ2_STATIC_LIBRARY_DEBUG BZ2_INCLUDE_DIR + VERSION_VAR BZ2_VERSION_STRING) +ELSE(WIN32) +set(BZ2_SHARED_LIBRARY_DEBUG ${BZ2_SHARED_LIBRARY_RELEASE}) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(BZ2 + REQUIRED_VARS BZ2_SHARED_LIBRARY_RELEASE BZ2_INCLUDE_DIR + VERSION_VAR BZ2_VERSION_STRING) +ENDIF(WIN32) + +if (BZ2_FOUND) + include(CheckLibraryExists) + include(CMakePushCheckState) + cmake_push_check_state() + set(CMAKE_REQUIRED_QUIET ${BZ2_FIND_QUIETLY}) + CHECK_LIBRARY_EXISTS("${BZIP2_LIBRARIES}" BZ2_bzCompressInit "" BZIP2_NEED_PREFIX) + cmake_pop_check_state() + + if(NOT TARGET BZ2) + if(WIN32) + add_library(BZ2 SHARED IMPORTED) + set_property(TARGET BZ2 PROPERTY IMPORTED_LOCATION_DEBUG "${BZ2_SHARED_SO_DEBUG}") + set_property(TARGET BZ2 PROPERTY IMPORTED_LOCATION_RELEASE "${BZ2_SHARED_SO_RELEASE}") + set_property(TARGET BZ2 PROPERTY IMPORTED_LOCATION_RELWITHDEBINFO "${BZ2_SHARED_SO_RELWITHDEBINFO}") + set_property(TARGET BZ2 PROPERTY IMPORTED_IMPLIB_DEBUG "${BZ2_SHARED_LIBRARY_DEBUG}") + set_property(TARGET BZ2 PROPERTY IMPORTED_IMPLIB_RELEASE "${BZ2_SHARED_LIBRARY_RELEASE}") + set_property(TARGET BZ2 PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "${BZ2_SHARED_LIBRARY_RELWITHDEBINFO}") + set_property(TARGET BZ2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${BZ2_INCLUDE_DIRS}") + else(WIN32) + add_library(BZ2 SHARED IMPORTED) + set_target_properties(BZ2 PROPERTIES + IMPORTED_LOCATION_DEBUG "${BZ2_SHARED_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${BZ2_SHARED_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${BZ2_SHARED_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${BZ2_INCLUDE_DIRS}") + endif(WIN32) + endif() + + if(NOT TARGET BZ2_STATIC) + add_library(BZ2_STATIC UNKNOWN IMPORTED) + set_target_properties(BZ2_STATIC PROPERTIES + IMPORTED_LOCATION_DEBUG "${BZ2_STATIC_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${BZ2_STATIC_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${BZ2_STATIC_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${BZ2_INCLUDE_DIR}") + endif() +endif () + +mark_as_advanced(BZ2_INCLUDE_DIR) diff --git a/cmakemodules/FindGMock.cmake b/cmakemodules/FindGMock.cmake new file mode 100644 index 0000000..4ab06ba --- /dev/null +++ b/cmakemodules/FindGMock.cmake @@ -0,0 +1,87 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include (CheckIncludeFiles) +include (CheckLibraryExists) +include (CheckSymbolExists) + +find_path(GMOCK_INCLUDE_DIR gmock/gmock.h + HINTS + $ENV{GMOCK_ROOT}/include + ${GMOCK_ROOT}/include +) +mark_as_advanced(GMOCK_INCLUDE_DIR) +# if (NOT GMOCK_LIBRARIES) + find_library(GMOCK_SHARED_LIBRARY_RELEASE NAMES gmock HINTS $ENV{GMOCK_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${GMOCK_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(GMOCK_SHARED_LIBRARY_RELWITHDEBINFO NAMES gmock HINTS $ENV{GMOCK_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${GMOCK_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(GMOCK_SHARED_LIBRARY_DEBUG NAMES gmockd HINTS $ENV{GMOCK_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${GMOCK_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + IF(WIN32) + SET(_tmp ${CMAKE_FIND_LIBRARY_SUFFIXES}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(GMOCK_SHARED_SO_RELEASE NAMES gmock HINTS $ENV{GMOCK_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${GMOCK_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(GMOCK_SHARED_SO_RELWITHDEBINFO NAMES gmock HINTS $ENV{GMOCK_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${GMOCK_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(GMOCK_SHARED_SO_DEBUG NAMES gmockd HINTS $ENV{GMOCK_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${GMOCK_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_tmp}) + endif(WIN32) +# endif () + +# handle the QUIETLY and REQUIRED arguments and set BZip2_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMOCK + REQUIRED_VARS GMOCK_SHARED_LIBRARY_RELEASE GMOCK_SHARED_LIBRARY_DEBUG GMOCK_INCLUDE_DIR + ) + +if(GMOCK_FOUND) + set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR}) + set(GMOCK_LIBRARIES ${GMOCK_LIBRARY}) + + if(NOT TARGET GMOCK) + if(WIN32) + add_library(GMOCK SHARED IMPORTED) + set_property(TARGET GMOCK PROPERTY IMPORTED_LOCATION_DEBUG "${GMOCK_SHARED_SO_DEBUG}") + set_property(TARGET GMOCK PROPERTY IMPORTED_LOCATION_RELEASE "${GMOCK_SHARED_SO_RELEASE}") + set_property(TARGET GMOCK PROPERTY IMPORTED_LOCATION_RELWITHDEBINFO "${GMOCK_SHARED_SO_RELWITHDEBINFO}") + set_property(TARGET GMOCK PROPERTY IMPORTED_IMPLIB_DEBUG "${GMOCK_SHARED_LIBRARY_DEBUG}") + set_property(TARGET GMOCK PROPERTY IMPORTED_IMPLIB_RELEASE "${GMOCK_SHARED_LIBRARY_RELEASE}") + set_property(TARGET GMOCK PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "${GMOCK_SHARED_LIBRARY_RELWITHDEBINFO}") + set_property(TARGET GMOCK PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIRS}") + else(WIN32) + add_library(GMOCK SHARED IMPORTED) + set_target_properties(GMOCK PROPERTIES + IMPORTED_LOCATION_DEBUG "${GMOCK_SHARED_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${GMOCK_SHARED_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${GMOCK_SHARED_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIRS}") + endif(WIN32) + endif() + +endif() + +mark_as_advanced(GMOCK_INCLUDE_DIR) diff --git a/cmakemodules/FindGTest.cmake b/cmakemodules/FindGTest.cmake new file mode 100644 index 0000000..9e73a89 --- /dev/null +++ b/cmakemodules/FindGTest.cmake @@ -0,0 +1,86 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include (CheckIncludeFiles) +include (CheckLibraryExists) +include (CheckSymbolExists) + +find_path(GTEST_INCLUDE_DIR gtest/gtest.h + HINTS + $ENV{GTEST_ROOT}/include + ${GTEST_ROOT}/include +) +mark_as_advanced(GTEST_INCLUDE_DIR) +# if (NOT GTEST_LIBRARIES) + find_library(GTEST_SHARED_LIBRARY_RELEASE NAMES gtest HINTS $ENV{GTEST_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${GTEST_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(GTEST_SHARED_LIBRARY_RELWITHDEBINFO NAMES gtest HINTS $ENV{GTEST_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${GTEST_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(GTEST_SHARED_LIBRARY_DEBUG NAMES gtestd HINTS $ENV{GTEST_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${GTEST_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + IF(WIN32) + SET(_tmp ${CMAKE_FIND_LIBRARY_SUFFIXES}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(GTEST_SHARED_SO_RELWITHDEBINFO NAMES gtest HINTS $ENV{GTEST_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${GTEST_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(GTEST_SHARED_SO_RELEASE NAMES gtest HINTS $ENV{GTEST_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${GTEST_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(GTEST_SHARED_SO_DEBUG NAMES gtestd HINTS $ENV{GTEST_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${GTEST_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_tmp}) + endif(WIN32) +# endif () + +# handle the QUIETLY and REQUIRED arguments and set BZip2_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(GTEST + REQUIRED_VARS GTEST_SHARED_LIBRARY_RELEASE GTEST_SHARED_LIBRARY_DEBUG GTEST_INCLUDE_DIR + ) + +if(GTEST_FOUND) + set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR}) + set(GTEST_LIBRARIES ${GTEST_LIBRARY}) + + if(NOT TARGET GTEST) + if(WIN32) + add_library(GTEST SHARED IMPORTED) + set_property(TARGET GTEST PROPERTY IMPORTED_LOCATION_DEBUG "${GTEST_SHARED_SO_DEBUG}") + set_property(TARGET GTEST PROPERTY IMPORTED_LOCATION_RELEASE "${GTEST_SHARED_SO_RELEASE}") + set_property(TARGET GTEST PROPERTY IMPORTED_LOCATION_RELWITHDEBINFO "${GTEST_SHARED_SO_RELWITHDEBINFO}") + set_property(TARGET GTEST PROPERTY IMPORTED_IMPLIB_DEBUG "${GTEST_SHARED_LIBRARY_DEBUG}") + set_property(TARGET GTEST PROPERTY IMPORTED_IMPLIB_RELEASE "${GTEST_SHARED_LIBRARY_RELEASE}") + set_property(TARGET GTEST PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "${GTEST_SHARED_LIBRARY_RELWITHDEBINFO}") + set_property(TARGET GTEST PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}") + else(WIN32) + add_library(GTEST SHARED IMPORTED) + set_target_properties(GTEST PROPERTIES + IMPORTED_LOCATION_DEBUG "${GTEST_SHARED_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${GTEST_SHARED_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${GTEST_SHARED_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIRS}") + endif(WIN32) + endif() +endif() + +mark_as_advanced(GTEST_INCLUDE_DIR) diff --git a/cmakemodules/FindHaru.cmake b/cmakemodules/FindHaru.cmake new file mode 100644 index 0000000..0f210b3 --- /dev/null +++ b/cmakemodules/FindHaru.cmake @@ -0,0 +1,121 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include (CheckIncludeFiles) +include (CheckLibraryExists) +include (CheckSymbolExists) + +find_path(HARU_INCLUDE_DIR hpdf.h + HINTS + $ENV{HARU_ROOT}/include + $ENV{HARU_ROOT}/include/libharu + ${BZ2_ROOT}/include + ${BZ2_ROOT}/include/libharu +) +mark_as_advanced(HARU_INCLUDE_DIR) +# if (NOT HARU_LIBRARIES) + find_library(HARU_SHARED_LIBRARY_RELEASE NAMES libhpdf HINTS $ENV{HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(HARU_SHARED_LIBRARY_RELWITHDEBINFO NAMES libhpdf HINTS $ENV{HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(HARU_STATIC_LIBRARY_RELEASE NAMES libhpdfs HINTS $ENV{HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(HARU_STATIC_LIBRARY_RELWITHDEBINFO NAMES libhpdfs HINTS $ENV{HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(HARU_SHARED_LIBRARY_DEBUG NAMES libhpdfd HINTS $ENV{HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(HARU_STATIC_LIBRARY_DEBUG NAMES libhpdfsd HINTS $ENV{HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + IF(WIN32) + SET(_tmp ${CMAKE_FIND_LIBRARY_SUFFIXES}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(HARU_SHARED_SO_RELEASE NAMES libhpdf HINTS $ENV{HARU_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(HARU_SHARED_SO_RELWITHDEBINFO NAMES libhpdf HINTS $ENV{HARU_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(HARU_SHARED_SO_DEBUG NAMES libhpdfd HINTS $ENV{HARU_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${HARU_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_tmp}) + endif(WIN32) +# endif () + +if(HARU_INCLUDE_DIR AND EXISTS "${HARU_INCLUDE_DIR}/hpdf_version.h") + file(STRINGS "${HARU_INCLUDE_DIR}/hpdf_version.h" HARU_H REGEX "^#define HPDF_VERSION_TEXT \"[^\"]*\"$") + + string(REGEX REPLACE "^.*HPDF_VERSION_TEXT \"([0-9]+).*$" "\\1" HARU_VERSION_MAJOR "${HARU_H}") + string(REGEX REPLACE "^.*HPDF_VERSION_TEXT \"[0-9]+\\.([0-9]+).*$" "\\1" HARU_VERSION_MINOR "${HARU_H}") + string(REGEX REPLACE "^.*HPDF_VERSION_TEXT \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" HARU_VERSION_PATCH "${HARU_H}") + set(HARU_VERSION_STRING "${HARU_VERSION_MAJOR}.${HARU_VERSION_MINOR}.${HARU_VERSION_PATCH}") + + # only append a TWEAK version if it exists: + set(HARU_VERSION_TWEAK "") + if( "${HARU_H}" MATCHES "HARU_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)") + set(HARU_VERSION_TWEAK "${CMAKE_MATCH_1}") + set(HARU_VERSION_STRING "${HARU_VERSION_STRING}.${HARU_VERSION_TWEAK}") + endif() + + set(HARU_MAJOR_VERSION "${HARU_VERSION_MAJOR}") + set(HARU_MINOR_VERSION "${HARU_VERSION_MINOR}") + set(HARU_PATCH_VERSION "${HARU_VERSION_PATCH}") +endif() + +# handle the QUIETLY and REQUIRED arguments and set BZip2_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(HARU + REQUIRED_VARS HARU_SHARED_LIBRARY_RELEASE HARU_STATIC_LIBRARY_RELEASE HARU_SHARED_LIBRARY_DEBUG HARU_STATIC_LIBRARY_DEBUG HARU_INCLUDE_DIR + VERSION_VAR HARU_VERSION_STRING) + +if(HARU_FOUND) + set(HARU_INCLUDE_DIRS ${HARU_INCLUDE_DIR}) + set(HARU_LIBRARIES ${HARU_LIBRARY}) + + if(NOT TARGET HARU) + if(WIN32) + add_library(HARU SHARED IMPORTED) + set_property(TARGET HARU PROPERTY IMPORTED_LOCATION_DEBUG "${HARU_SHARED_SO_DEBUG}") + set_property(TARGET HARU PROPERTY IMPORTED_LOCATION_RELEASE "${HARU_SHARED_SO_RELEASE}") + set_property(TARGET HARU PROPERTY IMPORTED_LOCATION_RELWITHDEBINFO "${HARU_SHARED_SO_RELWITHDEBINFO}") + set_property(TARGET HARU PROPERTY IMPORTED_IMPLIB_DEBUG "${HARU_SHARED_LIBRARY_DEBUG}") + set_property(TARGET HARU PROPERTY IMPORTED_IMPLIB_RELEASE "${HARU_SHARED_LIBRARY_RELEASE}") + set_property(TARGET HARU PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "${HARU_SHARED_LIBRARY_RELWITHDEBINFO}") + set_property(TARGET HARU PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${HARU_INCLUDE_DIRS}") + else(WIN32) + add_library(HARU SHARED IMPORTED) + set_target_properties(HARU PROPERTIES + IMPORTED_LOCATION_DEBUG "${HARU_SHARED_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${HARU_SHARED_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${HARU_SHARED_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${HARU_INCLUDE_DIRS}") + endif(WIN32) + endif() + + if(NOT TARGET HARU_STATIC) + add_library(HARU_STATIC UNKNOWN IMPORTED) + set_target_properties(HARU_STATIC PROPERTIES + IMPORTED_LOCATION_DEBUG "${HARU_STATIC_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${HARU_STATIC_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${HARU_STATIC_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${HARU_INCLUDE_DIR}") + endif() + +endif() + +mark_as_advanced(HARU_INCLUDE_DIR) diff --git a/cmakemodules/FindPCSC.cmake b/cmakemodules/FindPCSC.cmake new file mode 100644 index 0000000..ff058c8 --- /dev/null +++ b/cmakemodules/FindPCSC.cmake @@ -0,0 +1,54 @@ + +include(FindPkgConfig) + +function (get_soname SONAME OBJFILE) + find_program(CMAKE_OBJDUMP names objdump DOC "The objdump program") + execute_process( + COMMAND objdump -p "${OBJFILE}" + COMMAND sed -n -es/^[[:space:]]*SONAME[[:space:]]*//p + RESULT_VARIABLE STATUS + OUTPUT_VARIABLE SONAME_OUT + ERROR_QUIET + ) + STRING(REPLACE "\n" "" SONAME_OUT "${SONAME_OUT}") +# get_filename_component(_tmp ${OBJFILE} DIRECTORY) + if (STATUS EQUAL 0) + set(${SONAME} "${SONAME_OUT}" PARENT_SCOPE) + else() + set(${SONAME} "" PARENT_SCOPE) + endif() +endfunction() + + +if (PKG_CONFIG_FOUND) + pkg_check_modules(PCSC libpcsclite) +else() + set(PCSC_INCLUDE_DIRS ${PCSC_INCLUDE_DIRS} /usr/local/include) + set(PCSC_LIBRARY_DIRS ${PCSC_LIBRARY_DIRS} /usr/local/lib) +endif() + +find_path(PCSC_INCLUDE_DIR pcsclite.h PATHS ${PCSC_INCLUDE_DIRS} PATH_SUFFIXES PCSC) + +find_library(PCSC_LIBRARY pcsclite PATHS ${PCSC_LIBRARY_DIRS}) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCSC DEFAULT_MSG PCSC_INCLUDE_DIR PCSC_LIBRARY) + +mark_as_advanced(PCSC_INCLUDE_DIR PCSC_LIBRARY) + +if(PCSC_FOUND) + if(NOT TARGET pcsc) + if(UNIX) + get_soname(PCSC_SO_NAME ${PCSC_LIBRARY}) + find_library(PCSC_LIBRARY_SO ${PCSC_SO_NAME} PATHS ${PCSC_LIBRARY_DIRS}) + add_library(pcsc SHARED IMPORTED) +message(STATUS "PCSC_LIBRARY = ${PCSC_LIBRARY}") +message(STATUS "PCSC SO name = ${PCSC_SO_NAME}") + set_target_properties(pcsc PROPERTIES + IMPORTED_LOCATION "${PCSC_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${PCSC_INCLUDE_DIR}" + IMPORTED_SONAME "${PCSC_SO_NAME}" + DLOPEN_SONAME "${PCSC_SO_NAME}" + ) + endif(UNIX) + endif() +endif(PCSC_FOUND) diff --git a/cmakemodules/FindZLIB.cmake b/cmakemodules/FindZLIB.cmake new file mode 100644 index 0000000..cf160a1 --- /dev/null +++ b/cmakemodules/FindZLIB.cmake @@ -0,0 +1,130 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +include (CheckIncludeFiles) +include (CheckLibraryExists) +include (CheckSymbolExists) + +find_path(ZLIB_INCLUDE_DIR zlib.h + HINTS + $ENV{ZLIB_ROOT}/include + $ENV{ZLIB_ROOT}/include/zLib + ${BZ2_ROOT}/include + ${BZ2_ROOT}/include/zLib +) +mark_as_advanced(ZLIB_INCLUDE_DIR) + +# if (NOT ZLIB_LIBRARIES) + find_library(ZLIB_SHARED_LIBRARY_RELEASE NAMES z zdll HINTS $ENV{ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_SHARED_LIBRARY_RELWITHDEBINFO NAMES z zdll HINTS $ENV{ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_STATIC_LIBRARY_RELEASE NAMES zlib HINTS $ENV{ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_STATIC_LIBRARY_RELWITHDEBINFO NAMES zlib HINTS $ENV{ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_SHARED_LIBRARY_DEBUG NAMES zd zdlld HINTS $ENV{ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_STATIC_LIBRARY_DEBUG NAMES zlibd HINTS $ENV{ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/lib${TS_LIB_DIR_SUFFIX}) + IF(WIN32) + SET(_tmp ${CMAKE_FIND_LIBRARY_SUFFIXES}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(ZLIB_SHARED_SO_RELEASE NAMES zdll1 HINTS $ENV{ZLIB_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_SHARED_SO_RELWITHDEBINFO NAMES zdll1 HINTS $ENV{ZLIB_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + find_library(ZLIB_SHARED_SO_DEBUG NAMES zdlld1 HINTS $ENV{ZLIB_ROOT}/bin${TS_LIB_DIR_SUFFIX} ${ZLIB_ROOT}/bin${TS_LIB_DIR_SUFFIX}) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ${_tmp}) + endif(WIN32) +# endif () + +if(ZLIB_INCLUDE_DIR AND EXISTS "${ZLIB_INCLUDE_DIR}/zlib.h") + file(STRINGS "${ZLIB_INCLUDE_DIR}/zlib.h" ZLIB_H REGEX "^#define ZLIB_VERSION \"[^\"]*\"$") + + string(REGEX REPLACE "^.*ZLIB_VERSION \"([0-9]+).*$" "\\1" ZLIB_VERSION_MAJOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_MINOR "${ZLIB_H}") + string(REGEX REPLACE "^.*ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ZLIB_VERSION_PATCH "${ZLIB_H}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_MAJOR}.${ZLIB_VERSION_MINOR}.${ZLIB_VERSION_PATCH}") + + # only append a TWEAK version if it exists: + set(ZLIB_VERSION_TWEAK "") + if( "${ZLIB_H}" MATCHES "ZLIB_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+)") + set(ZLIB_VERSION_TWEAK "${CMAKE_MATCH_1}") + set(ZLIB_VERSION_STRING "${ZLIB_VERSION_STRING}.${ZLIB_VERSION_TWEAK}") + endif() + + set(ZLIB_MAJOR_VERSION "${ZLIB_VERSION_MAJOR}") + set(ZLIB_MINOR_VERSION "${ZLIB_VERSION_MINOR}") + set(ZLIB_PATCH_VERSION "${ZLIB_VERSION_PATCH}") +endif() + +# handle the QUIETLY and REQUIRED arguments and set BZip2_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +IF(WIN32) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB + REQUIRED_VARS ZLIB_SHARED_LIBRARY_RELEASE ZLIB_STATIC_LIBRARY_RELEASE ZLIB_SHARED_LIBRARY_DEBUG ZLIB_STATIC_LIBRARY_DEBUG ZLIB_INCLUDE_DIR + VERSION_VAR ZLIB_VERSION_STRING) +ELSE(WIN32) +set(ZLIB_SHARED_LIBRARY_DEBUG ${ZLIB_SHARED_LIBRARY_RELEASE}) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ZLIB + REQUIRED_VARS ZLIB_SHARED_LIBRARY_RELEASE ZLIB_INCLUDE_DIR + VERSION_VAR ZLIB_VERSION_STRING) +ENDIF(WIN32) + +if(ZLIB_FOUND) + set(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR}) + set(ZLIB_LIBRARIES ${ZLIB_LIBRARY}) + + if(NOT TARGET ZLIB) + if(WIN32) + add_library(ZLIB SHARED IMPORTED) + set_property(TARGET ZLIB PROPERTY IMPORTED_LOCATION_DEBUG "${ZLIB_SHARED_SO_DEBUG}") + set_property(TARGET ZLIB PROPERTY IMPORTED_LOCATION_RELEASE "${ZLIB_SHARED_SO_RELEASE}") + set_property(TARGET ZLIB PROPERTY IMPORTED_LOCATION_RELWITHDEBINFO "${ZLIB_SHARED_SO_RELWITHDEBINFO}") + set_property(TARGET ZLIB PROPERTY IMPORTED_IMPLIB_DEBUG "${ZLIB_SHARED_LIBRARY_DEBUG}") + set_property(TARGET ZLIB PROPERTY IMPORTED_IMPLIB_RELEASE "${ZLIB_SHARED_LIBRARY_RELEASE}") + set_property(TARGET ZLIB PROPERTY IMPORTED_IMPLIB_RELWITHDEBINFO "${ZLIB_SHARED_LIBRARY_RELWITHDEBINFO}") + set_property(TARGET ZLIB PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") + else(WIN32) + add_library(ZLIB SHARED IMPORTED) + set_target_properties(ZLIB PROPERTIES + IMPORTED_LOCATION_DEBUG "${ZLIB_SHARED_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${ZLIB_SHARED_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${ZLIB_SHARED_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIRS}") + endif(WIN32) + endif() + + if(NOT TARGET ZLIB_STATIC) + add_library(ZLIB_STATIC UNKNOWN IMPORTED) + set_target_properties(ZLIB_STATIC PROPERTIES + IMPORTED_LOCATION_DEBUG "${ZLIB_STATIC_LIBRARY_DEBUG}" + IMPORTED_LOCATION_RELEASE "${ZLIB_STATIC_LIBRARY_RELEASE}" + IMPORTED_LOCATION_RELWITHDEBINFO "${ZLIB_STATIC_LIBRARY_RELWITHDEBINFO}" + INTERFACE_INCLUDE_DIRECTORIES "${ZLIB_INCLUDE_DIR}") + endif() + +endif() + +mark_as_advanced(ZLIB_INCLUDE_DIR) diff --git a/cmakemodules/compiler_tecsec_darwin.cmake b/cmakemodules/compiler_tecsec_darwin.cmake new file mode 100644 index 0000000..8b8e06b --- /dev/null +++ b/cmakemodules/compiler_tecsec_darwin.cmake @@ -0,0 +1,59 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +add_definitions(-DMAC) + +# the following two lines are needed for spidermonkey +add_definitions(-DXP_UNIX) +#add_definitions(-DDARWIN) + +## CMAKE_OSX_ARCHITECTURES is a built-in variable that lets you list +## the chips that you want to compile for. If you list more than +## one value, you get a universal binary. Each listed value will be +## converted into a '-arch v' argument to GCC. This was useful when +## the choices when set to "i386;ppc", but not so much when set +## to "i386;x86_64". +## +## From what I can tell, when -arch is set we don't need -m32 or -m64. +## Warning: If you mix -m32, -m64 and one or more -arch arguments, +## you don't always get what you expect. (Use /usr/bin/file on a +## generated .o or exe to confirm.) +## +if(OSX_64BIT) + SET(CMAKE_OSX_ARCHITECTURES "i386;x86_64") +else() + SET(CMAKE_OSX_ARCHITECTURES "i386") +endif() + +## These are noise for now. Hide them from the basic display in the +## GUI tools. +mark_as_advanced(CMAKE_OSX_DEPLOYMENT_TARGET) +mark_as_advanced(CMAKE_OSX_SYSROOT) +mark_as_advanced(CMAKE_INSTALL_PREFIX) + diff --git a/cmakemodules/compiler_tecsec_gnucc.cmake b/cmakemodules/compiler_tecsec_gnucc.cmake new file mode 100644 index 0000000..bfe6666 --- /dev/null +++ b/cmakemodules/compiler_tecsec_gnucc.cmake @@ -0,0 +1,109 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +# TODO should we add -Wconversion to make this more like the MSFT compiler? +# TODO or -Wsign-conversion ? + +# TODO would -Wunreachable-code make this more like the MSFT compiler? + +# TODO how about -Wmissing-prototypes ?? this would make the compiler VERY +# TODO fussy, but it might catch some interesting problems + +# TODO I would love to add +# TODO -Wdisallowed-function-list=strcpy,sprintf,etc +# TODO but gcc on the Mac is at version 4.0 and this +# TODO option was added in some later version. + +execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion + OUTPUT_VARIABLE GCC_VERSION) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +if(TS_X_PLATFORM STREQUAL "x64") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64 -mssse3 -maes") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -mssse3 -maes") + set(LINK_FLAGS "${LINK_FLAGS} -m64") +elseif(TS_X_PLATFORM STREQUAL "x86") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -msse -msse3 -maes -march=i686") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 -msse -msse3 -maes -march=i686") + set(LINK_FLAGS "${LINK_FLAGS} -m32") +else() + error(Missing processor type) +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wdeclaration-after-statement --std=gnu89 -Wno-unused-parameter") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-invalid-offsetof") + +# the apple_unicode code violates the strict-aliasing rules +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-strict-aliasing") + +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsigned-char") + +# Add -Wunused when using gcc 4.6 so we get the same errors as when building +# with cdbs (Common Debian Build System) +if (GCC_VERSION VERSION_GREATER 4.6 OR GCC_VERSION VERSION_EQUAL 4.6) + #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -std=c++11") + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused -std=c++11 -fno-implicit-templates") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused -std=c++11") +else() + #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wunused -std=c++0x") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused -std=c++0x") +endif() + +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG -DDEBUG") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_RELEASE") +if(MINGW) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_RELEASE") +else(MINGW) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_DEBUG -DDEBUG -fPIC") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_RELEASE -fPIC") +endif(MINGW) + +OPTION(SG_GCOV "Compile everything with -fprofile-arcs -ftest-coverage for gcov" OFF) + +#if(SG_GCOV) +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") +# SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") +#endif() + +OPTION(SG_GPROF "Compile everything with -pg for gprof" OFF) + +#if(SG_GPROF) +# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg") +# SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg") +#endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${TS_CONFIG}}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${TS_CONFIG}}") +if(NOT MINGW) + LINK_LIBRARIES(pthread dl) +endif(NOT MINGW) + diff --git a/cmakemodules/compiler_tecsec_msvc.cmake b/cmakemodules/compiler_tecsec_msvc.cmake new file mode 100644 index 0000000..2379ba7 --- /dev/null +++ b/cmakemodules/compiler_tecsec_msvc.cmake @@ -0,0 +1,109 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +add_definitions(-DWINDOWS) +add_definitions(-DXP_WIN) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Zi -nologo -Gm- -Gd -fp:precise -Zc:wchar_t -Zc:forScope -Zm300 -EHa -bigobj ") +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -MDd -RTC1 -Od -GS -D_DEBUG") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -MD -Ox -Oi -Ot -GL -GS- -Gy -D_RELEASE") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -MD -Ox -Oi -Ot -GL -GS- -Gy -D_RELEASE") +set(CMAKE_C_FLAGS_DEBUGSTATIC "${CMAKE_C_FLAGS_DEBUGSTATIC} -MTd -RTC1 -Od -GS -D_DEBUG -D_STATIC_MSVCRT -D_STATIC_TSFRAMEWORK") +set(CMAKE_C_FLAGS_RELEASESTATIC "${CMAKE_C_FLAGS_RELEASESTATIC} -MT -Ox -Oi -Ot -GL -GS- -Gy -D_RELEASE -D_STATIC_MSVCRT -D_STATIC_TSFRAMEWORK") + +if(MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP8") +endif() + +# #IF(MSVC_IDE) +# #set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -W4 /Yu\"StdAfx.h\"") +# #ELSE() +set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}") +# set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -W4") +# #ENDIF() +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") +set(CMAKE_CXX_FLAGS_DEBUGSTATIC "${CMAKE_C_FLAGS_DEBUGSTATIC}") +set(CMAKE_CXX_FLAGS_RELEASESTATIC "${CMAKE_C_FLAGS_RELEASESTATIC}") + +set(CMAKE_EXE_LINKER_FLAGS "/ALLOWISOLATION ") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO /LTCG /MACHINE:${TS_X_PLATFORM} /RELEASE") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO /LTCG /MACHINE:${TS_X_PLATFORM} /DEBUG") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO /MACHINE:${TS_X_PLATFORM} /DEBUG") +set(CMAKE_EXE_LINKER_FLAGS_RELEASESTATIC "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO /LTCG /MACHINE:${TS_X_PLATFORM} /RELEASE") +set(CMAKE_EXE_LINKER_FLAGS_DEBUGSTATIC "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO /MACHINE:${TS_X_PLATFORM} /DEBUG") + +set(CMAKE_SHARED_LINKER_FLAGS_RELEASESTATIC "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_DEBUGSTATIC "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}") + + + +set(CMAKE_MANAGED_CPP_V40_FLAGS "-Zi -nologo -W4 -EHa -fp:precise -Zc:wchar_t -Zc:forScope /clr /FU\"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0/Profile/Client/System.Data.dll\" /FU\"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0/Profile/Client/System.dll\" /FU\"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0/Profile/Client/System.Xml.dll\" ") +set(CMAKE_MANAGED_CPP_V40_FLAGS_RELEASE "/O2 /Oi /GL /MD /GS /Gy -D_RELEASE") +set(CMAKE_MANAGED_CPP_V40_FLAGS_DEBUG "/Od /MDd /GS -D_DEBUG") + +set(CMAKE_MANAGED_EXE_LINKER_FLAGS "/NOLOGO /ALLOWISOLATION /KEYFILE:\"${MANAGED_KEYFILE}\" /DELAYSIGN /NXCOMPAT /DYNAMICBASE /FIXED:NO /TLBID:1") +set(CMAKE_MANAGED_EXE_LINKER_FLAGS_RELEASE "/LTCG /MANIFEST /UACExecutionLevel:\"level='asInvoker'\" /UACUIAccess:\"uiAccess='false'\"") +set(CMAKE_MANAGED_EXE_LINKER_FLAGS_DEBUG "/DEBUG /NXCOMPAT /MANIFEST /UACExecutionLevel:\"level='asInvoker'\" /UACUIAccess:\"uiAccess='false'\" /ALLOWISOLATION:NO") + + +set(CMAKE_MANAGED_SHARED_LINKER_FLAGS "/NOLOGO /KEYFILE:\"${MANAGED_KEYFILE}\" /NXCOMPAT /DYNAMICBASE /FIXED:NO /TLBID:1 /LinkKeyFile:\"${MANAGED_KEYFILE}\"") +set(CMAKE_MANAGED_SHARED_LINKER_FLAGS_RELEASE "/MANIFEST /UACExecutionLevel:\"level='asInvoker'\" /UACUIAccess:\"uiAccess='false'\"") +set(CMAKE_MANAGED_SHARED_LINKER_FLAGS_DEBUG "/DEBUG /NXCOMPAT /MANIFEST /UACExecutionLevel:\"level='asInvoker'\" /UACUIAccess:\"uiAccess='false'\" /ASSEMBLYDEBUG") + + #/ManifestFile:"S:\devsup\Crypto_Unicode\obj\TecSec.Crypto.Loader\x64\Release\TecSec.Crypto.Loader.dll.intermediate.manifest" + +set(CMAKE_MANAGED_CPP_V45_FLAGS "-Zi -nologo -W4 -EHa -fp:precise -Zc:wchar_t -Zc:forScope /clr /FU\"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/System.Data.dll\" /FU\"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/System.dll\" /FU\"C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/System.Xml.dll\" ") +set(CMAKE_MANAGED_CPP_V45_FLAGS_RELEASE "/O2 /Oi /GL /MD /GS /Gy -D_RELEASE") +set(CMAKE_MANAGED_CPP_V45_FLAGS_DEBUG "/Od /MDd /GS") + + #if (CMAKE_BUILD_TYPE STREQUAL "Debug") +# SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:msvcrt.lib ") +# SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:msvcrt.lib ") +#endif() # (CMAKE_BUILD_TYPE STREQUAL "Debug") + +if (MACHINETYPE STREQUAL "x86") + set(VS_ANALYZE CACHE BOOL "Compile with /analyze. Available only on Windows with VS 2010 Premium and for 32-bit builds.") + if (VS_ANALYZE) + add_definitions(-DCODE_ANALYSIS -analyze) + endif() +endif() + +set(SG_OS_LIBS rpcrt4.lib winmm.lib advapi32.lib wininet.lib shlwapi.lib) + +# set(COMPILE_DEFINITIONS_RELEASE "${COMPILE_DEFINITIONS_RELEASE};_RELEASE") +# STRING(REPLACE "_RELEASE" "" COMPILE_DEFINITIONS_RELEASESTATIC ${COMPILE_DEFINITIONS_RELEASE}) +# set(COMPILE_DEFINITIONS_RELEASESTATIC "${COMPILE_DEFINITIONS_RELEASESTATIC};_RELEASESTATIC") +# set(COMPILE_DEFINITIONS_DEBUGSTATIC "${COMPILE_DEFINITIONS_DEBUG};_DEBUGSTATIC") +# STRING(REPLACE "_RELEASE" "" COMPILE_DEFINITIONS_RELEASENONSXS ${COMPILE_DEFINITIONS_RELEASE}) +# set(COMPILE_DEFINITIONS_RELEASENONSXS "${COMPILE_DEFINITIONS_RELEASENONSXS};_RELEASENONSXS") + + + diff --git a/cmakemodules/compiler_tecsec_msvc.noWarnings.cmake b/cmakemodules/compiler_tecsec_msvc.noWarnings.cmake new file mode 100644 index 0000000..b98bd60 --- /dev/null +++ b/cmakemodules/compiler_tecsec_msvc.noWarnings.cmake @@ -0,0 +1,32 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -WX") +set(CMAKE_MANAGED_CPP_V40_FLAGS "${CMAKE_MANAGED_CPP_V40_FLAGS} -WX") +set(CMAKE_MANAGED_CPP_V45_FLAGS "${CMAKE_MANAGED_CPP_V45_FLAGS} -WX") diff --git a/cmakemodules/cotire.cmake b/cmakemodules/cotire.cmake new file mode 100644 index 0000000..d127f65 --- /dev/null +++ b/cmakemodules/cotire.cmake @@ -0,0 +1,3629 @@ +# - cotire (compile time reducer) +# +# See the cotire manual for usage hints. +# +#============================================================================= +# Copyright 2012-2014 Sascha Kratky +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +#============================================================================= + +if(__COTIRE_INCLUDED) + return() +endif() +set(__COTIRE_INCLUDED TRUE) + +# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode +# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(PUSH) +endif() +# we need the CMake variables CMAKE_SCRIPT_MODE_FILE and CMAKE_ARGV available since 2.8.5 +# we need APPEND_STRING option for set_property available since 2.8.6 +cmake_minimum_required(VERSION 2.8.6) +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(POP) +endif() + +if (NOT CMAKE_VERSION VERSION_LESS "3.1.0") + # include TARGET_OBJECTS expressions in a target's SOURCES property + cmake_policy(SET CMP0051 NEW) + # only interpret if() arguments as variables or keywords when unquoted + cmake_policy(SET CMP0054 NEW) +endif() + +set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") +set (COTIRE_CMAKE_MODULE_VERSION "1.6.9") + +include(CMakeParseArguments) +include(ProcessorCount) + +function (cotire_determine_compiler_version _language _versionPrefix) + if (NOT ${_versionPrefix}_VERSION) + # use CMake's predefined compiler version variable (available since CMake 2.8.8) + if (DEFINED CMAKE_${_language}_COMPILER_VERSION) + set (${_versionPrefix}_VERSION "${CMAKE_${_language}_COMPILER_VERSION}") + elseif (WIN32) + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) + execute_process ( + COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} + ERROR_VARIABLE _versionLine OUTPUT_QUIET TIMEOUT 10) + string (REGEX REPLACE ".*Version *([0-9]+(\\.[0-9]+)*).*" "\\1" ${_versionPrefix}_VERSION "${_versionLine}") + else() + # assume GCC like command line interface + string (STRIP "${CMAKE_${_language}_COMPILER_ARG1}" _compilerArg1) + execute_process ( + COMMAND ${CMAKE_${_language}_COMPILER} ${_compilerArg1} "-dumpversion" + OUTPUT_VARIABLE ${_versionPrefix}_VERSION + RESULT_VARIABLE _result + OUTPUT_STRIP_TRAILING_WHITESPACE TIMEOUT 10) + if (_result) + set (${_versionPrefix}_VERSION "") + endif() + endif() + if (${_versionPrefix}_VERSION) + set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" CACHE INTERNAL "${_language} compiler version") + endif() + set (${_versionPrefix}_VERSION "${${_versionPrefix}_VERSION}" PARENT_SCOPE) + if (COTIRE_DEBUG) + message (STATUS "${CMAKE_${_language}_COMPILER} version ${${_versionPrefix}_VERSION}") + endif() + endif() +endfunction() + +function (cotire_get_configuration_types _configsVar) + set (_configs "") + if (CMAKE_CONFIGURATION_TYPES) + list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) + endif() + if (CMAKE_BUILD_TYPE) + list (APPEND _configs "${CMAKE_BUILD_TYPE}") + endif() + if (_configs) + list (REMOVE_DUPLICATES _configs) + set (${_configsVar} ${_configs} PARENT_SCOPE) + else() + set (${_configsVar} "None" PARENT_SCOPE) + endif() +endfunction() + +function (cotire_get_source_file_extension _sourceFile _extVar) + # get_filename_component returns extension from first occurrence of . in file name + # this function computes the extension from last occurrence of . in file name + string (FIND "${_sourceFile}" "." _index REVERSE) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) + else() + set (_sourceExt "") + endif() + set (${_extVar} "${_sourceExt}" PARENT_SCOPE) +endfunction() + +macro (cotire_check_is_path_relative_to _path _isRelativeVar) + set (${_isRelativeVar} FALSE) + if (IS_ABSOLUTE "${_path}") + foreach (_dir ${ARGN}) + file (RELATIVE_PATH _relPath "${_dir}" "${_path}") + if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) + set (${_isRelativeVar} TRUE) + break() + endif() + endforeach() + endif() +endmacro() + +function (cotire_filter_language_source_files _language _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) + set (_sourceFiles "") + set (_excludedSourceFiles "") + set (_cotiredSourceFiles "") + if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") + else() + set (_languageExtensions "") + endif() + if (CMAKE_${_language}_IGNORE_EXTENSIONS) + set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") + else() + set (_ignoreExtensions "") + endif() + if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) + set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") + else() + set (_excludeExtensions "") + endif() + if (COTIRE_DEBUG) + message (STATUS "${_language} source file extensions: ${_languageExtensions}") + message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") + message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") + endif() + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_allSourceFiles ${ARGN}) + else() + # as of CMake 3.1 target sources may contain generator expressions + # since we cannot obtain required property information about source files added + # through generator expressions at configure time, we filter them out + string (GENEX_STRIP "${ARGN}" _allSourceFiles) + endif() + foreach (_sourceFile ${_allSourceFiles}) + get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) + get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) + get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) + get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) + set (_sourceIsFiltered FALSE) + if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) + cotire_get_source_file_extension("${_sourceFile}" _sourceExt) + if (_sourceExt) + list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) + if (_ignoreIndex LESS 0) + list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) + if (_excludeIndex GREATER -1) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) + if (_sourceIndex GREATER -1) + set (_sourceIsFiltered TRUE) + elseif ("${_sourceLanguage}" STREQUAL "${_language}") + # add to excluded sources, if file is not ignored and has correct language without having the correct extension + list (APPEND _excludedSourceFiles "${_sourceFile}") + endif() + endif() + endif() + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_sourceFile} filtered=${_sourceIsFiltered} language=${_sourceLanguage} header=${_sourceIsHeaderOnly}") + endif() + if (_sourceIsFiltered) + get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) + get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) + if (COTIRE_DEBUG) + message (STATUS "${_sourceFile} excluded=${_sourceIsExcluded} cotired=${_sourceIsCotired} compileFlags=${_sourceCompileFlags}") + endif() + if (_sourceIsCotired) + list (APPEND _cotiredSourceFiles "${_sourceFile}") + elseif (_sourceIsExcluded OR _sourceCompileFlags) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _sourceFiles "${_sourceFile}") + endif() + endif() + endforeach() + if (COTIRE_DEBUG) + message (STATUS "All: ${ARGN}") + message (STATUS "${_language}: ${_sourceFiles}") + message (STATUS "Excluded: ${_excludedSourceFiles}") + message (STATUS "Cotired: ${_cotiredSourceFiles}") + endif() + set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) + set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) + set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (NOT _propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_file_property_values _valuesVar _property) + set (_values "") + foreach (_sourceFile ${ARGN}) + get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) + if (_propertyValue) + list (APPEND _values "${_propertyValue}") + endif() + endforeach() + set (${_valuesVar} ${_values} PARENT_SCOPE) +endfunction() + +function (cotire_resolve_config_properites _configurations _propertiesVar) + set (_properties "") + foreach (_property ${ARGN}) + if ("${_property}" MATCHES "") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + string (REPLACE "" "${_upperConfig}" _configProperty "${_property}") + list (APPEND _properties ${_configProperty}) + endforeach() + else() + list (APPEND _properties ${_property}) + endif() + endforeach() + set (${_propertiesVar} ${_properties} PARENT_SCOPE) +endfunction() + +function (cotire_copy_set_properites _configurations _type _source _target) + cotire_resolve_config_properites("${_configurations}" _properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) + set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") + endif() + endforeach() +endfunction() + +function (cotire_get_target_link_libraries_for_usage_requirements _target _targetLinkLibrariesVar) + set (_targetLinkLibraries "") + get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) + while (_librariesToProcess) + # remove from head + list (GET _librariesToProcess 0 _library) + list (REMOVE_AT _librariesToProcess 0) + list (FIND _targetLinkLibraries ${_library} _index) + if (_index LESS 0) + list (APPEND _targetLinkLibraries ${_library}) + # process transitive libraries + if (TARGET ${_library}) + get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) + if (_libraries) + list (APPEND _librariesToProcess ${_libraries}) + endif() + endif() + endif() + endwhile() + set (${_targetLinkLibrariesVar} ${_targetLinkLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + set (_flagPrefix "[/-]") + else() + set (_flagPrefix "--?") + endif() + set (_optionFlag "") + set (_matchedOptions "") + set (_unmatchedOptions "") + foreach (_compileFlag ${ARGN}) + if (_compileFlag) + if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") + # option with separate argument + list (APPEND _matchedOptions "${_compileFlag}") + set (_optionFlag "") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") + # remember option + set (_optionFlag "${CMAKE_MATCH_2}") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") + # option with joined argument + list (APPEND _matchedOptions "${CMAKE_MATCH_3}") + set (_optionFlag "") + else() + # flush remembered option + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + set (_optionFlag "") + endif() + # add to unfiltered options + list (APPEND _unmatchedOptions "${_compileFlag}") + endif() + endif() + endforeach() + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + endif() + if (COTIRE_DEBUG) + message (STATUS "Filter ${_flagFilter}") + if (_matchedOptions) + message (STATUS "Matched ${_matchedOptions}") + endif() + if (_unmatchedOptions) + message (STATUS "Unmatched ${_unmatchedOptions}") + endif() + endif() + set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) + set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_flags _config _language _directory _target _flagsVar) + string (TOUPPER "${_config}" _upperConfig) + # collect options from CMake language variables + set (_compileFlags "") + if (CMAKE_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") + endif() + if (CMAKE_${_language}_FLAGS_${_upperConfig}) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") + endif() + if (_target) + # add option from CMake target type variable + get_target_property(_targetType ${_target} TYPE) + if (POLICY CMP0018) + # handle POSITION_INDEPENDENT_CODE property introduced with CMake 2.8.9 if policy CMP0018 is turned on + cmake_policy(GET CMP0018 _PIC_Policy) + else() + # default to old behavior + set (_PIC_Policy "OLD") + endif() + if (COTIRE_DEBUG) + message(STATUS "CMP0018=${_PIC_Policy}") + endif() + if (_PIC_Policy STREQUAL "NEW") + # NEW behavior: honor the POSITION_INDEPENDENT_CODE target property + get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) + if (_targetPIC) + if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") + elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") + endif() + endif() + else() + # OLD behavior or policy not set: use the value of CMAKE_SHARED_LIBRARY__FLAGS + if (_targetType STREQUAL "MODULE_LIBRARY") + # flags variable for module library uses different name SHARED_MODULE + # (e.g., CMAKE_SHARED_MODULE_C_FLAGS) + set (_targetType SHARED_MODULE) + endif() + if (CMAKE_${_targetType}_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_targetType}_${_language}_FLAGS}") + endif() + endif() + endif() + if (_directory) + # add_definitions may have been used to add flags to the compiler command + get_directory_property(_dirDefinitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS) + if (_dirDefinitions) + foreach(_define ${_dirDefinitions}) + set (_compileFlags "${_compileFlags} -D${_define}") + endforeach(_define) + + endif() + endif() + if (_target) + # add target compile options + get_target_property(_targetflags ${_target} COMPILE_FLAGS) + if (_targetflags) + set (_compileFlags "${_compileFlags} ${_targetflags}") + endif() + get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) + if (_targetOptions) + set (_compileFlags "${_compileFlags} ${_targetOptions}") + endif() + # interface compile options from linked library targets + cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) + foreach (_library ${_linkLibraries}) + if (TARGET ${_library}) + get_target_property(_targetOptions ${_library} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + set (_compileFlags "${_compileFlags} ${_targetOptions}") + endif() + endif() + endforeach() + endif() + if (UNIX) + separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") + elseif(WIN32) + separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") + else() + separate_arguments(_compileFlags) + endif() + # platform specific flags + if (APPLE) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) + if (NOT _architectures) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES) + endif() + if (_architectures) + foreach (_arch ${_architectures}) + list (APPEND _compileFlags "-arch" "${_arch}") + endforeach() + endif() + if (CMAKE_OSX_SYSROOT) + if (CMAKE_${_language}_SYSROOT_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") + else() + list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") + endif() + endif() + if (CMAKE_OSX_DEPLOYMENT_TARGET) + if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + else() + list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() + endif() + endif() + if (COTIRE_DEBUG AND _compileFlags) + message (STATUS "Target ${_target} compile flags ${_compileFlags}") + endif() + set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_include_directories _config _language _targetSourceDir _targetBinaryDir _target _includeDirsVar _systemIncludeDirsVar) + set (_includeDirs "") + set (_systemIncludeDirs "") + # default include dirs + if (CMAKE_INCLUDE_CURRENT_DIR) + list (APPEND _includeDirs "${_targetBinaryDir}") + list (APPEND _includeDirs "${_targetSourceDir}") + endif() + # parse additional include directories from target compile flags + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "I" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _includeDirs ${_dirs}) + endif() + # target include directories + get_directory_property(_dirs DIRECTORY "${_targetSourceDir}" INCLUDE_DIRECTORIES) + if (_target) + get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + # interface include directories from linked library targets + cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) + foreach (_library ${_linkLibraries}) + if (TARGET ${_library}) + get_target_property(_targetDirs ${_library} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_library} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endif() + endforeach() + endif() + if (dirs) + list (REMOVE_DUPLICATES _dirs) + endif() + list (LENGTH _includeDirs _projectInsertIndex) + foreach (_dir ${_dirs}) + if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) + cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") + if (_isRelative) + list (LENGTH _includeDirs _len) + if (_len EQUAL _projectInsertIndex) + list (APPEND _includeDirs "${_dir}") + else() + list (INSERT _includeDirs _projectInsertIndex "${_dir}") + endif() + math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") + else() + list (APPEND _includeDirs "${_dir}") + endif() + else() + list (APPEND _includeDirs "${_dir}") + endif() + endforeach() + list (REMOVE_DUPLICATES _includeDirs) + list (REMOVE_DUPLICATES _systemIncludeDirs) + if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) + list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) + endif() + if (COTIRE_DEBUG AND _includeDirs) + message (STATUS "Target ${_target} include dirs ${_includeDirs}") + endif() + set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) + if (COTIRE_DEBUG AND _systemIncludeDirs) + message (STATUS "Target ${_target} system include dirs ${_systemIncludeDirs}") + endif() + set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) +endfunction() + +macro (cotire_make_C_identifier _identifierVar _str) + if (CMAKE_VERSION VERSION_LESS "2.8.12") + # mimic CMake SystemTools::MakeCindentifier behavior + if ("${_str}" MATCHES "^[0-9].+$") + set (_str "_${str}") + endif() + string (REGEX REPLACE "[^a-zA-Z0-9]" "_" ${_identifierVar} "${_str}") + else() + string (MAKE_C_IDENTIFIER "${_str}" "${_identifierVar}") + endif() +endmacro() + +function (cotire_get_target_export_symbol _target _exportSymbolVar) + set (_exportSymbol "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_enableExports ${_target} ENABLE_EXPORTS) + if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR + (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) + get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) + if (NOT _exportSymbol) + set (_exportSymbol "${_target}_EXPORTS") + endif() + cotire_make_C_identifier(_exportSymbol "${_exportSymbol}") + endif() + set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_definitions _config _language _directory _target _definitionsVar) + string (TOUPPER "${_config}" _upperConfig) + set (_configDefinitions "") + # CMAKE_INTDIR for multi-configuration build systems + if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") + endif() + # target export define symbol + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + list (APPEND _configDefinitions "${_defineSymbol}") + endif() + # directory compile definitions + get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_directory_property(_definitions DIRECTORY "${_directory}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # target compile definitions + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # interface compile definitions from linked library targets + cotire_get_target_link_libraries_for_usage_requirements(${_target} _linkLibraries) + foreach (_library ${_linkLibraries}) + if (TARGET ${_library}) + get_target_property(_definitions ${_library} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + endif() + endforeach() + # parse additional compile definitions from target compile flags + # and don't look at directory compile definitions, which we already handled + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + list (REMOVE_DUPLICATES _configDefinitions) + if (COTIRE_DEBUG AND _configDefinitions) + message (STATUS "Target ${_target} compile definitions ${_configDefinitions}") + endif() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compiler_flags _config _language _directory _target _compilerFlagsVar) + # parse target compile flags omitting compile definitions and include directives + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_directory}" "${_target}" _targetFlags) + set (_compilerFlags "") + cotire_filter_compile_flags("${_language}" "[ID]" _ignore _compilerFlags ${_targetFlags}) + if (COTIRE_DEBUG AND _compilerFlags) + message (STATUS "Target ${_target} compiler flags ${_compilerFlags}") + endif() + set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) +endfunction() + +function (cotire_add_sys_root_paths _pathsVar) + if (APPLE) + if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) + foreach (_path IN LISTS ${_pathsVar}) + if (IS_ABSOLUTE "${_path}") + get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) + if (EXISTS "${_path}") + list (APPEND ${_pathsVar} "${_path}") + endif() + endif() + endforeach() + endif() + endif() + set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) + if (COTIRE_DEBUG) + message (STATUS "${_pathsVar}=${${_pathsVar}}") + endif() +endfunction() + +function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) + set (_extraProperties ${ARGN}) + set (_result "") + if (_extraProperties) + list (FIND _extraProperties "${_sourceFile}" _index) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + list (LENGTH _extraProperties _len) + math (EXPR _len "${_len} - 1") + foreach (_index RANGE ${_index} ${_len}) + list (GET _extraProperties ${_index} _value) + if (_value MATCHES "${_pattern}") + list (APPEND _result "${_value}") + else() + break() + endif() + endforeach() + endif() + endif() + set (${_resultVar} ${_result} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) + set (_compileDefinitions "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + string (TOUPPER "${_config}" _upperConfig) + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + if (COTIRE_DEBUG AND _compileDefinitions) + message (STATUS "Source ${_sourceFile} compile definitions ${_compileDefinitions}") + endif() + set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) + set (_configDefinitions "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) + if (_sourceDefinitions) + list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") + endif() + endforeach() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) + set (_sourceUndefs "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + get_source_file_property(_undefs "${_sourceFile}" ${_property}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + if (COTIRE_DEBUG AND _sourceUndefs) + message (STATUS "Source ${_sourceFile} ${_property} undefs ${_sourceUndefs}") + endif() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_undefs _property _sourceUndefsVar) + set (_sourceUndefs "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) + if (_undefs) + list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") + endif() + endforeach() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +macro (cotire_set_cmd_to_prologue _cmdVar) + set (${_cmdVar} "${CMAKE_COMMAND}") + if (COTIRE_DEBUG) + list (APPEND ${_cmdVar} "--warn-uninitialized") + endif() + list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") + if (COTIRE_VERBOSE) + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") + elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") + endif() +endmacro() + +function (cotire_init_compile_cmd _cmdVar _language _compilerExe _compilerArg1) + if (NOT _compilerExe) + set (_compilerExe "${CMAKE_${_language}_COMPILER}") + endif() + if (NOT _compilerArg1) + set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) + endif() + string (STRIP "${_compilerArg1}" _compilerArg1) + set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) +endfunction() + +macro (cotire_add_definitions_to_cmd _cmdVar _language) + foreach (_definition ${ARGN}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + list (APPEND ${_cmdVar} "/D${_definition}") + else() + list (APPEND ${_cmdVar} "-D${_definition}") + endif() + endforeach() +endmacro() + +macro (cotire_add_includes_to_cmd _cmdVar _language _includeSystemFlag _includesVar _systemIncludesVar) + foreach (_include ${${_includesVar}}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + file (TO_NATIVE_PATH "${_include}" _include) + list (APPEND ${_cmdVar} "/I${_include}") + else() + list (FIND ${_systemIncludesVar} ${_include} _index) + if(_index GREATER -1 AND NOT "${_includeSystemFlag}" STREQUAL "") + list (APPEND ${_cmdVar} "${_includeSystemFlag}${_include}") + else() + list (APPEND ${_cmdVar} "-I${_include}") + endif() + endif() + endforeach() +endmacro() + +macro (cotire_add_frameworks_to_cmd _cmdVar _language) + if (APPLE) + set (_frameWorkDirs "") + foreach (_include ${ARGN}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameWorkDir "${_include}" PATH) + list (APPEND _frameWorkDirs "${_frameWorkDir}") + endif() + endforeach() + if (_frameWorkDirs) + list (REMOVE_DUPLICATES _frameWorkDirs) + foreach (_frameWorkDir ${_frameWorkDirs}) + list (APPEND ${_cmdVar} "-F${_frameWorkDir}") + endforeach() + endif() + endif() +endmacro() + +macro (cotire_add_compile_flags_to_cmd _cmdVar) + foreach (_flag ${ARGN}) + list (APPEND ${_cmdVar} "${_flag}") + endforeach() +endmacro() + +function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + set (_triggerFile "") + foreach (_dependencyFile ${ARGN}) + if (EXISTS "${_dependencyFile}" AND "${_dependencyFile}" IS_NEWER_THAN "${_file}") + set (_triggerFile "${_dependencyFile}") + break() + endif() + endforeach() + get_filename_component(_fileName "${_file}" NAME) + if (EXISTS "${_file}") + if (_triggerFile) + if (COTIRE_VERBOSE) + message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") + endif() + else() + if (COTIRE_VERBOSE) + message (STATUS "${_fileName} is up-to-date.") + endif() + set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) + endif() + else() + if (COTIRE_VERBOSE) + message (STATUS "${_fileName} does not exist yet.") + endif() + endif() +endfunction() + +macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) + set (${_relPathVar} "") + foreach (_includeDir ${_includeDirs}) + if (IS_DIRECTORY "${_includeDir}") + file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") + if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") + string (LENGTH "${${_relPathVar}}" _closestLen) + string (LENGTH "${_relPath}" _relLen) + if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) + set (${_relPathVar} "${_relPath}") + endif() + endif() + elseif ("${_includeDir}" STREQUAL "${_headerFile}") + # if path matches exactly, return short non-empty string + set (${_relPathVar} "1") + break() + endif() + endforeach() +endmacro() + +macro (cotire_check_header_file_location _headerFile _insideIncudeDirs _outsideIncudeDirs _headerIsInside) + # check header path against ignored and honored include directories + cotire_find_closest_relative_path("${_headerFile}" "${_insideIncudeDirs}" _insideRelPath) + if (_insideRelPath) + # header is inside, but could be become outside if there is a shorter outside match + cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncudeDirs}" _outsideRelPath) + if (_outsideRelPath) + string (LENGTH "${_insideRelPath}" _insideRelPathLen) + string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) + if (_outsideRelPathLen LESS _insideRelPathLen) + set (${_headerIsInside} FALSE) + else() + set (${_headerIsInside} TRUE) + endif() + else() + set (${_headerIsInside} TRUE) + endif() + else() + # header is outside + set (${_headerIsInside} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) + if (NOT EXISTS "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif (IS_DIRECTORY "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") + # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path + # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation + # with the error message "error: no include path in which to search for header.h" + set (${_headerIsIgnoredVar} TRUE) + else() + set (${_headerIsIgnoredVar} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) + # check header file extension + cotire_get_source_file_extension("${_headerFile}" _headerFileExt) + set (${_headerIsIgnoredVar} FALSE) + if (_headerFileExt) + list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) + if (_index GREATER -1) + set (${_headerIsIgnoredVar} TRUE) + endif() + endif() +endmacro() + +macro (cotire_parse_line _line _headerFileVar _headerDepthVar) + if (MSVC) + # cl.exe /showIncludes output looks different depending on the language pack used, e.g.: + # English: "Note: including file: C:\directory\file" + # German: "Hinweis: Einlesen der Datei: C:\directory\file" + # We use a very general regular expression, relying on the presence of the : characters + if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") + # Visual Studio compiler output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + else() + if (_line MATCHES "^(\\.+) (.*)$") + # GCC like output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + if (IS_ABSOLUTE "${CMAKE_MATCH_2}") + set (${_headerFileVar} "${CMAKE_MATCH_2}") + else() + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) + endif() + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + endif() +endmacro() + +function (cotire_parse_includes _language _scanOutput _ignoredIncudeDirs _honoredIncudeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) + if (WIN32) + # prevent CMake macro invocation errors due to backslash characters in Windows paths + string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") + endif() + # canonize slashes + string (REPLACE "//" "/" _scanOutput "${_scanOutput}") + # prevent semicolon from being interpreted as a line separator + string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") + # then separate lines + string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") + list (LENGTH _scanOutput _len) + # remove duplicate lines to speed up parsing + list (REMOVE_DUPLICATES _scanOutput) + list (LENGTH _scanOutput _uniqueLen) + if (COTIRE_VERBOSE OR COTIRE_DEBUG) + message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") + if (_ignoredExtensions) + message (STATUS "Ignored extensions: ${_ignoredExtensions}") + endif() + if (_ignoredIncudeDirs) + message (STATUS "Ignored paths: ${_ignoredIncudeDirs}") + endif() + if (_honoredIncudeDirs) + message (STATUS "Included paths: ${_honoredIncudeDirs}") + endif() + endif() + set (_sourceFiles ${ARGN}) + set (_selectedIncludes "") + set (_unparsedLines "") + # stack keeps track of inside/outside project status of processed header files + set (_headerIsInsideStack "") + foreach (_line IN LISTS _scanOutput) + if (_line) + cotire_parse_line("${_line}" _headerFile _headerDepth) + if (_headerFile) + cotire_check_header_file_location("${_headerFile}" "${_ignoredIncudeDirs}" "${_honoredIncudeDirs}" _headerIsInside) + if (COTIRE_DEBUG) + message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") + endif() + # update stack + list (LENGTH _headerIsInsideStack _stackLen) + if (_headerDepth GREATER _stackLen) + math (EXPR _stackLen "${_stackLen} + 1") + foreach (_index RANGE ${_stackLen} ${_headerDepth}) + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endforeach() + else() + foreach (_index RANGE ${_headerDepth} ${_stackLen}) + list (REMOVE_AT _headerIsInsideStack -1) + endforeach() + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerIsInsideStack}") + endif() + # header is a candidate if it is outside project + if (NOT _headerIsInside) + # get parent header file's inside/outside status + if (_headerDepth GREATER 1) + math (EXPR _index "${_headerDepth} - 2") + list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) + else() + set (_parentHeaderIsInside TRUE) + endif() + # select header file if parent header file is inside project + # (e.g., a project header file that includes a standard header file) + if (_parentHeaderIsInside) + cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) + if (NOT _headerIsIgnored) + cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) + if (NOT _headerIsIgnored) + list (APPEND _selectedIncludes "${_headerFile}") + else() + # fix header's inside status on stack, it is ignored by extension now + list (REMOVE_AT _headerIsInsideStack -1) + list (APPEND _headerIsInsideStack TRUE) + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") + endif() + endif() + endif() + else() + if (MSVC) + # for cl.exe do not keep unparsed lines which solely consist of a source file name + string (FIND "${_sourceFiles}" "${_line}" _index) + if (_index LESS 0) + list (APPEND _unparsedLines "${_line}") + endif() + else() + list (APPEND _unparsedLines "${_line}") + endif() + endif() + endif() + endforeach() + list (REMOVE_DUPLICATES _selectedIncludes) + set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) + set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) +endfunction() + +function (cotire_scan_includes _includesVar) + set(_options "") + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE UNPARSED_LINES) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + set (_cmd "${_option_COMPILER_EXECUTABLE}" ${_option_COMPILER_ARG1}) + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) + # only consider existing source files for scanning + set (_existingSourceFiles "") + foreach (_sourceFile ${_sourceFiles}) + if (EXISTS "${_sourceFile}") + list (APPEND _existingSourceFiles "${_sourceFile}") + endif() + endforeach() + if (NOT _existingSourceFiles) + set (${_includesVar} "" PARENT_SCOPE) + return() + endif() + list (APPEND _cmd ${_existingSourceFiles}) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + if (COTIRE_DEBUG) + message (STATUS "clearing VS_UNICODE_OUTPUT") + endif() + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process( + COMMAND ${_cmd} WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result OUTPUT_QUIET ERROR_VARIABLE _output) + if (_result) + message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") + endif() + cotire_parse_includes( + "${_option_LANGUAGE}" "${_output}" + "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" + "${_option_IGNORE_EXTENSIONS}" + _includes _unparsedLines + ${_sourceFiles}) + set (${_includesVar} ${_includes} PARENT_SCOPE) + if (_option_UNPARSED_LINES) + set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_append_undefs _contentsVar) + set (_undefs ${ARGN}) + if (_undefs) + list (REMOVE_DUPLICATES _undefs) + foreach (_definition ${_undefs}) + list (APPEND ${_contentsVar} "#undef ${_definition}") + endforeach() + endif() +endmacro() + +macro (cotire_comment_str _language _commentText _commentVar) + if ("${_language}" STREQUAL "CMAKE") + set (${_commentVar} "# ${_commentText}") + else() + set (${_commentVar} "/* ${_commentText} */") + endif() +endmacro() + +function (cotire_write_file _language _file _contents _force) + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) + cotire_comment_str("${_language}" "${_file}" _header2) + set (_contents "${_header1}\n${_header2}\n${_contents}") + if (COTIRE_DEBUG) + message (STATUS "${_contents}") + endif() + if (_force OR NOT EXISTS "${_file}") + file (WRITE "${_file}" "${_contents}") + else() + file (READ "${_file}" _oldContents) + if (NOT "${_oldContents}" STREQUAL "${_contents}") + file (WRITE "${_file}" "${_contents}") + else() + if (COTIRE_DEBUG) + message (STATUS "${_file} unchanged") + endif() + endif() + endif() +endfunction() + +function (cotire_generate_unity_source _unityFile) + set(_options "") + set(_oneValueArgs LANGUAGE) + set(_multiValueArgs + DEPENDS SOURCE_LOCATIONS SOURCES_COMPILE_DEFINITIONS + PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) + if (_unityFileIsUpToDate) + return() + endif() + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_PRE_UNDEFS) + set (_option_PRE_UNDEFS "") + endif() + if (NOT _option_SOURCES_PRE_UNDEFS) + set (_option_SOURCES_PRE_UNDEFS "") + endif() + if (NOT _option_POST_UNDEFS) + set (_option_POST_UNDEFS "") + endif() + if (NOT _option_SOURCES_POST_UNDEFS) + set (_option_SOURCES_POST_UNDEFS "") + endif() + set (_contents "") + if (_option_PROLOGUE) + list (APPEND _contents ${_option_PROLOGUE}) + endif() + if (_option_LANGUAGE AND _sourceFiles) + if ("${_option_LANGUAGE}" STREQUAL "CXX") + list (APPEND _contents "#ifdef __cplusplus") + elseif ("${_option_LANGUAGE}" STREQUAL "C") + list (APPEND _contents "#ifndef __cplusplus") + endif() + endif() + set (_compileUndefinitions "") + set (_index 0) + foreach (_sourceFile ${_sourceFiles}) + cotire_get_source_compile_definitions( + "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions + ${_option_SOURCES_COMPILE_DEFINITIONS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) + if (_option_PRE_UNDEFS) + list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) + endif() + if (_sourcePreUndefs) + list (APPEND _compileUndefinitions ${_sourcePreUndefs}) + endif() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_sourcePostUndefs) + list (APPEND _compileUndefinitions ${_sourcePostUndefs}) + endif() + if (_option_POST_UNDEFS) + list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) + endif() + foreach (_definition ${_compileDefinitions}) + if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") + list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") + list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") + else() + list (APPEND _contents "#define ${_definition}") + list (INSERT _compileUndefinitions 0 "${_definition}") + endif() + endforeach() + if (_option_SOURCE_LOCATIONS) + # use explicitly provided source file location + list (GET _option_SOURCE_LOCATIONS ${_index} _sourceFileLocation) + else() + # use absolute path as source file location + get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) + endif() + if (WIN32) + file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) + endif() + list (APPEND _contents "#include \"${_sourceFileLocation}\"") + math (EXPR _index "${_index} + 1") + endforeach() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_option_LANGUAGE AND _sourceFiles) + list (APPEND _contents "#endif") + endif() + if (_option_EPILOGUE) + list (APPEND _contents ${_option_EPILOGUE}) + endif() + list (APPEND _contents "") + string (REPLACE ";" "\n" _contents "${_contents}") + if (COTIRE_VERBOSE) + message ("${_contents}") + endif() + cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) +endfunction() + +function (cotire_generate_prefix_header _prefixFile) + set(_options "") + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG) + set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS + INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) + if (_prefixFileIsUpToDate) + set (_unparsedLinesFile "${_prefixFile}.log") + file (WRITE "${_unparsedLinesFile}" "") + return() + endif() + endif() + set (_prologue "") + set (_epilogue "") + if (_option_COMPILER_ID MATCHES "Clang") + set (_prologue "#pragma clang system_header") + elseif (_option_COMPILER_ID MATCHES "GNU") + set (_prologue "#pragma GCC system_header") + elseif (_option_COMPILER_ID MATCHES "MSVC") + set (_prologue "#pragma warning(push, 0)") + set (_epilogue "#pragma warning(pop)") + elseif (_option_COMPILER_ID MATCHES "Intel") + # Intel compiler requires hdrstop pragma to stop generating PCH file + set (_epilogue "#pragma hdrstop") + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + cotire_scan_includes(_selectedHeaders ${_sourceFiles} + LANGUAGE "${_option_LANGUAGE}" + COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" + COMPILER_ID "${_option_COMPILER_ID}" + COMPILER_VERSION "${_option_COMPILER_VERSION}" + COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} + COMPILE_FLAGS ${_option_COMPILE_FLAGS} + INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} + INCLUDE_SYSTEM_FLAG ${_option_INCLUDE_SYSTEM_FLAG} + SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} + IGNORE_PATH ${_option_IGNORE_PATH} + INCLUDE_PATH ${_option_INCLUDE_PATH} + IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} + UNPARSED_LINES _unparsedLines) + cotire_generate_unity_source("${_prefixFile}" + PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) + set (_unparsedLinesFile "${_prefixFile}.log") + if (_unparsedLines) + if (COTIRE_VERBOSE OR NOT _selectedHeaders) + list (LENGTH _unparsedLines _skippedLineCount) + file (RELATIVE_PATH _unparsedLinesFileRelPath "${CMAKE_BINARY_DIR}" "${_unparsedLinesFile}") + message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFileRelPath}") + endif() + string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") + endif() + file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}") +endfunction() + +function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + # cl.exe options used + # /nologo suppresses display of sign-on banner + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # /showIncludes list include files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /showIncludes") + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fdirectives-only do not expand macros, requires GCC >= 4.3 + if (_flags) + # append to list + list (APPEND _flags -H -E) + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + list (APPEND _flags "-fdirectives-only") + endif() + else() + # return as a flag string + set (_flags "-H -E") + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + set (_flags "${_flags} -fdirectives-only") + endif() + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -H print the name of each header file used + # -E invoke preprocessor + if (_flags) + # append to list + list (APPEND _flags -H -E) + else() + # return as a flag string + set (_flags "-H -E") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + # Windows Intel options used + # /nologo do not display compiler version information + # /QH display the include file order + # /EP preprocess to stdout, omitting #line directives + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /QH") + endif() + else() + # Linux / Mac OS X Intel options used + # -H print the name of each header file used + # -EP preprocess to stdout, omitting #line directives + # -Kc++ process all source or unrecognized file types as C++ source files + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags -H -EP) + else() + # return as a flag string + if ("${_language}" STREQUAL "CXX") + set (_flags "-Kc++ ") + endif() + set (_flags "${_flags}-H -EP") + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /Zs syntax check only + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + endif() + elseif (_compilerID MATCHES "GNU|Clang") + # GCC / Clang options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may + # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # Windows Intel options used + # /nologo do not display compiler version information + # /Yc create a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + # /Zs syntax check only + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-create name of the precompiled header (PCH) to create + # -Kc++ process all source or unrecognized file types as C++ source files + # -fsyntax-only check only for correct syntax + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + get_filename_component(_pchDir "${_pchFile}" PATH) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "-Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -include process include file as the first line of the primary source file + # -Winvalid-pch warns if precompiled header is found but cannot be used + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -include process include file as the first line of the primary source file + # -include-pch include precompiled header file + # -Qunused-arguments don't emit warning for unused driver arguments + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # Windows Intel options used + # /Yu use a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-use name of the precompiled header (PCH) to use + # -include process include file as the first line of the primary source file + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + get_filename_component(_pchDir "${_pchFile}" PATH) + get_filename_component(_pchName "${_pchFile}" NAME) + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "-Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) + set(_options "") + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ID COMPILER_VERSION INCLUDE_SYSTEM_FLAG LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" "${_option_INCLUDE_SYSTEM_FLAG}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_INCLUDE_DIRECTORIES}) + cotire_add_pch_compilation_flags( + "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + if (COTIRE_DEBUG) + message (STATUS "clearing VS_UNICODE_OUTPUT") + endif() + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result) + if (_result) + message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") + endif() +endfunction() + +function (cotire_check_precompiled_header_support _language _targetSourceDir _target _msgVar) + set (_unsupportedCompiler + "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # supported since Visual Studio C++ 6.0 + # and CMake does not support an earlier version + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC PCH support requires version >= 3.4 + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND + "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") + set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # all Clang versions have PCH support + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel PCH support requires version >= 8.0.0 + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + if ("${COTIRE_${_language}_COMPILER_VERSION}" MATCHES ".+" AND + "${COTIRE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") + set (${_msgVar} "${_unsupportedCompiler} version ${COTIRE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + else() + set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) + endif() + if (CMAKE_${_language}_COMPILER MATCHES "ccache") + if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros|pch_defines") + set (${_msgVar} + "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + endif() + if (APPLE) + # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) + cotire_get_configuration_types(_configs) + foreach (_config ${_configs}) + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_targetSourceDir}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) + list (LENGTH _architectures _numberOfArchitectures) + if (_numberOfArchitectures GREATER 1) + string (REPLACE ";" ", " _architectureStr "${_architectures}") + set (${_msgVar} + "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." + PARENT_SCOPE) + break() + endif() + endforeach() + endif() +endfunction() + +macro (cotire_get_intermediate_dir _cotireDir) + get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) +endmacro() + +macro (cotire_setup_file_extension_variables) + set (_unityFileExt_C ".c") + set (_unityFileExt_CXX ".cxx") + set (_prefixFileExt_C ".h") + set (_prefixFileExt_CXX ".hxx") + set (_prefixSourceFileExt_C ".c") + set (_prefixSourceFileExt_CXX ".cxx") +endmacro() + +function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") + cotire_get_intermediate_dir(_baseDir) + set (_unityFile "${_baseDir}/${_unityFileName}") + set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) + if (COTIRE_DEBUG) + message(STATUS "${_unityFile}") + endif() +endfunction() + +function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + cotire_get_intermediate_dir(_baseDir) + set (_startIndex 0) + set (_index 0) + set (_unityFiles "") + set (_sourceFiles ${ARGN}) + foreach (_sourceFile ${_sourceFiles}) + get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) + math (EXPR _unityFileCount "${_index} - ${_startIndex}") + if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) + if (_index GREATER 0) + # start new unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (_startIndex ${_index}) + endif() + math (EXPR _index "${_index} + 1") + endforeach() + list (LENGTH _sourceFiles _numberOfSources) + if (_startIndex EQUAL 0) + # there is only a single unity file + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) + elseif (_startIndex LESS _numberOfSources) + # end with final unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) + if (COTIRE_DEBUG) + message(STATUS "${_unityFiles}") + endif() +endfunction() + +function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_prefixFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") + string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") + set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) +endfunction() + +function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _prefixSourceFileExt_${_language}) + set (${_prefixSourceFileVar} "" PARENT_SCOPE) + return() + endif() + string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") + set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) + cotire_setup_file_extension_variables() + if (NOT _language) + set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") + elseif (DEFINED _prefixFileExt_${_language}) + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") + else() + set (_prefixFileBaseName "") + set (_prefixFileName "") + endif() + set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) + set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_path _language _target _prefixFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_prefixFileVar} "" PARENT_SCOPE) + if (_prefixFileName) + if (NOT _language) + set (_language "C") + endif() + if (MSVC OR CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel") + cotire_get_intermediate_dir(_baseDir) + set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (cotire_make_pch_file_path _language _targetSourceDir _target _pchFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_pchFileVar} "" PARENT_SCOPE) + if (_prefixFileBaseName AND _prefixFileName) + cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _msg) + if (NOT _msg) + if (XCODE) + # For Xcode, we completely hand off the compilation of the prefix header to the IDE + return() + endif() + cotire_get_intermediate_dir(_baseDir) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # MSVC uses the extension .pch added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel uses the extension .pchi added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + +function (cotire_select_unity_source_files _unityFile _sourcesVar) + set (_sourceFiles ${ARGN}) + if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") + set (_startIndex ${CMAKE_MATCH_1}) + set (_endIndex ${CMAKE_MATCH_2}) + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _startIndex LESS _numberOfSources) + math (EXPR _startIndex "${_numberOfSources} - 1") + endif() + if (NOT _endIndex LESS _numberOfSources) + math (EXPR _endIndex "${_numberOfSources} - 1") + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${_endIndex}) + list (GET _sourceFiles ${_index} _file) + list (APPEND _files "${_file}") + endforeach() + else() + set (_files ${_sourceFiles}) + endif() + set (${_sourcesVar} ${_files} PARENT_SCOPE) +endfunction() + +function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target's generated source files + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) + if (_generatedSources) + # but omit all generated source files that have the COTIRE_EXCLUDED property set to true + cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) + if (_excludedGeneratedSources) + list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) + endif() + # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly + cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) + if (_excludedNonDependencySources) + list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) + endif() + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} unity source depends on ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) + # depend on target source files marked with custom COTIRE_DEPENDENCY property + set (_dependencySources "") + cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GCC and clang raise a fatal error if a file is not found during preprocessing + # thus we depend on target's generated source files for prefix header generation + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${ARGN}) + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} prefix header DEPENDS ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_generate_target_script _language _configurations _targetSourceDir _targetBinaryDir _target _targetScriptVar _targetConfigScriptVar) + set (COTIRE_TARGET_SOURCES ${ARGN}) + cotire_get_source_file_property_values(COTIRE_TARGET_SOURCE_LOCATIONS LOCATION ${COTIRE_TARGET_SOURCES}) + cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${COTIRE_TARGET_SOURCES}) + cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${COTIRE_TARGET_SOURCES}) + # set up variables to be configured + set (COTIRE_TARGET_LANGUAGE "${_language}") + cotire_determine_compiler_version("${COTIRE_TARGET_LANGUAGE}" COTIRE_${_language}_COMPILER) + get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) + get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) + get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) + get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) + get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${COTIRE_TARGET_SOURCES}) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${COTIRE_TARGET_SOURCES}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" COTIRE_INCLUDE_SYSTEM_FLAG) + set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + cotire_get_target_include_directories( + "${_config}" "${_language}" "${_targetSourceDir}" "${_targetBinaryDir}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) + cotire_get_target_compile_definitions( + "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) + cotire_get_target_compiler_flags( + "${_config}" "${_language}" "${_targetSourceDir}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) + cotire_get_source_files_compile_definitions( + "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${COTIRE_TARGET_SOURCES}) + endforeach() + get_cmake_property(_vars VARIABLES) + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") + # remove COTIRE_VERBOSE which is passed as a CMake define on command line + list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) + set (_contents "") + set (_contentsHasGeneratorExpressions FALSE) + foreach (_var IN LISTS _matchVars ITEMS + XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES + CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + if (DEFINED ${_var}) + string (REPLACE "\"" "\\\"" _value "${${_var}}") + set (_contents "${_contents}set (${_var} \"${_value}\")\n") + if (NOT _contentsHasGeneratorExpressions) + if ("${_value}" MATCHES "\\$<.*>") + set (_contentsHasGeneratorExpressions TRUE) + endif() + endif() + endif() + endforeach() + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") + cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) + if (_contentsHasGeneratorExpressions) + # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time + if (NOT CMAKE_VERSION VERSION_LESS "2.8.12") + # the file(GENERATE ...) command requires cmake 2.8.12 or later + set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") + set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") + file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") + else() + message (WARNING "cotire: generator expression used in target ${_target}. This requires CMake 2.8.12 or later.") + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() + else() + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() + set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) + set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) +endfunction() + +function (cotire_setup_pch_file_compilation _language _target _targetSourceDir _targetScript _prefixFile _pchFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we attach the precompiled header compilation to the first source file + # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion + if (_sourceFiles) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + list (GET _sourceFiles 0 _hostFile) + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_pch_compilation_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) + set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") + # make first source file depend on prefix header + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") + # mark first source file as cotired to prevent it from being used in another cotired target + set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + # for makefile based generator, we add a custom command to precompile the prefix header + if (_targetScript) + cotire_set_cmd_to_prologue(_cmds) + list (GET _sourceFiles 0 _hostFile) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") + file (RELATIVE_PATH _pchFileRelPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + endif() + set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) + add_custom_command( + OUTPUT "${_pchFile}" + COMMAND ${_cmds} + DEPENDS "${_prefixFile}" + IMPLICIT_DEPENDS ${_language} "${_prefixFile}" + WORKING_DIRECTORY "${_targetSourceDir}" + COMMENT "Building ${_language} precompiled header ${_pchFileRelPath}" VERBATIM) + endif() + endif() +endfunction() + +function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we include the precompiled header in all but the first source file + # the first source file does the precompiled header compilation, see cotire_setup_pch_file_compilation + list (LENGTH _sourceFiles _numberOfSourceFiles) + if (_numberOfSourceFiles GREATER 1) + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + list (REMOVE_AT _sourceFiles 0) + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # make source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + if (NOT _wholeTarget) + # for makefile based generator, we force the inclusion of the prefix header for a subset + # of the source files, if this is a multi-language target or has excluded files + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + endif() + # make source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() +endfunction() + +function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) + set (_sourceFiles ${ARGN}) + # force the inclusion of the prefix header for the given source files + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + # make source files depend on prefix header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") +endfunction() + +function (cotire_get_first_set_property_value _propertyValueVar _type _object) + set (_properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) + return() + endif() + endforeach() + set (${_propertyValueVar} "" PARENT_SCOPE) +endfunction() + +function (cotire_setup_combine_command _language _sourceDir _targetScript _joinedFile _cmdsVar) + set (_files ${ARGN}) + set (_filesPaths "") + foreach (_file ${_files}) + if (IS_ABSOLUTE "${_file}") + set (_filePath "${_file}") + else() + get_filename_component(_filePath "${_sourceDir}/${_file}" ABSOLUTE) + endif() + file (RELATIVE_PATH _fileRelPath "${_sourceDir}" "${_filePath}") + if (NOT IS_ABSOLUTE "${_fileRelPath}" AND NOT "${_fileRelPath}" MATCHES "^\\.\\.") + list (APPEND _filesPaths "${_fileRelPath}") + else() + list (APPEND _filesPaths "${_filePath}") + endif() + endforeach() + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") + if (_targetScript) + list (APPEND _prefixCmd "${_targetScript}") + endif() + list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") + endif() + set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) + file (RELATIVE_PATH _joinedFileRelPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) + get_filename_component(_joinedFileExt "${_joinedFile}" EXT) + if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + set (_comment "Generating ${_language} unity source ${_joinedFileRelPath}") + elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") + if (_joinedFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_joinedFileRelPath}") + else() + set (_comment "Generating ${_language} prefix header ${_joinedFileRelPath}") + endif() + else() + set (_comment "Generating ${_joinedFileRelPath}") + endif() + add_custom_command( + OUTPUT "${_joinedFile}" + COMMAND ${_prefixCmd} + DEPENDS ${_files} + COMMENT "${_comment}" + WORKING_DIRECTORY "${_sourceDir}" VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_target_pch_usage _languages _targetSourceDir _target _wholeTarget) + if (XCODE) + # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers + # if necessary, we also generate a single prefix header which includes all language specific prefix headers + set (_prefixFiles "") + foreach (_language ${_languages}) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + list (APPEND _prefixFiles "${_prefixFile}") + endif() + endforeach() + set (_cmds ${ARGN}) + list (LENGTH _prefixFiles _numberOfPrefixFiles) + if (_numberOfPrefixFiles GREATER 1) + cotire_make_prefix_file_path("" ${_target} _prefixHeader) + cotire_setup_combine_command("" "${_targetSourceDir}" "" "${_prefixHeader}" _cmds ${_prefixFiles}) + else() + set (_prefixHeader "${_prefixFiles}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") + endif() + add_custom_command(TARGET "${_target}" + PRE_BUILD ${_cmds} + WORKING_DIRECTORY "${_targetSourceDir}" + COMMENT "Updating target ${_target} prefix headers" VERBATIM) + # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") + elseif ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + # for makefile based generator, we force inclusion of the prefix header for all target source files + # if this is a single-language target without any excluded files + if (_wholeTarget) + set (_language "${_languages}") + # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level + # see cotire_setup_pch_file_inclusion + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + set (_flags "") + cotire_determine_compiler_version("${_language}" COTIRE_${_language}_COMPILER) + get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${COTIRE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property(TARGET ${_target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + endif() + endif() + endif() + endif() +endfunction() + +function (cotire_setup_unity_generation_commands _language _targetSourceDir _target _targetScript _targetConfigScript _unityFiles _cmdsVar) + set (_dependencySources "") + cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) + foreach (_unityFile ${_unityFiles}) + file (RELATIVE_PATH _unityFileRelPath "${CMAKE_BINARY_DIR}" "${_unityFile}") + set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) + # set up compiled unity source dependencies via OBJECT_DEPENDS + # this ensures that missing source files are generated before the unity file is compiled + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") + endif() + if (_dependencySources) + # the OBJECT_DEPENDS property requires a list of full paths + set (_objectDependsPaths "") + foreach (_sourceFile ${_dependencySources}) + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND _objectDependsPaths "${_sourceLocation}") + endforeach() + set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) + endif() + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel + set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") + endif() + cotire_set_cmd_to_prologue(_unityCmd) + list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_unityCmdDepends "${_targetScript}") + else() + # CMake 3.1.0 supports generator expressions in arguments to DEPENDS + set (_unityCmdDepends "${_targetConfigScript}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") + endif() + add_custom_command( + OUTPUT "${_unityFile}" + COMMAND ${_unityCmd} + DEPENDS ${_unityCmdDepends} + COMMENT "Generating ${_language} unity source ${_unityFileRelPath}" + WORKING_DIRECTORY "${_targetSourceDir}" VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) + endforeach() + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles GREATER 1) + # create a joint unity file from all unity file segments + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetConfigScript}" "${_unityFile}" ${_cmdsVar} ${_unityFiles}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_command _language _target _targetSourceDir _targetScript _prefixFile _unityFile _cmdsVar) + set (_sourceFiles ${ARGN}) + set (_dependencySources "") + cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" "${_unityFile}") + set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources}") + endif() + file (RELATIVE_PATH _prefixFileRelPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") + get_filename_component(_prefixFileExt "${_prefixFile}" EXT) + if (_prefixFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_prefixFileRelPath}") + else() + set (_comment "Generating ${_language} prefix header ${_prefixFileRelPath}") + endif() + add_custom_command( + OUTPUT "${_prefixFile}" "${_prefixFile}.log" + COMMAND ${_prefixCmd} + DEPENDS "${_unityFile}" ${_dependencySources} + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_unity_command _language _target _targetSourceDir _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles GREATER 1) + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_prefix_generation_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" + "${_prefixSourceFile}" "${_unityFile}" ${_cmdsVar} ${_sourceFiles}) + else() + cotire_setup_prefix_generation_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetScript}" + "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + endif() + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" ${_cmdsVar} ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_provided_command _language _target _targetSourceDir _targetScript _prefixFile _cmdsVar) + set (_prefixHeaderFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + cotire_setup_combine_command(${_language} "${_targetSourceDir}" "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_init_cotire_target_properties _target) + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") + cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") + if (NOT _isRelative) + set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") + endif() + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) + if (NOT _isSet) + if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") + else() + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") + endif() + endif() +endfunction() + +function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + string (REPLACE ";" " " _languagesStr "${_languages}") + math (EXPR _numberOfExcludedFiles "${ARGC} - 4") + if (_numberOfExcludedFiles EQUAL 0) + set (_excludedStr "") + elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) + string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") + else() + set (_excludedStr "excluding ${_numberOfExcludedFiles} files") + endif() + set (_targetMsg "") + if (NOT _languages) + set (_targetMsg "Target ${_target} cannot be cotired.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH AND NOT _targetAddSCU) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") + endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetAddSCU) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") + endif() + else() + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired.") + endif() + endif() + set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) +endfunction() + +function (cotire_choose_target_languages _targetSourceDir _target _targetLanguagesVar _wholeTargetVar) + set (_languages ${ARGN}) + set (_allSourceFiles "") + set (_allExcludedSourceFiles "") + set (_allCotiredSourceFiles "") + set (_targetLanguages "") + set (_pchEligibleTargetLanguages "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + set (_disableMsg "") + foreach (_language ${_languages}) + get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) + get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) + if (_prefixHeader OR _unityBuildFile) + message (STATUS "cotire: target ${_target} has already been cotired.") + set (${_targetLanguagesVar} "" PARENT_SCOPE) + return() + endif() + if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$") + cotire_check_precompiled_header_support("${_language}" "${_targetSourceDir}" "${_target}" _disableMsg) + if (_disableMsg) + set (_targetUsePCH FALSE) + endif() + endif() + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _excludedSources OR _cotiredSources) + list (APPEND _targetLanguages ${_language}) + endif() + if (_sourceFiles) + list (APPEND _allSourceFiles ${_sourceFiles}) + endif() + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + list (APPEND _pchEligibleTargetLanguages ${_language}) + endif() + if (_excludedSources) + list (APPEND _allExcludedSourceFiles ${_excludedSources}) + endif() + if (_cotiredSources) + list (APPEND _allCotiredSourceFiles ${_cotiredSources}) + endif() + endforeach() + set (_targetMsgLevel STATUS) + if (NOT _targetLanguages) + string (REPLACE ";" " or " _languagesStr "${_languages}") + set (_disableMsg "No ${_languagesStr} source files.") + set (_targetUsePCH FALSE) + set (_targetAddSCU FALSE) + endif() + if (_targetUsePCH) + if (_allCotiredSourceFiles) + cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) + list (REMOVE_DUPLICATES _cotireTargets) + string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") + set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") + set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") + set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") + set (_targetMsgLevel SEND_ERROR) + set (_targetUsePCH FALSE) + elseif (NOT _pchEligibleTargetLanguages) + set (_disableMsg "Too few applicable sources.") + set (_targetUsePCH FALSE) + elseif (XCODE AND _allExcludedSourceFiles) + # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target + set (_disableMsg "Exclusion of source files not supported for generator Xcode.") + set (_targetUsePCH FALSE) + elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") + # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target + set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") + set (_targetUsePCH FALSE) + endif() + endif() + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) + cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) + if (_targetMsg) + if (NOT DEFINED COTIREMSG_${_target}) + set (COTIREMSG_${_target} "") + endif() + if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR + NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") + # cache message to avoid redundant messages on re-configure + set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") + message (${_targetMsgLevel} "${_targetMsg}") + endif() + endif() + list (LENGTH _targetLanguages _numberOfLanguages) + if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) + set (${_wholeTargetVar} FALSE PARENT_SCOPE) + else() + set (${_wholeTargetVar} TRUE PARENT_SCOPE) + endif() + set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) +endfunction() + +function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) + set (_sourceFiles ${ARGN}) + get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") + set (_numberOfThreads "${CMAKE_MATCH_2}") + if (NOT _numberOfThreads) + # use all available cores + ProcessorCount(_numberOfThreads) + endif() + list (LENGTH _sourceFiles _numberOfSources) + math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") + # a unity source segment must not contain less than COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES files + if (_maxIncludes LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_maxIncludes ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + endif() + elseif (NOT _maxIncludes MATCHES "[0-9]+") + set (_maxIncludes 0) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_target} unity source max includes = ${_maxIncludes}") + endif() + set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) +endfunction() + +function (cotire_process_target_language _language _configurations _targetSourceDir _targetBinaryDir _target _wholeTarget _cmdsVar) + set (${_cmdsVar} "" PARENT_SCOPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (NOT _sourceFiles AND NOT _cotiredSources) + return() + endif() + set (_cmds "") + # check for user provided unity source file list + get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) + if (NOT _unitySourceFiles) + set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) + endif() + cotire_generate_target_script( + ${_language} "${_configurations}" "${_targetSourceDir}" "${_targetBinaryDir}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) + cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) + cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) + if (NOT _unityFiles) + return() + endif() + cotire_setup_unity_generation_commands( + ${_language} "${_targetSourceDir}" ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) + if (_prefixFile) + # check for user provided prefix header files + get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + if (_prefixHeaderFiles) + cotire_setup_prefix_generation_from_provided_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + else() + cotire_setup_prefix_generation_from_unity_command( + ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + endif() + # check if selected language has enough sources at all + list (LENGTH _sourceFiles _numberOfSources) + if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_targetUsePCH FALSE) + else() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + endif() + if (_targetUsePCH) + cotire_make_pch_file_path(${_language} "${_targetSourceDir}" ${_target} _pchFile) + if (_pchFile) + cotire_setup_pch_file_compilation( + ${_language} ${_target} "${_targetSourceDir}" "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + cotire_setup_pch_file_inclusion( + ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + endif() + elseif (_prefixHeaderFiles) + # user provided prefix header must be included unconditionally + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) + endif() + endif() + # mark target as cotired for language + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") + if (_prefixFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") + if (_targetUsePCH AND _pchFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") + endif() + endif() + set (${_cmdsVar} ${_cmds} PARENT_SCOPE) +endfunction() + +function (cotire_setup_clean_target _target) + set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") + if (NOT TARGET "${_cleanTargetName}") + cotire_set_cmd_to_prologue(_cmds) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") + add_custom_target(${_cleanTargetName} COMMAND ${_cmds} WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up target ${_target} cotire generated files" VERBATIM) + cotire_init_target("${_cleanTargetName}") + endif() +endfunction() + +function (cotire_setup_pch_target _languages _configurations _target) + if ("${CMAKE_GENERATOR}" MATCHES "Makefiles|Ninja") + # for makefile based generators, we add a custom target to trigger the generation of the cotire related files + set (_dependsFiles "") + foreach (_language ${_languages}) + set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # Visual Studio and Intel only create precompiled header as a side effect + list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) + endif() + cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) + if (_dependsFile) + list (APPEND _dependsFiles "${_dependsFile}") + endif() + endforeach() + if (_dependsFiles) + set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") + add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) + cotire_init_target("${_pchTargetName}") + cotire_add_to_pch_all_target(${_pchTargetName}) + endif() + else() + # for other generators, we add the "clean all" target to clean up the precompiled header + cotire_setup_clean_all_target() + endif() +endfunction() + +function (cotire_setup_unity_build_target _languages _configurations _targetSourceDir _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (NOT _unityTargetName) + set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") + endif() + # determine unity target sub type + get_target_property(_targetType ${_target} TYPE) + if ("${_targetType}" STREQUAL "EXECUTABLE") + set (_unityTargetSubType "") + elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (_unityTargetSubType "${CMAKE_MATCH_1}") + else() + message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") + return() + endif() + # determine unity target sources + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_unityTargetSources ${_targetSourceFiles}) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + # remove source files that are included in the unity source + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _cotiredSources) + list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) + endif() + # if cotire is applied to a target which has not been added in the current source dir, + # non-existing files cannot be referenced from the unity build target (this is a CMake restriction) + if (NOT "${_targetSourceDir}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + set (_nonExistingFiles "") + foreach (_file ${_unityTargetSources}) + if (NOT EXISTS "${_file}") + list (APPEND _nonExistingFiles "${_file}") + endif() + endforeach() + if (_nonExistingFiles) + if (COTIRE_VERBOSE) + message (STATUS "removing non-existing ${_nonExistingFiles} from ${_unityTargetName}") + endif() + list (REMOVE_ITEM _unityTargetSources ${_nonExistingFiles}) + endif() + endif() + # add unity source files instead + list (APPEND _unityTargetSources ${_unityFiles}) + endif() + endforeach() + if (COTIRE_DEBUG) + message (STATUS "add ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") + endif() + # generate unity target + if ("${_targetType}" STREQUAL "EXECUTABLE") + add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + else() + add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + endif() + set (_outputDirProperties + ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ + LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ + RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) + # copy output location properties + if (COTIRE_UNITY_OUTPUT_DIRECTORY) + set (_setDefaultOutputDir TRUE) + if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + else() + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties}) + foreach (_property ${_properties}) + get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) + if (_outputDir) + get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") + set (_setDefaultOutputDir FALSE) + endif() + endforeach() + if (_setDefaultOutputDir) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + endif() + endif() + if (_setDefaultOutputDir) + set_target_properties(${_unityTargetName} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" + LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" + RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") + endif() + else() + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + endif() + # copy output name + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ + LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ + OUTPUT_NAME OUTPUT_NAME_ + RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ + PREFIX _POSTFIX SUFFIX) + # copy compile stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ + COMPILE_FLAGS COMPILE_OPTIONS + Fortran_FORMAT Fortran_MODULE_DIRECTORY + INCLUDE_DIRECTORIES + INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ + POSITION_INDEPENDENT_CODE + C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN) + # copy interface stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN COMPATIBLE_INTERFACE_STRING + INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_OPTIONS INTERFACE_INCLUDE_DIRECTORIES + INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + INTERFACE_AUTOUIC_OPTIONS) + # copy link stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH + LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED + LINK_FLAGS LINK_FLAGS_ + LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ + LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ + LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC + STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ + NO_SONAME SOVERSION VERSION) + # copy Qt stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + AUTOMOC AUTOMOC_MOC_OPTIONS AUTOUIC AUTOUIC_OPTIONS AUTORCC AUTORCC_OPTIONS + AUTOGEN_TARGET_DEPENDS) + # copy cmake stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) + # copy Apple platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUNDLE BUNDLE_EXTENSION FRAMEWORK INSTALL_NAME_DIR MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST + MACOSX_RPATH OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE) + # copy Windows platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + GNUtoMS + PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ + VS_DOTNET_REFERENCES VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE VS_KEYWORD + VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER + VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES WIN32_EXECUTABLE) + # use output name from original target + get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) + if (NOT _targetOutputName) + set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") + endif() + # use export symbol from original target + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") + if ("${_targetType}" STREQUAL "EXECUTABLE") + set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) + endif() + endif() + cotire_init_target(${_unityTargetName}) + cotire_add_to_unity_all_target(${_unityTargetName}) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") +endfunction(cotire_setup_unity_build_target) + +function (cotire_target _target) + set(_options "") + set(_oneValueArgs SOURCE_DIR BINARY_DIR) + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_SOURCE_DIR) + set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + if (NOT _option_BINARY_DIR) + set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + if (NOT _option_LANGUAGES) + get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + endif() + if (NOT _option_CONFIGURATIONS) + cotire_get_configuration_types(_option_CONFIGURATIONS) + endif() + # trivial checks + get_target_property(_imported ${_target} IMPORTED) + if (_imported) + message (WARNING "cotire: imported target ${_target} cannot be cotired.") + return() + endif() + # resolve alias + get_target_property(_aliasName ${_target} ALIASED_TARGET) + if (_aliasName) + if (COTIRE_DEBUG) + message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") + endif() + set (_target ${_aliasName}) + endif() + # check if target needs to be cotired for build type + # when using configuration types, the test is performed at build time + cotire_init_cotire_target_properties(${_target}) + if (NOT CMAKE_CONFIGURATION_TYPES) + if (CMAKE_BUILD_TYPE) + list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) + else() + list (FIND _option_CONFIGURATIONS "None" _index) + endif() + if (_index EQUAL -1) + if (COTIRE_DEBUG) + message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") + endif() + return() + endif() + endif() + # choose languages that apply to the target + cotire_choose_target_languages("${_option_SOURCE_DIR}" "${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) + if (NOT _targetLanguages) + return() + endif() + set (_cmds "") + foreach (_language ${_targetLanguages}) + cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" + "${_option_SOURCE_DIR}" "${_option_BINARY_DIR}" ${_target} ${_wholeTarget} _cmd) + if (_cmd) + list (APPEND _cmds ${_cmd}) + endif() + endforeach() + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + if (_targetAddSCU) + cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" "${_option_SOURCE_DIR}" ${_target}) + endif() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + if (_targetUsePCH) + cotire_setup_target_pch_usage("${_targetLanguages}" "${_option_SOURCE_DIR}" ${_target} ${_wholeTarget} ${_cmds}) + cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + endif() + get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) + if (_targetAddCleanTarget) + cotire_setup_clean_target(${_target}) + endif() +endfunction(cotire_target) + +function (cotire_map_libraries _strategy _mappedLibrariesVar) + set (_mappedLibraries "") + foreach (_library ${ARGN}) + if (TARGET "${_library}" AND "${_strategy}" MATCHES "COPY_UNITY") + # use target's corresponding unity target, if available + get_target_property(_libraryUnityTargetName ${_library} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + endforeach() + list (REMOVE_DUPLICATES _mappedLibraries) + set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_target_link_libraries _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_unityTargetName}") + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") + endif() + if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") + if (CMAKE_VERSION VERSION_LESS "2.8.11") + message (WARNING "cotire: unity target link strategy ${_linkLibrariesStrategy} requires CMake 2.8.11 or later. Defaulting to NONE for ${_target}.") + else() + set (_unityLinkLibraries "") + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + if (_linkLibraries) + list (APPEND _unityLinkLibraries ${_linkLibraries}) + endif() + get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) + if (_interfaceLinkLibraries) + list (APPEND _unityLinkLibraries ${_interfaceLinkLibraries}) + endif() + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_unityLinkLibraries}) + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} libraries: ${_unityLinkLibraries}") + endif() + if (_unityLinkLibraries) + target_link_libraries(${_unityTargetName} ${_unityLinkLibraries}) + endif() + endif() + endif() + endif() +endfunction(cotire_target_link_libraries) + +function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) + if (_targetName) + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") + else() + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") + endif() + # filter files in intermediate directory + set (_filesToRemove "") + foreach (_file ${_cotireFiles}) + get_filename_component(_dir "${_file}" PATH) + get_filename_component(_dirName "${_dir}" NAME) + if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") + list (APPEND _filesToRemove "${_file}") + endif() + endforeach() + if (_filesToRemove) + if (COTIRE_VERBOSE) + message (STATUS "removing ${_filesToRemove}") + endif() + file (REMOVE ${_filesToRemove}) + endif() +endfunction() + +function (cotire_init_target _targetName) + if (COTIRE_TARGETS_FOLDER) + set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") + endif() + if (MSVC_IDE) + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endfunction() + +function (cotire_add_to_pch_all_target _pchTargetName) + set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_pchTargetName}) +endfunction() + +function (cotire_add_to_unity_all_target _unityTargetName) + set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_unityTargetName}) +endfunction() + +function (cotire_setup_clean_all_target) + set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") + add_custom_target(${_targetName} COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Cleaning up all cotire generated files" VERBATIM) + cotire_init_target("${_targetName}") + endif() +endfunction() + +function (cotire) + set(_options "") + set(_oneValueArgs SOURCE_DIR BINARY_DIR) + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_targets ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_SOURCE_DIR) + set (_option_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + if (NOT _option_BINARY_DIR) + set (_option_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") + endif() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS} + SOURCE_DIR "${_option_SOURCE_DIR}" BINARY_DIR "${_option_BINARY_DIR}") + else() + message (WARNING "cotire: ${_target} is not a target.") + endif() + endforeach() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target_link_libraries(${_target}) + endif() + endforeach() +endfunction() + +if (CMAKE_SCRIPT_MODE_FILE) + + # cotire is being run in script mode + # locate -P on command args + set (COTIRE_ARGC -1) + foreach (_index RANGE ${CMAKE_ARGC}) + if (COTIRE_ARGC GREATER -1) + set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") + math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") + elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") + set (COTIRE_ARGC 0) + endif() + endforeach() + + # include target script if available + if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") + # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) + include("${COTIRE_ARGV2}") + endif() + + if (COTIRE_DEBUG) + message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") + endif() + + if (WIN32) + # for MSVC, compiler IDs may not always be set correctly + if (MSVC) + set (CMAKE_C_COMPILER_ID "MSVC") + set (CMAKE_CXX_COMPILER_ID "MSVC") + endif() + endif() + + if (NOT COTIRE_BUILD_TYPE) + set (COTIRE_BUILD_TYPE "None") + endif() + string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) + set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) + set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) + # check if target has been cotired for actual build type COTIRE_BUILD_TYPE + list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) + if (_index GREATER -1) + set (_sources ${COTIRE_TARGET_SOURCES}) + set (_sourceLocations ${COTIRE_TARGET_SOURCE_LOCATIONS}) + set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) + else() + if (COTIRE_DEBUG) + message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") + endif() + set (_sources "") + set (_sourceLocations "") + set (_sourcesDefinitions "") + endif() + set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) + set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) + set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) + set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) + + if ("${COTIRE_ARGV1}" STREQUAL "unity") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on target script + set (_dependsOption DEPENDS "${COTIRE_ARGV2}") + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sourceLocations ${_sourceLocations}) + + cotire_generate_unity_source( + "${COTIRE_ARGV3}" ${_sources} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + SOURCE_LOCATIONS ${_sourceLocations} + SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} + PRE_UNDEFS ${_targetPreUndefs} + POST_UNDEFS ${_targetPostUndefs} + SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} + SOURCES_POST_UNDEFS ${_sourcesPostUndefs} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies + set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + set (_files "") + foreach (_index RANGE 4 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_generate_prefix_header( + "${COTIRE_ARGV3}" ${_files} + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" + INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} + IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" + INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}" + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") + + set (_files "") + foreach (_index RANGE 5 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_precompile_prefix_header( + "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${COTIRE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + INCLUDE_SYSTEM_FLAG "${COTIRE_INCLUDE_SYSTEM_FLAG}" + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "combine") + + if (COTIRE_TARGET_LANGUAGE) + set (_startIndex 3) + else() + set (_startIndex 2) + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + if (COTIRE_TARGET_LANGUAGE) + cotire_generate_unity_source(${_files} LANGUAGE "${COTIRE_TARGET_LANGUAGE}") + else() + cotire_generate_unity_source(${_files}) + endif() + + elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") + + cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") + + else() + message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") + endif() + +else() + + # cotire is being run in include mode + # set up all variable and property definitions + + unset (COTIRE_C_COMPILER_VERSION CACHE) + unset (COTIRE_CXX_COMPILER_VERSION CACHE) + + if (NOT DEFINED COTIRE_DEBUG_INIT) + if (DEFINED COTIRE_DEBUG) + set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) + else() + set (COTIRE_DEBUG_INIT FALSE) + endif() + endif() + option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) + + if (NOT DEFINED COTIRE_VERBOSE_INIT) + if (DEFINED COTIRE_VERBOSE) + set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) + else() + set (COTIRE_VERBOSE_INIT FALSE) + endif() + endif() + option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING + "Ignore headers with the listed file extensions from the generated prefix header.") + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING + "Ignore headers from these directories when generating the prefix header.") + + set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING + "Ignore sources with the listed file extensions from the generated unity source.") + + set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING + "Minimum number of sources in target required to enable use of precompiled header.") + + if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) + if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) + elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") + # enable parallelization for generators that run multiple jobs by default + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") + else() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") + endif() + endif() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING + "Maximum number of source files to include in a single unity source file.") + + if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) + set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") + endif() + if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) + set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") + endif() + if (NOT COTIRE_INTDIR) + set (COTIRE_INTDIR "cotire") + endif() + if (NOT COTIRE_PCH_ALL_TARGET_NAME) + set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) + set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") + endif() + if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) + set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") + endif() + if (NOT COTIRE_CLEAN_TARGET_SUFFIX) + set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") + endif() + if (NOT COTIRE_PCH_TARGET_SUFFIX) + set (COTIRE_PCH_TARGET_SUFFIX "_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) + set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") + endif() + if (NOT DEFINED COTIRE_TARGETS_FOLDER) + set (COTIRE_TARGETS_FOLDER "cotire") + endif() + if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) + if ("${CMAKE_GENERATOR}" MATCHES "Ninja") + # generated Ninja build files do not work if the unity target produces the same output file as the cotired target + set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") + else() + set (COTIRE_UNITY_OUTPUT_DIRECTORY "") + endif() + endif() + + # define cotire cache variables + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of include directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "If not defined, defaults to empty list." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" + BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a header file extension matches one in the list, it will be excluded from the generated prefix header." + "Includes with an extension in CMAKE__SOURCE_FILE_EXTENSIONS are always ignored." + "If not defined, defaults to inc;inl;ipp." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" + BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a source file extension matches one in the list, it will be excluded from the generated unity source file." + "Source files with an extension in CMAKE__IGNORE_EXTENSIONS are always excluded." + "If not defined, defaults to m;mm." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" + BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." + FULL_DOCS + "The variable can be set to an integer > 0." + "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." + "If not defined, defaults to 3." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer >= 0." + "If 0, cotire will only create a single unity source file." + "If a target contains more than that number of source files, cotire will create multiple unity source files for it." + "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." + "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." + "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." + ) + + # define cotire directory properties + + define_property( + DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" + BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." + FULL_DOCS + "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" + BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_UNITY_BUILD." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" + BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_CLEAN." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" + BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." + FULL_DOCS + "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." + ) + + # define cotire target properties + + define_property( + TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED + BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." + FULL_DOCS + "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." + "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." + "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." + "The target name will be set to this target's name with the suffix _pch appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED + BRIEF_DOCS "Add a new target that performs a unity build for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." + "Most of the relevant target properties will be copied from this target to the new unity build target." + "Target dependencies and linked libraries have to be manually set up for the new unity build target." + "The unity target name will be set to this target's name with the suffix _unity appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED + BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." + "The clean target name will be set to this target's name with the suffix _clean_cotire appended." + "Inherited from directory." + "Defaults to FALSE." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "Inherited from directory." + "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." + "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," + "the option which yields the closer relative path match wins." + "Inherited from directory." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer > 0." + "If a target contains more than that number of source files, cotire will create multiple unity build files for it." + "If not set, cotire will only create a single unity source file." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE_INIT" + BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will only add the given file(s) to the generated unity source file." + "If not set, cotire will add all the target source files to the generated unity source file." + "The property can be set to a user provided unity source file." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER_INIT" + BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will add the given header file(s) to the generated prefix header file." + "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." + "The property can be set to a user provided prefix header file (e.g., stdafx.h)." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED + BRIEF_DOCS "Define strategy for setting up unity target's link libraries." + FULL_DOCS + "If this property is empty, the generated unity target's link libraries have to be set up manually." + "If this property is set to COPY, the unity target's link libraries will be copied from this target." + "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE" + BRIEF_DOCS "Read-only property. The generated unity source file(s)." + FULL_DOCS + "cotire sets this property to the path of the generated single computation unit source file for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER" + BRIEF_DOCS "Read-only property. The generated prefix header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language prefix header for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PRECOMPILED_HEADER" + BRIEF_DOCS "Read-only property. The generated precompiled header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language precompiled header binary for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" + BRIEF_DOCS "The name of the generated unity build target corresponding to this target." + FULL_DOCS + "This property can be set to the desired name of the unity target that will be created by cotire." + "If not set, the unity target name will be set to this target's name with the suffix _unity appended." + "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." + "Defaults to empty string." + ) + + # define cotire source properties + + define_property( + SOURCE PROPERTY "COTIRE_EXCLUDED" + BRIEF_DOCS "Do not modify source file's build command." + FULL_DOCS + "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." + "The source file will also be excluded from the generated unity source file." + "Source files that have their COMPILE_FLAGS property set will be excluded by default." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_DEPENDENCY" + BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." + FULL_DOCS + "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." + "If the file is modified, cotire will re-generate the prefix header source upon build." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" + BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." + FULL_DOCS + "If this property is set to TRUE, cotire will complete the current unity file and start a new one." + "The new unity source file will include this source file as the first one." + "This property essentially works as a separator for unity source files." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_TARGET" + BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." + FULL_DOCS + "cotire sets this property to the name of target, that the source file's build command has been altered for." + "Defaults to empty string." + ) + + message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") + +endif() diff --git a/cmakemodules/machineBitSize.cmake b/cmakemodules/machineBitSize.cmake new file mode 100644 index 0000000..33cee1c --- /dev/null +++ b/cmakemodules/machineBitSize.cmake @@ -0,0 +1,72 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# +# Determine the bitness of the machine +if (APPLE) + EXECUTE_PROCESS(COMMAND sysctl -n hw.cpu64bit_capable RESULT_VARIABLE error_code OUTPUT_VARIABLE SYSCTL_OUTPUT) + STRING(REGEX REPLACE "\n" "" OSX_64BIT "${SYSCTL_OUTPUT}") + if (OSX_64BIT) + MESSAGE(STATUS "Build universal binary - yes") + SET(MACHINETYPE "universal") + else() + MESSAGE(STATUS "Build universal binary - no") + SET(MACHINETYPE "i386") + endif() +ELSEIF("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + EXECUTE_PROCESS(COMMAND /bin/uname -m RESULT_VARIABLE error_code OUTPUT_VARIABLE UNAME_OUTPUT) + IF (error_code) + MESSAGE(FATAL_ERROR "Unable to determine machine archtecture") + ENDIF(error_code) + + STRING(REGEX REPLACE "\n" "" MACHINETYPE "${UNAME_OUTPUT}") + + MESSAGE(STATUS "Machine Type: ${MACHINETYPE}") + + EXECUTE_PROCESS(COMMAND /usr/bin/lsb_release -s -i RESULT_VARIABLE error_code OUTPUT_VARIABLE LSB_OUTPUT) + IF (NOT error_code) + STRING(REGEX REPLACE "\n" "" LINUX_VENDOR "${LSB_OUTPUT}") + EXECUTE_PROCESS(COMMAND /usr/bin/lsb_release -s -c RESULT_VARIABLE ec OUTPUT_VARIABLE LSB_CODENAME) + IF (NOT ec) + STRING(REGEX REPLACE "\n" "" LINUX_CODENAME "${LSB_OUTPUT}") + ENDIF(NOT ec) + ELSE() + SET(LINUX_VENDOR "Unknown") + ENDIF() +ELSEIF(WIN32) + EXECUTE_PROCESS(COMMAND cl.exe RESULT_VARIABLE error_code OUTPUT_VARIABLE CL_OUTPUT ERROR_VARIABLE CL_ERR) + + STRING(REGEX MATCH ".*x64.*" WIN64 "${CL_ERR}") + + IF(WIN64 STREQUAL "") + SET(MACHINETYPE "x86") + ELSE() + SET(MACHINETYPE "amd64") + ENDIF() +ENDIF(APPLE) diff --git a/cmakemodules/precompiled.header.cmake b/cmakemodules/precompiled.header.cmake new file mode 100644 index 0000000..960111a --- /dev/null +++ b/cmakemodules/precompiled.header.cmake @@ -0,0 +1,166 @@ +# Function for setting up precompiled headers. Usage: +# +# add_library/executable(target +# pchheader.c pchheader.cpp pchheader.h) +# +# add_precompiled_header(target pchheader.h +# [FORCEINCLUDE] +# [SOURCE_C pchheader.c] +# [SOURCE_CXX pchheader.cpp]) +# +# Options: +# +# FORCEINCLUDE: Add compiler flags to automatically include the +# pchheader.h from every source file. Works with both GCC and +# MSVC. This is recommended. +# +# SOURCE_C/CXX: Specifies the .c/.cpp source file that includes +# pchheader.h for generating the pre-compiled header +# output. Defaults to pchheader.c. Only required for MSVC. +# +# Caveats: +# +# * Its not currently possible to use the same precompiled-header in +# more than a single target in the same directory (No way to set +# the source file properties differently for each target). +# +# * MSVC: A source file with the same name as the header must exist +# and be included in the target (E.g. header.cpp). Name of file +# can be changed using the SOURCE_CXX/SOURCE_C options. +# +# License: +# +# Copyright (C) 2009-2013 Lars Christensen +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation files +# (the 'Software') deal in the Software without restriction, +# including without limitation the rights to use, copy, modify, merge, +# publish, distribute, sublicense, and/or sell copies of the Software, +# and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +include(CMakeParseArguments) +include(cotire) + +macro(combine_arguments _variable) + set(_result "") + foreach(_element ${${_variable}}) + set(_result "${_result} \"${_element}\"") + endforeach() + string(STRIP "${_result}" _result) + set(${_variable} "${_result}") +endmacro() + +function(export_all_flags _filename) + set(_include_directories "$") + set(_compile_definitions "$") + set(_compile_flags "$") + set(_compile_options "$") + set(_include_directories "$<$:-I$\n>") + set(_compile_definitions "$<$:-D$\n>") + set(_compile_flags "$<$:$\n>") + set(_compile_options "$<$:$\n>") +# file(GENERATE OUTPUT "${_filename}" CONTENT "${_compile_definitions}${_include_directories}${_compile_flags}${_compile_options}\n") + file(WRITE "${_filename}" "${_compile_definitions}${_include_directories}${_compile_flags}${_compile_options}\n") +endfunction() + +function(add_precompiled_header _target _input) + cmake_parse_arguments(_PCH "FORCEINCLUDE" "SOURCE_CXX:SOURCE_C" "" ${ARGN}) + + get_filename_component(_input_we ${_input} NAME_WE) + if(NOT _PCH_SOURCE_CXX) + set(_PCH_SOURCE_CXX "${_input_we}.cpp") + endif() + if(NOT _PCH_SOURCE_C) + set(_PCH_SOURCE_C "${_input_we}.c") + endif() + + if(MSVC_IDE) + SET_SOURCE_FILES_PROPERTIES(${_PCH_SOURCE_CXX} PROPERTIES COMPILE_FLAGS "/Yc\"${_input}\"") + SET_TARGET_PROPERTIES(${_target} PROPERTIES COMPILE_FLAGS "/Yu\"${_input}\"") + elseif(MSVC) + set_target_properties(${_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${_input}") + cotire(${_target}) + endif(MSVC_IDE) + + if(CMAKE_COMPILER_IS_GNUCXX) + set_target_properties(${_target} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${_input}") + cotire(${_target}) + # get_filename_component(_name ${_input} NAME) + # set(_pch_header "${CMAKE_CURRENT_SOURCE_DIR}/${_input}") + # set(_pch_binary_dir "${CMAKE_CURRENT_BINARY_DIR}/${_target}_pch") + # set(_pchfile "${_pch_binary_dir}/${_input}") + # set(_outdir "${CMAKE_CURRENT_BINARY_DIR}/${_target}_pch/${_name}.gch") + # make_directory(${_outdir}) + # set(_output_cxx "${_outdir}/.c++") + # set(_output_c "${_outdir}/.c") + + # set(_pch_flags_file "${_pch_binary_dir}/compile_flags.rsp") + # export_all_flags("${_pch_flags_file}") + # set(_compiler_FLAGS "@${_pch_flags_file}") + # add_custom_command( + # OUTPUT "${_pchfile}" + # COMMAND "${CMAKE_COMMAND}" -E copy "${_pch_header}" "${_pchfile}" + # DEPENDS "${_pch_header}" + # COMMENT "Updating ${_name}") + # add_custom_command( + # OUTPUT "${_output_cxx}" + # COMMAND "${CMAKE_CXX_COMPILER}" ${_compiler_FLAGS} -x c++-header -o "${_output_cxx}" "${_pchfile}" + # DEPENDS "${_pchfile}" "${_pch_flags_file}" + # COMMENT "Precompiling ${_name} for ${_target} (C++)") + # add_custom_command( + # OUTPUT "${_output_c}" + # COMMAND "${CMAKE_C_COMPILER}" ${_compiler_FLAGS} -x c-header -o "${_output_c}" "${_pchfile}" + # DEPENDS "${_pchfile}" "${_pch_flags_file}" + # COMMENT "Precompiling ${_name} for ${_target} (C)") + + # get_property(_sources TARGET ${_target} PROPERTY SOURCES) + # foreach(_source ${_sources}) + # set(_pch_compile_flags "") + + # if(_source MATCHES \\.\(cc|cxx|cpp|c\)$) + # get_source_file_property(_pch_compile_flags "${_source}" COMPILE_FLAGS) + # if(NOT _pch_compile_flags) + # set(_pch_compile_flags) + # endif() + # separate_arguments(_pch_compile_flags) + # list(APPEND _pch_compile_flags -Winvalid-pch) + # if(_PCH_FORCEINCLUDE) + # list(APPEND _pch_compile_flags -include "${_pchfile}") + # else(_PCH_FORCEINCLUDE) + # list(APPEND _pch_compile_flags "-I${_pch_binary_dir}") + # endif(_PCH_FORCEINCLUDE) + + # get_source_file_property(_object_depends "${_source}" OBJECT_DEPENDS) + # if(NOT _object_depends) + # set(_object_depends) + # endif() + # list(APPEND _object_depends "${_pchfile}") + # if(_source MATCHES \\.\(cc|cxx|cpp\)$) + # list(APPEND _object_depends "${_output_cxx}") + # else() + # list(APPEND _object_depends "${_output_c}") + # endif() + + # combine_arguments(_pch_compile_flags) + # message("${_source}" ${_pch_compile_flags}) + # set_source_files_properties(${_source} PROPERTIES + # COMPILE_FLAGS "${_pch_compile_flags}" + # OBJECT_DEPENDS "${_object_depends}") + # endif() + # endforeach() + endif(CMAKE_COMPILER_IS_GNUCXX) +endfunction() diff --git a/cmakemodules/summary.cmake b/cmakemodules/summary.cmake new file mode 100644 index 0000000..3cdecfa --- /dev/null +++ b/cmakemodules/summary.cmake @@ -0,0 +1,119 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# ======================================================================= +# print summary of configuration to screen +# ======================================================================= + +macro(summary) +set(_output_results " +Summary of CMake build system results for the TecSec component + +Library options: +TSF_FULL_VERSION: ${TSF_FULL_VERSION} +TS_X_PLATFORM: ${TS_X_PLATFORM} +TS_TOOLSET: ${TS_TOOLSET} +CMAKE_VS_PLATFORM_TOOLSET: ${CMAKE_VS_PLATFORM_TOOLSET} +TS_VS_CONFIGURATION: ${TS_VS_CONFIGURATION} +Postfix for DLLS... ${CMAKE_${TS_CONFIG}_POSTFIX} + +Other important CMake variables: + +CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME} +UNIX: ${UNIX} +WIN32: ${WIN32} +APPLE: ${APPLE} +MSVC_IDE: ${MSVC_IDE} +MSVC: ${MSVC} (MSVC_VERSION: ${MSVC_VERSION}) +MINGW: ${MINGW} +MSYS: ${MSYS} +CYGWIN: ${CYGWIN} + +CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE} +CMAKE_C_COMPILER CMAKE_C_FLAGS: ${CMAKE_C_COMPILER} +CMAKE_C_FLAGS: ${CMAKE_C_FLAGS} +CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS} +CMAKE_EXECUTABLE_SUFFIX: ${CMAKE_EXECUTABLE_SUFFIX} +CMAKE_SHARED_MODULE_PREFIX: ${CMAKE_SHARED_MODULE_PREFIX} +CMAKE_SHARED_MODULE_SUFFIX: ${CMAKE_SHARED_MODULE_SUFFIX} +CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX} +CMAKE_INSTALL_EXEC_PREFIX ${CMAKE_INSTALL_EXEC_PREFIX} +CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} +CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} +CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} + +TS_INSTALL_PREFIX: ${TS_INSTALL_PREFIX} +DATA_DIR: ${DATA_DIR} +INCLUDE_DIR: ${INCLUDE_DIR} +ALLBIN_DIR: ${ALLBIN_DIR} +BIN_DIR: ${BIN_DIR} +LIB_DIR: ${LIB_DIR} +SHLIB_DIR: ${SHLIB_DIR} +DOC_DIR: ${DOC_DIR} +INFO_DIR: ${INFO_DIR} +MAN_DIR: ${MAN_DIR} +BUILD_DIR: ${BUILD_DIR} +SOURCE_DIR: ${SOURCE_DIR} +INSTALL_BIN_DIR: ${INSTALL_BIN_DIR} +INSTALL_SHLIB_DIR: ${INSTALL_SHLIB_DIR} +INSTALL_LIB_DIR: ${INSTALL_LIB_DIR} +INSTALL_OTHER_DIR: ${INSTALL_OTHER_DIR} + +Optional libraries:") +if (ZLIB_FOUND) +set(_output_results "${_output_results} +ZLIB_FOUND") +endif(ZLIB_FOUND) +if (PNG_FOUND) +set(_output_results "${_output_results} +PNG_FOUND") +endif(PNG_FOUND) +if (GMOCK_FOUND) +set(_output_results "${_output_results} +GMOCK_FOUND") +endif(GMOCK_FOUND) +if (GTEST_FOUND) +set(_output_results "${_output_results} +GTEST_FOUND") +endif(GTEST_FOUND) +if (Boost_FOUND) +set(_output_results "${_output_results} +Boost_FOUND") +endif(Boost_FOUND) +if (BZ2_FOUND) +set(_output_results "${_output_results} +BZ2_FOUND") +endif(BZ2_FOUND) +if (HARU_FOUND) +set(_output_results "${_output_results} +HARU_FOUND") +endif(HARU_FOUND) + +message("${_output_results}") +endmacro(summary) diff --git a/cmakemodules/tecsec_base_macros.cmake b/cmakemodules/tecsec_base_macros.cmake new file mode 100644 index 0000000..6f9e6a3 --- /dev/null +++ b/cmakemodules/tecsec_base_macros.cmake @@ -0,0 +1,678 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +macro(ConfigureExe target) + set_target_properties(${target} PROPERTIES DEBUG_POSTFIX "d") +endmacro() +macro(CopyFile source dest) + ADD_CUSTOM_COMMAND( + OUTPUT + ${dest} + DEPENDS + ${source} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${source} ${dest} + ) +endmacro() +macro(SignThenCopy source destination) + ADD_CUSTOM_COMMAND( + OUTPUT ${destination} + DEPENDS ${source} + COMMAND signtool.exe sign ${TSF_CERT_SPEC} "${source}" + COMMAND ${CMAKE_COMMAND} -E copy ${source} ${destination} + ) +endmacro() +macro(StrongSignThenCopy source destination) + ADD_CUSTOM_COMMAND( + OUTPUT ${destination} + DEPENDS ${source} + COMMAND sn.exe -R "${source}" "${PUBLIC_SOURCE_TOP_DIR}/SolutionItems/${TSF_KEY_FILE}" + COMMAND signtool.exe sign ${TSF_CERT_SPEC} "${source}" + COMMAND ${CMAKE_COMMAND} -E copy ${source} ${destination} + ) +endmacro() + +macro(CopyTlbHeadersToSDK idlName) + ADD_CUSTOM_COMMAND( + OUTPUT ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/${idlName}_h.h ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/${idlName}_i.h + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${idlName}_h.h ${CMAKE_CURRENT_BINARY_DIR}/${idlName}_i.h + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${idlName}_h.h ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/ + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${idlName}_i.h ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/ + ) +endmacro() +macro(CopyTlbToSDK idlName) + ADD_CUSTOM_COMMAND( + OUTPUT ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/${idlName}.tlb + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${idlName}.tlb + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/${idlName}.tlb ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/ + ) +endmacro() +macro(CopyToSDKInclude filename destName) + ADD_CUSTOM_COMMAND( + OUTPUT ${SDK_ROOT_VS}/include/${destName} + DEPENDS ${filename} + COMMAND ${CMAKE_COMMAND} -E copy ${filename} ${SDK_ROOT_VS}/include/${destName} + ) +endmacro() +macro(CopyToSDKInstallerInclude filename destName) + ADD_CUSTOM_COMMAND( + OUTPUT ${SDK_ROOT_VS}/${TS_MODULE}/installer/include/${destName} + DEPENDS ${filename} + COMMAND ${CMAKE_COMMAND} -E copy ${filename} ${SDK_ROOT_VS}/${TS_MODULE}/installer/include/${destName} + ) +endmacro() +macro(DumpAllVariables) + get_cmake_property(_variableNames VARIABLES) + foreach(_variableName ${_variableNames}) + message(STATUS "${_variableName}=${${_variableName}}") + endforeach() +endmacro() +macro(DumpAllTargetVariables targetName) + get_target_property(_variableNames ${targetName} VARIABLES) + foreach(_variableName ${_variableNames}) + message(STATUS "tgt: ${_variableName}=${${_variableName}}") + endforeach() +endmacro() + + +IF(BUILD_SXS) +macro(MakeManifest manifestBaseFilename) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.manifest" _maniPath) + CopyFile(${CMAKE_CURRENT_BINARY_DIR}/${manifestBaseFilename}.manifest ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.manifest) + ADD_CUSTOM_COMMAND( + OUTPUT + ${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${manifestBaseFilename}.manifest + ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${manifestBaseFilename}.manifest + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cdf + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.manifest + ${ARGN} + COMMAND mt.exe -nologo -manifest "${_maniPath}" -makecdfs + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.manifest ${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${manifestBaseFilename}.manifest + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.manifest ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${manifestBaseFilename}.manifest + COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cdf" + COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.manifest.cdf" "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cdf" + ) +endmacro() + +macro(MakeManifestCatalog manifestBaseFilename) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cdf" _cdfPath) + ADD_CUSTOM_COMMAND( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cat + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cdf + COMMAND MakeCat.Exe "${_cdfPath}" + COMMAND signtool.exe sign ${TSF_CERT_SPEC} "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cat" + ) + CopyFile(${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${manifestBaseFilename}.cat ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${manifestBaseFilename}.cat) +endmacro() + +macro(MakePolicyManifest policyBaseFilename) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.manifest" _maniPath) + CopyFile(${CMAKE_CURRENT_BINARY_DIR}/${policyBaseFilename}.manifest ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.manifest) + ADD_CUSTOM_COMMAND( + OUTPUT + ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${policyBaseFilename}.manifest + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cdf + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.manifest + ${ARGN} + COMMAND mt.exe -nologo -manifest "${_maniPath}" -makecdfs + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.manifest ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${policyBaseFilename}.manifest + COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cdf" + COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.manifest.cdf" "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cdf" + ) +endmacro() + +macro(MakePolicyCatalog policyBaseFilename) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cdf" _cdfPath) + + ADD_CUSTOM_COMMAND( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cat + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cdf + COMMAND MakeCat.Exe "${_cdfPath}" + COMMAND signtool.exe sign ${TSF_CERT_SPEC} "${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cat" + ) + + CopyFile(${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${policyBaseFilename}.cat ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${policyBaseFilename}.cat) +endmacro() +ENDIF(BUILD_SXS) + +macro(SignBinary sourcePath signedPath filename dest) + ADD_CUSTOM_COMMAND( + OUTPUT + ${signedPath}/${filename} + DEPENDS + ${sourcePath}/${filename} + COMMAND ${CMAKE_COMMAND} -E echo Signing file ${sourcePath}/${filename} + COMMAND ${CMAKE_COMMAND} -E make_directory ${signedPath} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${sourcePath}/${filename} ${signedPath}/${filename} + COMMAND signtool.exe sign ${TSF_CERT_SPEC} "${signedPath}/${filename}" + ) + CopyFile(${signedPath}/${filename} ${dest}/${filename}) +endmacro() + +IF(WIN32) +macro(BuildTLB_sdk idlName) + ADD_CUSTOM_COMMAND( + OUTPUT + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + DEPENDS ${idlName}.idl + COMMAND + ${CMAKE_COMMAND} -E make_directory ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ + COMMAND + midl /D "_DEBUG" /W1 /nologo /char signed /env ${TS_PLATFORM} /Oicf /I ${CMAKE_CURRENT_SOURCE_DIR}/../include /I ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ ${TS_MIDL_INCLUDES} /h "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h" /iid "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h" /proxy "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c" /tlb "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb" /robust ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/include/${TS_X_PLATFORM} + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/installer/include/ + ) + add_custom_target(Generate_${idlName}_TLB ALL + SOURCES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + DEPENDS + ${ARGN} + ) +endmacro() +macro(BuildTLB_app idlName) + ADD_CUSTOM_COMMAND( + OUTPUT + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + DEPENDS ${idlName}.idl + COMMAND + ${CMAKE_COMMAND} -E make_directory ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ + COMMAND + midl /D "_DEBUG" /W1 /nologo /char signed /env ${TS_PLATFORM} /Oicf /I ${CMAKE_CURRENT_SOURCE_DIR}/../include/ /I ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ ${TS_MIDL_INCLUDES} /h "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h" /iid "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h" /proxy "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c" /tlb "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb" /robust ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/include/${TS_X_PLATFORM} + ) + add_custom_target(Generate_${idlName}_TLB ALL + SOURCES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + DEPENDS + ${ARGN} + ) +endmacro() +macro(BuildTLBInBinary idlName) + ADD_CUSTOM_COMMAND( + OUTPUT + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${idlName}.idl + COMMAND + ${CMAKE_COMMAND} -E make_directory ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ + COMMAND midl /D "_DEBUG" /W1 /nologo /char signed /env ${TS_PLATFORM} /Oicf /I ${CMAKE_CURRENT_SOURCE_DIR}/../include/ /I ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ ${TS_MIDL_INCLUDES} /h "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h" /iid "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h" /proxy "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c" /tlb "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb" /robust ${CMAKE_CURRENT_BINARY_DIR}/${idlName}.idl + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/include/${TS_X_PLATFORM} + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/installer/include/${TS_X_PLATFORM} + ) + + add_custom_target(Generate_${idlName}_TLB ALL + SOURCES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb + DEPENDS + ${ARGN} + ) +endmacro() +macro(BuildTLBNoLib idlName) + ADD_CUSTOM_COMMAND( + OUTPUT + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DEPENDS ${idlName}.idl + COMMAND + ${CMAKE_COMMAND} -E make_directory ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ + COMMAND + midl /D "_DEBUG" /W1 /nologo /char signed /env ${TS_PLATFORM} /Oicf /I ${CMAKE_CURRENT_SOURCE_DIR}/../include/ /I ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ ${TS_MIDL_INCLUDES} /h "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h" /iid "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h" /proxy "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c" /tlb "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}.tlb" /robust ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/include/${TS_X_PLATFORM} + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/installer/include/${TS_X_PLATFORM} + ) + add_custom_target(Generate_${idlName}_TLB ALL + SOURCES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DEPENDS + ${ARGN} + ) +endmacro() +macro(BuildTypeTLB_sdk idlName) + ADD_CUSTOM_COMMAND( + OUTPUT + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DEPENDS ${idlName}.idl + COMMAND midl /D "_DEBUG" /W1 /nologo /char signed /notlb /env ${TS_PLATFORM} /Oicf /I ${CMAKE_CURRENT_SOURCE_DIR}/../include/ /I ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ ${TS_MIDL_INCLUDES} /h "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h" /iid "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h" /proxy "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c" /robust ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ) + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/include/${TS_X_PLATFORM} + ) + install( + FILES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/installer/include/${TS_X_PLATFORM} + ) + add_custom_target(Generate_${idlName}_TLB ALL + SOURCES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DEPENDS + ${ARGN} + ) +endmacro() +macro(BuildTypeTLB_app idlName) + ADD_CUSTOM_COMMAND( + OUTPUT + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DEPENDS ${idlName}.idl + COMMAND midl /D "_DEBUG" /W1 /nologo /char signed /notlb /env ${TS_PLATFORM} /Oicf /I ${CMAKE_CURRENT_SOURCE_DIR}/../include/ /I ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/ ${TS_MIDL_INCLUDES} /h "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h" /iid "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h" /proxy "${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c" /robust ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ) + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/${idlName}.idl + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DESTINATION + ${TS_MODULE}/include/${TS_X_PLATFORM} + ) + add_custom_target(Generate_${idlName}_TLB ALL + SOURCES + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_h.h + ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_i.h + # ${PUBLIC_BINARY_TOP_DIR}/include/${TS_VS_CONFIGURATION}/${idlName}_p.c + DEPENDS + ${ARGN} + ) +endmacro() + +macro(Tlb2TypesDll idlName asmName namespace Product dependency configName) + # Copy the required manifest and config files + configure_file(${PUBLIC_SOURCE_TOP_DIR}/SolutionItems/${asmName}.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/${asmName}.manifest) + configure_file(${PUBLIC_SOURCE_TOP_DIR}/SolutionItems/policy.${asmName}.config.in ${CMAKE_CURRENT_BINARY_DIR}/${TSF_POLICYFILENAME}.${asmName}.config) + + # Create the .net TYPES dll + ADD_CUSTOM_COMMAND( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${asmName}.dll + DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${idlName}.tlb + COMMAND + tlbimp.exe -nologo /out:${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${asmName}.dll /namespace:${namespace} /delaysign /keyfile:${PUBLIC_SOURCE_TOP_DIR}/SolutionItems/${TSF_KEY_FILE} /primary /machine:${TS_X_PLATFORM} /asmversion:"${TSF_FULL_VERSION}" ${ARGN} /productversion:"${TSF_FULL_VERSION}" ${SDK_ROOT_VS}/include/${TS_X_PLATFORM}/${idlName}.tlb /company:"TecSec Inc" "/copyright:Copyright (c) 2013 TecSec, Inc. All rights reserved" /product:"${Product}" + COMMAND + mt.exe -nologo -manifest "${CMAKE_CURRENT_BINARY_DIR}/${asmName}.manifest" -hashupdate -outputresource:${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${asmName}.dll\;2 + ) + StrongSignThenCopy(${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${asmName}.dll ${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${asmName}.dll) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${asmName}.dll ${SDK_ROOT_VS}/assembly/${TS_X_PLATFORM}/${asmName}.dll) + + + # create the policy dll for the .net component + CopyFile(${CMAKE_CURRENT_BINARY_DIR}/${TSF_POLICYFILENAME}.${asmName}.config ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${TSF_POLICYFILENAME}.${asmName}.config) + ADD_CUSTOM_COMMAND( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${TSF_POLICYFILENAME}.${asmName}.dll + DEPENDS + # ${SDK_ROOT_VS}/Assembly/${TS_X_PLATFORM}/${asmName}.dll + ${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${TSF_POLICYFILENAME}.${asmName}.config + COMMAND + al /linkresource:${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${TSF_POLICYFILENAME}.${asmName}.config /out:${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${TSF_POLICYFILENAME}.${asmName}.dll /keyfile:${PUBLIC_SOURCE_TOP_DIR}/SolutionItems/${TSF_KEY_FILE} /v:${TSF_FULL_VERSION} + ) + SignThenCopy(${CMAKE_CURRENT_BINARY_DIR}/${TS_VS_CONFIGURATION}/${TSF_POLICYFILENAME}.${asmName}.dll "${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${TSF_POLICYFILENAME}.${asmName}.dll") + + # Put it all together as a VS project + add_custom_target(Generate_${asmName} ALL + SOURCES + ${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${asmName}.dll + ${SDK_ROOT_VS}/assembly/${TS_X_PLATFORM}/${asmName}.dll + ${SDK_ROOT_VS}/policy/${TS_X_PLATFORM}/${TSF_POLICYFILENAME}.${asmName}.dll + DEPENDS + Generate_${idlName}_TLB ${dependency} + ) +endmacro() +ENDIF(WIN32) + +set(SDK_FRAMEWORK_BINARIES + ${CMAKE_SHARED_MODULE_PREFIX}TSFramework${CMAKE_SHARED_MODULE_SUFFIX} + ) +IF(BUILD_SXS) +set(SDK_FRAMEWORK_BINARIES ${SDK_FRAMEWORK_BINARIES} + TSFramework-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + ) +ENDIF(BUILD_SXS) +set(SDK_CRYPTO_BINARIES + ${SDK_FRAMEWORK_BINARIES} + + ${CMAKE_SHARED_MODULE_PREFIX}TSCryptoSupport${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmCrypto2${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmCrypto_Fips${CMAKE_SHARED_MODULE_SUFFIX} + ) +IF(BUILD_SXS) +set(SDK_CRYPTO_BINARIES ${SDK_CRYPTO_BINARIES} + TSCkmCrypto2-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + TSCkmCrypto_Fips-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + TSCryptoSupport-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + ) +ENDIF(BUILD_SXS) +set(SDK_RUNTIME_BINARIES + ${SDK_CRYPTO_BINARIES} + + ${CMAKE_SHARED_MODULE_PREFIX}BsiCore${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmEBClient${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmHeader${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmFileSupport${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmKeyGen${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmUI${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmDatastore${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}CkmWinscard${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}Ckm_Pkcs11${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}TSAppCommon${CMAKE_SHARED_MODULE_SUFFIX} + ${CMAKE_SHARED_MODULE_PREFIX}TSCkmLoader${CMAKE_SHARED_MODULE_SUFFIX} + ) +IF(BUILD_SXS) +set(SDK_RUNTIME_BINARIES + ${SDK_RUNTIME_BINARIES} + + TSAppCommon-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + TSCkmUI-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + TSCkmLoader-${TS_TOOLSET}-${TS_X_PLATFORM}-assembly.manifest + ) +ENDIF(BUILD_SXS) + +set(GMOCK_BINARIES + ${CMAKE_SHARED_MODULE_PREFIX}gmock.dll + ${CMAKE_SHARED_MODULE_PREFIX}gmock_main.dll + ${CMAKE_SHARED_MODULE_PREFIX}gtest.dll + ${CMAKE_SHARED_MODULE_PREFIX}gtest_main.dll + ) +macro(CopySdkFrameworkBinaries folder name) + set(__list "") + foreach(_file ${SDK_FRAMEWORK_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + add_custom_target(Start_AppFolders_${name} + SOURCES + ${__list} + DEPENDS + ${name} + ${ARGN} + COMMAND + ${CMAKE_COMMAND} -E echo Creating the application output folders + ) +endmacro() +macro(CopySdkFrameworkBinariesAndGmock folder name) + set(__list "") + foreach(_file ${SDK_FRAMEWORK_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + foreach(_file ${GMOCK_BINARIES}) + CopyFile(${PUBLIC_SOURCE_TOP_DIR}/../thirdparty/${TS_VS_CONFIGURATION}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + add_custom_target(Start_AppFolders_${name} + SOURCES + ${__list} + DEPENDS + ${name} + ${ARGN} + COMMAND + ${CMAKE_COMMAND} -E echo Creating the application output folders + ) +endmacro() +macro(CopySdkCryptoBinaries folder name) + set(__list "") + foreach(_file ${SDK_CRYPTO_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + add_custom_target(Start_AppFolders_${name} + SOURCES + ${__list} + + DEPENDS + ${name} + ${ARGN} + COMMAND + echo Creating the application output folders + ) +endmacro() +macro(CopySdkCryptoBinariesAndGmock folder name) + set(__list "") + foreach(_file ${SDK_CRYPTO_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + foreach(_file ${GMOCK_BINARIES}) + CopyFile(${PUBLIC_SOURCE_TOP_DIR}/../thirdparty/${TS_VS_CONFIGURATION}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + add_custom_target(Start_AppFolders_${name} + SOURCES + ${__list} + DEPENDS + ${name} + ${ARGN} + COMMAND + echo Creating the application output folders + ) +endmacro() +macro(CopySdkRuntimeBinaries folder name) + set(__list "") + foreach(_file ${SDK_RUNTIME_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + add_custom_target(Start_AppFolders_${name} + SOURCES + ${__list} + + DEPENDS + ${name} + ${ARGN} + COMMAND + echo Creating the application output folders + ) +endmacro() +macro(CopySdkRuntimeBinariesAndGmock folder name) + set(__list "") + foreach(_file ${SDK_RUNTIME_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + foreach(_file ${GMOCK_BINARIES}) + CopyFile(${PUBLIC_SOURCE_TOP_DIR}/../thirdparty/${TS_VS_CONFIGURATION}/${_file} ${folder}/${_file}) + set(__list ${__list} ${folder}/${_file}) + endforeach() + add_custom_target(Start_AppFolders_${name} + SOURCES + ${__list} + DEPENDS + ${name} + ${ARGN} + COMMAND + echo Creating the application output folders + ) +endmacro() +macro(CopySdkRteBinariesToWeb name folder) + set(__list "") + foreach(_file ${SDK_RUNTIME_BINARIES}) + CopyFile(${SDK_ROOT_VS}/bin/${TS_X_PLATFORM}/${_file} ${APP_TEST_ROOT_VS}/${folder}/${TS_X_PLATFORM}-${TS_TOOLSET}/Web/bin/${_file}) + set(__list ${__list} ${APP_TEST_ROOT_VS}/${folder}/${TS_X_PLATFORM}-${TS_TOOLSET}/Web/bin/${_file}) + endforeach() + add_custom_target(Start_AppFolders.Web.${name} + SOURCES + ${__list} + + COMMAND + echo Creating the application output folders + ) + set_target_properties(Start_AppFolders.Web.${name} PROPERTIES FOLDER "Finish") +endmacro() + +macro(Minify source dest) + GET_FILENAME_COMPONENT(__destFile ${dest} NAME) + GET_FILENAME_COMPONENT(__destPath ${dest} DIRECTORY) + ADD_CUSTOM_COMMAND( + OUTPUT + ${dest} + DEPENDS + ${source} + COMMAND + ${CMAKE_COMMAND} -E copy_if_different ${source} ${dest}.tmp.js +# COMMAND +# ${CMAKE_COMMAND} -E chdir ${__destPath} java -jar s:/devsup/utils/yuicompressor-2.4.8.jar -o "${__destFile}" "${dest}.tmp.js" + COMMAND + java.exe -jar s:/devsup/utils/yuicompressor-2.4.8.jar -o "${__destFile}" "${dest}.tmp.js" WORKING_DIRECTORY ${__destPath} + COMMAND + ${CMAKE_COMMAND} -E remove ${dest}.tmp.js + ) +endmacro() +macro(add_uninstall) +# add the uninstall support +find_file(UNINSTALL_HELPER uninstall.cmake.in PATHS ${CMAKE_MODULE_PATH}) +if("${UNINSTALL_HELPER}" STREQUAL "UNINSTALL_HELPER-NOTFOUND") + MESSAGE(FATAL "The file uninstall.cmake.in could not be found.") +endif() +IF("${CMAKEMODULESPATH}" STREQUAL "") + SET(CMAKEMODULESPATH ${PUBLIC_SOURCE_TOP_DIR}/../cmakemodules) +ENDIF() +CONFIGURE_FILE("${UNINSTALL_HELPER}" "${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake" IMMEDIATE @ONLY) + +ADD_CUSTOM_TARGET(uninstall + "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/uninstall.cmake") +set_target_properties(uninstall PROPERTIES FOLDER "CMakePredefinedTargets") +endmacro() + +macro(ImportTarget target) +if(TARGET ${target}) + #include_directories($>>) + get_property(_tmp TARGET ${target} PROPERTY INTERFACE_INCLUDE_DIRECTORIES_${TS_CONFIG}) + if(NOT ("${_tmp}" STREQUAL "")) + include_directories(${_tmp}) + endif(NOT ("${_tmp}" STREQUAL "")) + get_property(_tmp TARGET ${target} PROPERTY INTERFACE_MIDL_INCLUDE_${TS_CONFIG}) + if(NOT "${_tmp}" STREQUAL "") + list(APPEND TS_MIDL_INCLUDES "-I" "${_tmp}") + endif(NOT "${_tmp}" STREQUAL "") +endif(TARGET ${target}) +endmacro() +macro(CopyImportTargetBinaries target dest) + get_property(_tmp TARGET ${target} PROPERTY INTERFACE_BIN_MODULES_${TS_CONFIG}) + install(FILES ${_tmp} DESTINATION ${dest}) +endmacro() +macro(CopyImportTargetTools target dest) + get_property(_tmp TARGET ${target} PROPERTY INTERFACE_TOOLS_${TS_CONFIG}) + if(NOT("${_tmp}" STREQUAL "")) + install(FILES ${_tmp} DESTINATION ${dest}) + endif(NOT("${_tmp}" STREQUAL "")) +endmacro() diff --git a/cmakemodules/tecsec_installdirs.cmake b/cmakemodules/tecsec_installdirs.cmake new file mode 100644 index 0000000..2503d08 --- /dev/null +++ b/cmakemodules/tecsec_installdirs.cmake @@ -0,0 +1,78 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set(CMAKE_INSTALL_PREFIX ${TS_INSTALL_PREFIX}) + +set(EXE_DLL_POSTFIX ${CMAKE_${TS_CONFIG}_POSTFIX}) +set(CMAKE_INSTALL_EXEC_PREFIX ${CMAKE_INSTALL_PREFIX}/${TS_MODULE}) +set(CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${TS_MODULE}/include) +set(ALLBIN_DIR ${CMAKE_INSTALL_PREFIX}/bin${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) +set(ALLSHLIB_DIR ${CMAKE_INSTALL_PREFIX}/bin${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + +set(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_EXEC_PREFIX}/bin) +set(CMAKE_INSTALL_DATADIR ${CMAKE_INSTALL_PREFIX}/share) +set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_EXEC_PREFIX}/lib) +set(CMAKE_INSTALL_INFODIR ${CMAKE_INSTALL_DATADIR}/info) +set(CMAKE_INSTALL_MANDIR ${CMAKE_INSTALL_DATADIR}/man) + + +set(DATA_DIR ${CMAKE_INSTALL_DATADIR}) +set(INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}) +if(WIN32) + set(BIN_DIR ${CMAKE_INSTALL_BINDIR}${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(LIB_DIR ${CMAKE_INSTALL_LIBDIR}${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(SHLIB_DIR ${BIN_DIR}) + set(INSTALL_BIN_DIR ${CMAKE_INSTALL_EXEC_PREFIX}/installer/bin${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(INSTALL_SHLIB_DIR ${CMAKE_INSTALL_EXEC_PREFIX}/installer/bin${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(INSTALL_LIB_DIR ${CMAKE_INSTALL_EXEC_PREFIX}/installer/lib${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(INSTALL_OTHER_DIR ${CMAKE_INSTALL_EXEC_PREFIX}/installer) +elseif(UNIX) + set(BIN_DIR ${CMAKE_INSTALL_BINDIR}${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(LIB_DIR ${CMAKE_INSTALL_LIBDIR}${TS_LIB_DIR_SUFFIX}${EXE_DLL_POSTFIX}) + set(SHLIB_DIR ${BIN_DIR}) + set(ALLSHLIB_DIR ${SHLIB_DIR}) + set(INSTALL_BIN_DIR ${BIN_DIR}) + set(INSTALL_SHLIB_DIR ${SHLIB_DIR}) + set(INSTALL_LIB_DIR ${LIB_DIR}) + set(INSTALL_OTHER_DIR ${CMAKE_INSTALL_EXEC_PREFIX}) +#else(WIN32) +# set(BIN_DIR ${CMAKE_INSTALL_BINDIR}) +# set(LIB_DIR ${CMAKE_INSTALL_LIBDIR}${TS_LIB_DIR_SUFFIX}) +# set(SHLIB_DIR ${CMAKE_INSTALL_LIBDIR}${TS_LIB_DIR_SUFFIX}) +# set(ALLSHLIB_DIR ${SHLIB_DIR}) +# set(INSTALL_BIN_DIR ${BIN_DIR}) +# set(INSTALL_SHLIB_DIR ${SHLIB_DIR}) +# set(INSTALL_LIB_DIR ${LIB_DIR}) +# set(INSTALL_OTHER_DIR ${CMAKE_INSTALL_EXEC_PREFIX}) +endif(WIN32) +set(DOC_DIR ${CMAKE_INSTALL_DATADIR}/doc) +set(INFO_DIR ${CMAKE_INSTALL_INFODIR}) +set(MAN_DIR ${CMAKE_INSTALL_MANDIR}) +set(BUILD_DIR ${CMAKE_BINARY_DIR}) +set(SOURCE_DIR ${CMAKE_SOURCE_DIR}) diff --git a/cmakemodules/tecsec_top.cmake b/cmakemodules/tecsec_top.cmake new file mode 100644 index 0000000..c381d6b --- /dev/null +++ b/cmakemodules/tecsec_top.cmake @@ -0,0 +1,279 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# if (CMAKE_CONFIGURATION_TYPES) + # set (CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo) + # set (CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING + # "Reset the configurations for TSFramework" FORCE) +# endif() + +set (PUBLIC_SOURCE_TOP_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set (PUBLIC_BINARY_TOP_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +if(WIN32) + STRING(REPLACE "/" "\\" NATIVE_PUBLIC_SOURCE_TOP_DIR ${PUBLIC_SOURCE_TOP_DIR}) + STRING(REPLACE "/" "\\" NATIVE_PUBLIC_BINARY_TOP_DIR ${PUBLIC_BINARY_TOP_DIR}) +else() + SET(NATIVE_PUBLIC_SOURCE_TOP_DIR ${PUBLIC_SOURCE_TOP_DIR}) + SET(NATIVE_PUBLIC_BINARY_TOP_DIR ${PUBLIC_BINARY_TOP_DIR}) +endif() + +set(TECSEC_TOOLS_DIR ${PUBLIC_SOURCE_TOP_DIR}/../utils) +set(CMAKE_DEBUG_POSTFIX "d") + +# Generate the version strings +mark_as_advanced(BUILDNUMBER) +set(TSF_SHORT_VERSION "${TSF_MAJOR_VERSION}.${TSF_MINOR_VERSION}.${TSF_REV_VERSION}") +add_definitions(-DBUILDNUMBER=${BUILDNUMBER}) +string(REPLACE "\"" "" TSF_BUILDNUMBER "${BUILDNUMBER}") +set(TSF_FULL_VERSION "${TSF_MAJOR_VERSION}.${TSF_MINOR_VERSION}.${TSF_REV_VERSION}.${TSF_BUILDNUMBER}") +set(TSF_FULL_VERSION_COMMAS "${TSF_MAJOR_VERSION},${TSF_MINOR_VERSION},${TSF_REV_VERSION},${TSF_BUILDNUMBER}") + +set(TSF_MAJOR_MINOR "${TSF_MAJOR_VERSION}.${TSF_MINOR_VERSION}") +set(TSF_MAJOR_MINOR_DASH "${TSF_MAJOR_VERSION}-${TSF_MINOR_VERSION}") + +#PolicyFileName=policy.4.2 +set(TSF_POLICYFILENAME "policy.${TSF_MAJOR_MINOR}") +if(TSF_INCPOLICY) + set(TSF_INCLUDE_POLICY "True") +else(TSF_INCPOLICY) + set(TSF_INCLUDE_POLICY "") +endif(TSF_INCPOLICY) + +if(MSVC_IDE) + set(TS_CONFIG "${TS_VS_CONFIG}") +else() + set(TS_CONFIG ${CMAKE_BUILD_TYPE}) +endif() +string(TOUPPER "${TS_CONFIG}" TS_CONFIG) + +# determine the CPP compiler platform +if(FORCE_X86) + set(TS_X_PLATFORM "x86") + set(TS_PLATFORM "win32") + set(TS_OS_PLATFORM "x86") + set(TS_64BIT_PATH_PART_INSTALLER "") + set(TS_LIB_DIR_SUFFIX "") +elseif(FORCE_X64) + set(TS_X_PLATFORM "x64") + set(TS_PLATFORM "x64") + set(TS_OS_PLATFORM "amd64") + set(TS_64BIT_PATH_PART_INSTALLER "64") + set(TS_LIB_DIR_SUFFIX "64") +elseif(CMAKE_CL_64) + set(TS_X_PLATFORM "x64") + set(TS_PLATFORM "x64") + set(TS_OS_PLATFORM "amd64") + set(TS_64BIT_PATH_PART_INSTALLER "64") + set(TS_LIB_DIR_SUFFIX "64") +else(CMAKE_CL_64) + set(TS_X_PLATFORM "x86") + set(TS_PLATFORM "win32") + set(TS_OS_PLATFORM "x86") + set(TS_64BIT_PATH_PART_INSTALLER "") + set(TS_LIB_DIR_SUFFIX "") +endif(FORCE_X86) + +set(TS_TOOLSET "OTHER") +if(CMAKE_COMPILER_IS_GNUCC) + set(TS_TOOLSET "gcc") +elseif(WIN32) + if(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v140") + set(TS_TOOLSET "vc14") + set(TS_TOOLSET_NUMBER "140") + set(TS_VS_VERSION "VS2013") + set(MSVC2015 1) + set(TS_FRAMEWORK_NODOT v451) + set(TS_FRAMEWORK v4.5.1) + elseif(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v120") + set(TS_TOOLSET "vc12") + set(TS_TOOLSET_NUMBER "120") + set(TS_VS_VERSION "VS2013") + set(MSVC2013 1) + set(TS_FRAMEWORK_NODOT v451) + set(TS_FRAMEWORK v4.5.1) + elseif(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v110") + set(TS_TOOLSET "vc11") + set(TS_TOOLSET_NUMBER "110") + set(TS_VS_VERSION "VS2012") + set(MSVC2012 1) + set(TS_FRAMEWORK_NODOT v45) + set(TS_FRAMEWORK v4.5) + elseif(CMAKE_VS_PLATFORM_TOOLSET STREQUAL "v100") + set(TS_TOOLSET "vc10") + set(TS_TOOLSET_NUMBER "100") + set(TS_VS_VERSION "VS2010") + set(MSVC2010 1) + set(TS_FRAMEWORK_NODOT v40) + set(TS_FRAMEWORK v4.0) + elseif(MSVC10) + set(TS_TOOLSET "vc10") + set(TS_TOOLSET_NUMBER "100") + set(TS_VS_VERSION "VS2010") + set(MSVC2010 1) + set(TS_FRAMEWORK_NODOT v40) + set(TS_FRAMEWORK v4.0) + elseif(MSVC14) + set(TS_TOOLSET "vc14") + set(TS_TOOLSET_NUMBER "140") + set(TS_VS_VERSION "VS2015") + set(MSVC2015 1) + set(TS_FRAMEWORK_NODOT v451) + set(TS_FRAMEWORK v4.5.1) + elseif(MSVC12) + set(TS_TOOLSET "vc12") + set(TS_TOOLSET_NUMBER "120") + set(TS_VS_VERSION "VS2013") + set(MSVC2013 1) + set(TS_FRAMEWORK_NODOT v451) + set(TS_FRAMEWORK v4.5.1) + elseif(MSVC11) + set(TS_TOOLSET "vc11") + set(TS_TOOLSET_NUMBER "110") + set(TS_VS_VERSION "VS2012") + set(MSVC2012 1) + set(TS_FRAMEWORK_NODOT v45) + set(TS_FRAMEWORK v4.5) + else() + set(TS_TOOLSET "vc10") + set(TS_TOOLSET_NUMBER "100") + set(TS_VS_VERSION "VS2010") + set(MSVC2010 1) + set(TS_FRAMEWORK_NODOT v40) + set(TS_FRAMEWORK v4.0) + endif() +endif(CMAKE_COMPILER_IS_GNUCC) + +if(MSVC_IDE) + set(TS_VS_CONFIGURATION "${TS_VS_CONFIG}") +else() + set(TS_VS_CONFIGURATION ${CMAKE_BUILD_TYPE}) +endif() + +# if(MSVC) + # set (SDK_PARENT c:/TecSec) +# else() + # set (SDK_PARENT /usr/TecSec) +# endif() + +# if(WIN32) + # STRING(REPLACE "/" "\\" NATIVE_SDK_PARENT ${SDK_PARENT}) + # #STRING(REPLACE "/" "\\" NATIVE_SDK_ROOT ${SDK_ROOT}) +# else() + # set(NATIVE_SDK_PARENT ${SDK_PARENT}) + # #set(NATIVE_SDK_ROOT ${SDK_ROOT}) +# endif() + +IF(BUILD_SXS) + SET(SxSPart _SxS) +ELSE(BUILD_SXS) + SET(SxSPart "") +ENDIF(BUILD_SXS) + +IF (NOT CMAKE_BUILD_TYPE) +SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type determining compiler flags" FORCE ) +ENDIF (NOT CMAKE_BUILD_TYPE) + +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DDEBUG -D_DEBUG") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -D_RELEASE") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -D_RELEASE") + +if (UNIX) + if (NOT CMAKE_INSTALL_PREFIX) + SET(CMAKE_INSTALL_PREFIX "/usr/local") + ENDIF(NOT CMAKE_INSTALL_PREFIX) +endif(UNIX) + +include(machineBitSize) + +MESSAGE(STATUS "Machine type: ${MACHINETYPE}") + +# ---------------------------------------------------------------- +if(CMAKE_COMPILER_IS_GNUCC) +include(compiler_tecsec_gnucc) +endif() #CMAKE_COMPILER_IS_GNUCC + +# ---------------------------------------------------------------- +if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") +include (compiler_tecsec_darwin) +endif () # Darwin + +# ---------------------------------------------------------------- +IF(WIN32 AND NOT CMAKE_COMPILER_IS_GNUCC) +include(compiler_tecsec_msvc) +endif () # WIN32 AND NOT CMAKE_COMPILER_IS_GNUCC + +# ---------------------------------------------------------------- +if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + +add_definitions(-DLINUX) +add_definitions(-DXP_UNIX) + +if(NOT MINGW) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") +endif(NOT MINGW) + +# This link describes all of the various feature flags such as largefiles +# and posix vs gnu vs bsd. +# http://www.gnu.org/s/libc/manual/html_node/Feature-Test-Macros.html +# +# I added _GNU_SOURCE go get declarations for qsort_r() on Linux. +# +# _GNU_SOURCE causes the definition of strerror_r() to change, see sg_error.c +# +add_definitions(-D_GNU_SOURCE) + +# TODO this should probably call getconf LFS_CFLAGS instead +# +# TODO _GNU_SOURCE also turns on the LFS stuff, so we may not +# TODO need to explicitly set them below. +add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64) + +set(SG_OS_LIBS uuid pthread dl m) + +endif () # "${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" + +IF(WIN32) + SET(GMOCK_ROOT S:/ThirdParty/redist) + SET(GTEST_ROOT S:/ThirdParty/redist) + SET(ZLIB_ROOT S:/ThirdParty/redist) + SET(BZ2_ROOT S:/ThirdParty/redist) + SET(HARU_ROOT S:/ThirdParty/redist) + SET(BOOST_ROOT S:/ThirdParty/redist) +ENDIF(WIN32) + + +include (tecsec_base_macros) + +if(MSVC) + # Remove the /Fd option so that precompiled headers work + string(REPLACE "/Fd" "" CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") + string(REPLACE "/Fd" "" CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}") +endif(MSVC) + +include (tecsec_installdirs) diff --git a/cmakemodules/uninstall.cmake.in b/cmakemodules/uninstall.cmake.in new file mode 100644 index 0000000..be16197 --- /dev/null +++ b/cmakemodules/uninstall.cmake.in @@ -0,0 +1,54 @@ +# Copyright (c) 2015, TecSec, Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of TecSec nor the names of the contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# ALTERNATIVELY, provided that this notice is retained in full, this product +# may be distributed under the terms of the GNU General Public License (GPL), +# in which case the provisions of the GPL apply INSTEAD OF those given above. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find the install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +cmake_policy(PUSH) +cmake_policy(SET CMP0007 OLD) +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +list(REVERSE files) +foreach (file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + if (EXISTS "$ENV{DESTDIR}${file}") + execute_process( + COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval + ) + if(NOT ${rm_retval} EQUAL 0) + message(FATAL_ERROR "Problem removing file \"$ENV{DESTDIR}${file}\"") + endif(NOT ${rm_retval} EQUAL 0) + else(EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif(EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) +cmake_policy(POP) \ No newline at end of file diff --git a/configure.cmd b/configure.cmd new file mode 100644 index 0000000..287dd44 --- /dev/null +++ b/configure.cmd @@ -0,0 +1,3 @@ +call npm install nan --save +call npm install cmake-js --save +cmake-js configure -D \ No newline at end of file diff --git a/package.json b/package.json index 03cd46e..5013201 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,16 @@ "private": true, "gypfile": true, "dependencies": { - "bindings": "~1.2.1" + "bindings": "~1.2.1", + "cmake-js": "^3.0.0", + "nan": "^2.1.0" + }, + "scripts": { + "install": "cmake-js compile" + }, + "cmake-js": { + "runtime": "node", + "runtimeVersion": "0.12.2", + "arch": "ia32" } } diff --git a/src/Favorite.cpp b/src/Favorite.cpp new file mode 100644 index 0000000..3542cce --- /dev/null +++ b/src/Favorite.cpp @@ -0,0 +1,271 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include "Favorite.h" +#include "Session.h" +#include + +using namespace v8; + +Favorite::Favorite() { +} + +Favorite::~Favorite() { +} + +static tsAscii StringToTsAscii(v8::Local& string) +{ + tsAscii tmp; + const int length = string->Utf8Length() + 1; // Add one for trailing zero byte. + tmp.resize(length); + string->WriteOneByte((uint8_t*)tmp.rawData(), /* start */ 0, length); + return tmp; +} + +bool Favorite::encryptFile(Session* session, const tsAscii& sourceFile, bool compress, const tsAscii& encryptedFile) +{ + std::shared_ptr fileOps; + std::shared_ptr header; + std::shared_ptr status; + tsAscii inputFile(sourceFile.c_str()); + tsAscii outputFile(encryptedFile.c_str()); + + if (!isReady()) + throw tsAscii("Favorite not ready"); + + if (!InitializeCmsHeader()) + return false; + + if (xp_GetFileAttributes(inputFile) == XP_INVALID_FILE_ATTRIBUTES || xp_IsDirectory(inputFile)) + { + throw (tsAscii() << "File -> " << inputFile << " <- does not exist Encrypt operation aborted"); + } + + status = ::ServiceLocator()->Finish(new StatusClass()); + + if (!(fileOps = CreateFileVEILOperationsObject()) || + !(fileOps->SetStatusInterface(status)) || + !(fileOps->SetSession(session->handle()))) + { + throw tsAscii("An error occurred while building the file encryptor. The CKM Runtime may be damaged."); + } + + // Create output file name based on the input file name + if (outputFile.size() == 0) + { + outputFile = inputFile; + outputFile += ".ckm"; + } + if (!(header = ::ServiceLocator()->get_instance("/CmsHeader")) || !header->FromBytes(handle()->headerData())) + { + throw tsAscii("An error occurred while building the encryption header."); + } + + // Indicate compression is desired. + if (compress) + { + header->SetCompressionType(ct_zLib); + } + else + { + header->SetCompressionType(ct_None); + } + if (header->GetEncryptionAlgorithmID() == TS_ALG_INVALID) + header->SetEncryptionAlgorithmID(TS_ALG_AES_GCM_256); + + if (!(fileOps->EncryptFileAndStreams(inputFile.c_str(), outputFile.c_str(), header, compress ? ct_zLib : ct_None, + header->GetEncryptionAlgorithmID(), OIDtoID(header->GetDataHashOID().ToOIDString().c_str()), + header->HasHeaderSigningPublicKey(), true, + (Alg2Mode(header->GetEncryptionAlgorithmID()) == CKM_SymMode_GCM || + Alg2Mode(header->GetEncryptionAlgorithmID()) == CKM_SymMode_CCM) ? + TS_FORMAT_CMS_ENC_AUTH : TS_FORMAT_CMS_CT_HASHED, + false, header->GetPaddingType(), 5000000))) + { + throw tsAscii("The encryption failed."); + return false; + } + + return true; +} +tsData Favorite::encryptData(Session* session, const tsData& sourceData, bool compress) +{ + if (!isReady()) + throw tsAscii("Favorite not ready"); + + tsData encData; + + if (sourceData.size() == 0) + { + return tsData(); + } + + if (!InitializeCmsHeader()) + return tsData(); + + std::shared_ptr fileOps; + std::shared_ptr status; + std::shared_ptr header; + + if (!session->handle()) + { + throw tsAscii("Session not ready"); + } + + status = ::ServiceLocator()->Finish(new StatusClass()); + + if (!(fileOps = CreateFileVEILOperationsObject()) || + !(fileOps->SetStatusInterface(status)) || + !(fileOps->SetSession(session->handle()))) + { + throw tsAscii("An error occurred while building the file encryptor. The CKM Runtime may be damaged."); + } + if (!(header = ::ServiceLocator()->get_instance("/CmsHeader")) || !header->FromBytes(handle()->headerData())) + { + throw tsAscii("An error occurred while building the encryption header."); + } + + if (!header) + { + throw tsAscii("The favorite is invalid or incomplete."); + } + + // Indicate compression is desired. + if (compress) + { + header->SetCompressionType(ct_zLib); + } + else + { + header->SetCompressionType(ct_None); + } + if (header->GetEncryptionAlgorithmID() == TS_ALG_INVALID) + header->SetEncryptionAlgorithmID(TS_ALG_AES_GCM_256); + + if (!(fileOps->EncryptCryptoData(sourceData, encData, header, compress ? ct_zLib : ct_None, + header->GetEncryptionAlgorithmID(), OIDtoID(header->GetDataHashOID().ToOIDString().c_str()), + header->HasHeaderSigningPublicKey(), true, + (Alg2Mode(header->GetEncryptionAlgorithmID()) == CKM_SymMode_GCM || + Alg2Mode(header->GetEncryptionAlgorithmID()) == CKM_SymMode_CCM) ? + TS_FORMAT_CMS_ENC_AUTH : TS_FORMAT_CMS_CT_HASHED, + false, header->GetPaddingType(), 5000000))) + { + throw tsAscii("Encryption failed."); + } + + return encData; +} + +Nan::NAN_METHOD_RETURN_TYPE Favorite::Encrypt_File(Nan::NAN_METHOD_ARGS_TYPE info) +{ + Favorite* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 4 || !info[0]->IsObject() || !info[1]->IsString() || !info[2]->IsBoolean() || !info[3]->IsString()) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + Session* session = ObjectWrap::Unwrap(info[0]->ToObject()); + auto sourceFile = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + auto destFile = Nan::To(info[3]).ToLocalChecked(); + try + { + bool retVal = obj->encryptFile(session, *Nan::Utf8String(sourceFile), compress->BooleanValue(), *Nan::Utf8String(destFile)); + info.GetReturnValue().Set(retVal); + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } +} +Nan::NAN_METHOD_RETURN_TYPE Favorite::EncryptData(Nan::NAN_METHOD_ARGS_TYPE info) +{ + Favorite* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 3 || !info[0]->IsObject() || (!info[1]->IsString() && !info[1]->IsObject()) || !info[2]->IsBoolean()) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + Session* session = ObjectWrap::Unwrap(info[0]->ToObject()); + try + { + if (info[1]->IsObject()) + { + auto sourceData = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + + char* content = node::Buffer::Data(sourceData); + int contentlength = node::Buffer::Length(sourceData); + + tsData retVal = obj->encryptData(session, tsData((uint8_t*)content, contentlength), compress->BooleanValue()); + info.GetReturnValue().Set(Nan::CopyBuffer((char*)retVal.c_str(), retVal.size()).ToLocalChecked()); + } + else + { + auto sourceData = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + tsData retVal = obj->encryptData(session, tsAscii(*Nan::Utf8String(sourceData)).Base64ToData(), compress->BooleanValue()); + info.GetReturnValue().Set(Nan::New(retVal.ToBase64().c_str()).ToLocalChecked()); + } + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } +} +Nan::NAN_METHOD_RETURN_TYPE Favorite::EncryptString(Nan::NAN_METHOD_ARGS_TYPE info) +{ + Favorite* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 3 || !info[0]->IsObject() || !info[1]->IsString() || !info[2]->IsBoolean()) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + Session* session = ObjectWrap::Unwrap(info[0]->ToObject()); + auto sourceFile = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + try + { + tsData retVal = obj->encryptData(session, tsAscii(*Nan::Utf8String(sourceFile)).ToUTF8Data(), compress->BooleanValue()); + info.GetReturnValue().Set(Nan::New(retVal.ToBase64().c_str()).ToLocalChecked()); + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } +} diff --git a/src/Favorite.h b/src/Favorite.h new file mode 100644 index 0000000..233f54c --- /dev/null +++ b/src/Favorite.h @@ -0,0 +1,249 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __FAVORITE_H__ +#define __FAVORITE_H__ + +#include "OpenVEIL.h" +#include "CmsHeader.h" +#include "FileVEILSupport.h" +#include + +class Session; + +class Favorite : public Nan::ObjectWrap +{ +public: + static NAN_MODULE_INIT(Init) + { + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Favorite").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + Nan::SetPrototypeMethod(tpl, "release", Release); + Nan::SetPrototypeMethod(tpl, "encryptFile", Encrypt_File); + Nan::SetPrototypeMethod(tpl, "encryptData", EncryptData); + Nan::SetPrototypeMethod(tpl, "encryptString", EncryptString); + + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("favoriteId").ToLocalChecked(), GetFavoriteId, SetFavoriteId); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("enterpriseId").ToLocalChecked(), GetEnterpriseId, SetEnterpriseId); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("favoriteName").ToLocalChecked(), GetFavoriteName, SetFavoriteName); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("tokenSerialNumber").ToLocalChecked(), GetTokenSerialNumber, SetTokenSerialNumber); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("headerData").ToLocalChecked(), GetHeaderData, SetHeaderData); + + constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); + target->Set(Nan::New("Favorite").ToLocalChecked(), tpl->GetFunction()); + } + + explicit Favorite(std::shared_ptr val) : _value(val) {} + + std::shared_ptr handle() { return _value; } + void handle(std::shared_ptr val) { _value = val; } + + bool encryptFile(Session* session, const tsAscii& sourceFile, bool compress, const tsAscii& encryptedFile); + tsData encryptData(Session* session, const tsData& sourceData, bool compress); + + static inline Nan::Persistent & constructor() { + static Nan::Persistent my_constructor; + return my_constructor; + } + +private: + explicit Favorite(); + ~Favorite(); + + std::shared_ptr _value; + + void release() + { + _value.reset(); + } + + tsAscii getFavoriteId() + { + if (!isReady()) + return ""; + else + return ToString()(_value->favoriteId()); + } + void setFavoriteId(const tsAscii& setTo) + { + if (!isReady()) + return; + _value->favoriteId(ToGuid()(setTo)); + } + + tsAscii getEnterpriseId() + { + if (!isReady()) + return ""; + else + return ToString()(_value->enterpriseId()); + } + void setEnterpriseId(const tsAscii& setTo) + { + if (!isReady()) + return; + _value->enterpriseId(ToGuid()(setTo)); + } + + tsAscii getFavoriteName() + { + if (!isReady()) + return ""; + else + return _value->favoriteName(); + } + void setFavoriteName(const tsAscii& setTo) + { + if (!isReady()) + return; + _value->favoriteName(setTo); + } + + tsData getTokenSerialNumber() + { + if (!isReady()) + return ""; + else + return _value->tokenSerialNumber(); + } + void setTokenSerialNumber(const tsData& setTo) + { + if (!isReady()) + return; + _value->tokenSerialNumber(setTo); + } + + tsData headerData() + { + if (!isReady()) + return ""; + else + return _value->headerData(); + } + void headerData(const tsData& setTo) + { + if (!isReady()) + return; + _value->headerData(setTo); + } + + + + bool isReady() + { + return !!_value; + } + + static NAN_METHOD(New) + { + if (info.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + //double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + Favorite* obj = new Favorite(/*value*/); + obj->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + } + else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + v8::Local argv[argc] = { info[0] }; + v8::Local cons = Nan::New(constructor()); + info.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } + } + static NAN_METHOD(Release) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + obj->release(); + } + static NAN_GETTER(GetFavoriteId) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->getFavoriteId().c_str()).ToLocalChecked()); + } + static NAN_SETTER(SetFavoriteId) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + auto id = Nan::To(value).ToLocalChecked(); + obj->setFavoriteId(*Nan::Utf8String(id)); + } + static NAN_GETTER(GetEnterpriseId) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->getEnterpriseId().c_str()).ToLocalChecked()); + } + static NAN_SETTER(SetEnterpriseId) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + auto id = Nan::To(value).ToLocalChecked(); + obj->setEnterpriseId(*Nan::Utf8String(id)); + } + static NAN_GETTER(GetFavoriteName) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->getFavoriteName().c_str()).ToLocalChecked()); + } + static NAN_SETTER(SetFavoriteName) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + auto name = Nan::To(value).ToLocalChecked(); + obj->setFavoriteName(*Nan::Utf8String(name)); + } + static NAN_GETTER(GetTokenSerialNumber) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->getTokenSerialNumber().ToHexString().c_str()).ToLocalChecked()); + } + static NAN_SETTER(SetTokenSerialNumber) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + auto serial = Nan::To(value).ToLocalChecked(); + obj->setTokenSerialNumber(tsAscii(*Nan::Utf8String(serial)).HexToData()); + } + static NAN_GETTER(GetHeaderData) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->headerData().ToBase64().c_str()).ToLocalChecked()); + } + static NAN_SETTER(SetHeaderData) + { + Favorite* obj = ObjectWrap::Unwrap(info.This()); + auto data = Nan::To(value).ToLocalChecked(); + obj->headerData(tsAscii(*Nan::Utf8String(data)).HexToData()); + } + static NAN_METHOD(Encrypt_File); + static NAN_METHOD(EncryptData); + static NAN_METHOD(EncryptString); + +}; + +#endif // __FAVORITE_H__ \ No newline at end of file diff --git a/addon.cc b/src/GenericConnector.cpp similarity index 89% rename from addon.cc rename to src/GenericConnector.cpp index 0805fab..d8d4576 100644 --- a/addon.cc +++ b/src/GenericConnector.cpp @@ -28,13 +28,14 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -#include -#include "OpenVEILAddon.h" +#include "GenericConnector.h" using namespace v8; -void InitAll(Handle exports) { - OpenVEILAddon::Init(exports); +GenericConnector::GenericConnector() { + _value = ::ServiceLocator()->try_get_instance("/KeyVEILConnector"); +} + +GenericConnector::~GenericConnector() { } -NODE_MODULE(OpenVEIL, InitAll) diff --git a/src/GenericConnector.h b/src/GenericConnector.h new file mode 100644 index 0000000..604aa4c --- /dev/null +++ b/src/GenericConnector.h @@ -0,0 +1,245 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __GENERICCONNECTOR_H__ +#define __GENERICCONNECTOR_H__ + +#include "OpenVEIL.h" +#include + +class GenericConnector : public Nan::ObjectWrap +{ +public: + static NAN_MODULE_INIT(Init) + { + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("GenericConnector").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + Nan::SetPrototypeMethod(tpl, "connect", Connect); + Nan::SetPrototypeMethod(tpl, "disconnect", Disconnect); + + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("isConnected").ToLocalChecked(), IsConnected); + Nan::SetPrototypeMethod(tpl, "sendJsonRequest", SendJsonRequest); + Nan::SetPrototypeMethod(tpl, "sendRequest", SendRequest); + + + constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); + target->Set(Nan::New("GenericConnector").ToLocalChecked(), tpl->GetFunction()); + } + +private: + explicit GenericConnector(); + ~GenericConnector(); + + std::shared_ptr _value; + ConnectionStatus connect(const tsAscii& url, const tsAscii& username, const tsAscii& password) + { + if (!isReady()) + { + return connStatus_NoServer; + } + + return _value->genericConnectToServer(url, username, password); + } + void disconnect() + { + if (isConnected()) + { + _value->disconnect(); + } + } + bool isConnected() + { + if (isReady()) + { + return _value->isConnected(); + } + else + { + return false; + } + } + bool sendJsonRequest(const tsAscii& verb, const tsAscii& cmd, const tsAscii& inData, tsAscii& outData, int& status) + { + if (isReady()) + { + JSONObject inObj, outObj; + + if (inObj.FromJSON(inData.c_str()) <= 0) + return false; + + bool retVal = _value->sendJsonRequest(verb, cmd, inObj, outObj, status); + outData = outObj.ToJSON(); + return retVal; + } + else + { + return false; + } + } + bool sendRequest(const tsAscii& verb, const tsAscii& cmd, const tsAscii& inData, tsAscii& outData, int& status) + { + if (isReady()) + { + tsData inObj, outObj; + + inObj = inData.Base64ToData(); + + bool retVal = _value->sendRequest(verb, cmd, inObj, outObj, status); + outData = outObj.ToBase64(); + return retVal; + } + else + { + return false; + } + } + bool isReady() + { + return !!_value; + } + + + + static NAN_METHOD(New) + { + if (info.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + //double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + GenericConnector* obj = new GenericConnector(/*value*/); + obj->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + } + else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + v8::Local argv[argc] = { info[0] }; + v8::Local cons = Nan::New(constructor()); + info.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } + } + static NAN_METHOD(Connect) + { + GenericConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto url = Nan::To(info[0]).ToLocalChecked(); + auto username = Nan::To(info[1]).ToLocalChecked(); + auto password = Nan::To(info[2]).ToLocalChecked(); + switch (obj->connect(*Nan::Utf8String(url), *Nan::Utf8String(username), *Nan::Utf8String(password))) + { + case connStatus_Connected: + info.GetReturnValue().Set(Nan::New("Connected").ToLocalChecked()); + break; + case connStatus_NoServer: + info.GetReturnValue().Set(Nan::New("NoServer").ToLocalChecked()); + break; + case connStatus_BadAuth: + info.GetReturnValue().Set(Nan::New("BadAuth").ToLocalChecked()); + break; + case connStatus_WrongProtocol: + info.GetReturnValue().Set(Nan::New("WrongProtocol").ToLocalChecked()); + break; + case connStatus_UrlBad: + info.GetReturnValue().Set(Nan::New("UrlBad").ToLocalChecked()); + break; + default: + info.GetReturnValue().Set(Nan::New("unknown").ToLocalChecked()); + break; + } + } + static NAN_METHOD(Disconnect) + { + GenericConnector* obj = ObjectWrap::Unwrap(info.This()); + obj->disconnect(); + } + static NAN_GETTER(IsConnected) + { + GenericConnector* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->isConnected()); + } + static NAN_METHOD(SendJsonRequest) + { + GenericConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto verb = Nan::To(info[0]).ToLocalChecked(); + auto cmd = Nan::To(info[1]).ToLocalChecked(); + auto inData = Nan::To(info[2]).ToLocalChecked(); + + tsAscii outData; + int status = 0; + bool retVal = obj->sendJsonRequest(*Nan::Utf8String(verb), *Nan::Utf8String(cmd), *Nan::Utf8String(inData), outData, status); + + v8::Local outObj = Nan::New(); + outObj->Set(Nan::New("status").ToLocalChecked(), Nan::New(status)); + outObj->Set(Nan::New("retVal").ToLocalChecked(), Nan::New(retVal)); + outObj->Set(Nan::New("outData").ToLocalChecked(), Nan::New(outData.c_str()).ToLocalChecked()); + + info.GetReturnValue().Set(outObj); + } + static NAN_METHOD(SendRequest) + { + GenericConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto verb = Nan::To(info[0]).ToLocalChecked(); + auto cmd = Nan::To(info[1]).ToLocalChecked(); + auto inData = Nan::To(info[2]).ToLocalChecked(); + + tsAscii outData; + int status = 0; + bool retVal = obj->sendRequest(*Nan::Utf8String(verb), *Nan::Utf8String(cmd), *Nan::Utf8String(inData), outData, status); + + v8::Local outObj = Nan::New(); + outObj->Set(Nan::New("status").ToLocalChecked(), Nan::New(status)); + outObj->Set(Nan::New("retVal").ToLocalChecked(), Nan::New(retVal)); + outObj->Set(Nan::New("outData").ToLocalChecked(), Nan::New(outData.c_str()).ToLocalChecked()); + + info.GetReturnValue().Set(outObj); + } + static inline Nan::Persistent & constructor() { + static Nan::Persistent my_constructor; + return my_constructor; + } +}; + +#endif // __GENERICCONNECTOR_H__ \ No newline at end of file diff --git a/src/KeyVEILConnector.cpp b/src/KeyVEILConnector.cpp new file mode 100644 index 0000000..b7844eb --- /dev/null +++ b/src/KeyVEILConnector.cpp @@ -0,0 +1,265 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include "KeyVEILConnector.h" +#include "Favorite.h" +#include "Token.h" + +using namespace v8; + +static tsAscii StringToTsAscii(v8::Local& string) +{ + tsAscii tmp; + const int length = string->Utf8Length() + 1; // Add one for trailing zero byte. + tmp.resize(length); + string->WriteOneByte((uint8_t*)tmp.rawData(), /* start */ 0, length); + return tmp; +} + + +KeyVEILConnector::KeyVEILConnector() { + _value = ::ServiceLocator()->try_get_instance("/KeyVEILConnector"); +} + +KeyVEILConnector::~KeyVEILConnector() { +} + +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::TokenByIndex(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto index = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr tokPtr = obj->_value->token(index->Int32Value()); + if (!tokPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Token::constructor()); + auto tokObj = cons->NewInstance(); + Token* tok = ObjectWrap::Unwrap(tokObj); + tok->handle(tokPtr); + info.GetReturnValue().Set(tokObj); +} +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::TokenByName(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto name = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr tokPtr = obj->_value->token(tsAscii(*Nan::Utf8String(name))); + if (!tokPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Token::constructor()); + auto tokObj = cons->NewInstance(); + Token* tok = ObjectWrap::Unwrap(tokObj); + tok->handle(tokPtr); + info.GetReturnValue().Set(tokObj); +} +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::TokenBySerialNumber(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto serial = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr tokPtr = obj->_value->token(tsData(tsAscii(*Nan::Utf8String(serial)).HexToData())); + if (!tokPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Token::constructor()); + auto tokObj = cons->NewInstance(); + Token* tok = ObjectWrap::Unwrap(tokObj); + tok->handle(tokPtr); + info.GetReturnValue().Set(tokObj); +} +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::TokenById(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr tokPtr = obj->_value->token(ToGuid()(tsAscii(*Nan::Utf8String(id)))); + if (!tokPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Token::constructor()); + auto tokObj = cons->NewInstance(); + Token* tok = ObjectWrap::Unwrap(tokObj); + tok->handle(tokPtr); + info.GetReturnValue().Set(tokObj); +} + +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::FavoriteByIndex(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto index = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr favPtr = obj->_value->favorite(index->Int32Value()); + if (!favPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Favorite::constructor()); + auto favObj = cons->NewInstance(); + Favorite* fav = ObjectWrap::Unwrap(favObj); + fav->handle(favPtr); + info.GetReturnValue().Set(favObj); +} + +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::FavoriteByName(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto name = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr favPtr = obj->_value->favorite(tsAscii(*Nan::Utf8String(name))); + if (!favPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Favorite::constructor()); + auto favObj = cons->NewInstance(); + Favorite* fav = ObjectWrap::Unwrap(favObj); + fav->handle(favPtr); + info.GetReturnValue().Set(favObj); +} +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::FavoriteById(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + + std::shared_ptr favPtr = obj->_value->favorite(ToGuid()(tsAscii(*Nan::Utf8String(id)))); + if (!favPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Favorite::constructor()); + auto favObj = cons->NewInstance(); + Favorite* fav = ObjectWrap::Unwrap(favObj); + fav->handle(favPtr); + info.GetReturnValue().Set(favObj); +} +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::TokenForEnterprise(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 2) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + auto index = Nan::To(info[1]).ToLocalChecked(); + + std::shared_ptr tokPtr = obj->_value->tokenForEnterprise(ToGuid()(tsAscii(*Nan::Utf8String(id))), index->Int32Value()); + if (!tokPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Token::constructor()); + auto tokObj = cons->NewInstance(); + Token* tok = ObjectWrap::Unwrap(tokObj); + tok->handle(tokPtr); + info.GetReturnValue().Set(tokObj); +} + +Nan::NAN_METHOD_RETURN_TYPE KeyVEILConnector::FavoriteForEnterprise(Nan::NAN_METHOD_ARGS_TYPE info) +{ + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 2) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + auto index = Nan::To(info[1]).ToLocalChecked(); + + std::shared_ptr favPtr = obj->_value->favoriteForEnterprise(ToGuid()(tsAscii(*Nan::Utf8String(id))), index->Int32Value()); + if (!favPtr) + { + Nan::ThrowRangeError("Unable to retrieve that token"); + return; + } + + auto cons = Nan::New(Favorite::constructor()); + auto favObj = cons->NewInstance(); + Favorite* fav = ObjectWrap::Unwrap(favObj); + fav->handle(favPtr); + info.GetReturnValue().Set(favObj); +} diff --git a/src/KeyVEILConnector.h b/src/KeyVEILConnector.h new file mode 100644 index 0000000..7993e68 --- /dev/null +++ b/src/KeyVEILConnector.h @@ -0,0 +1,479 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __KEYVEILCONNECTOR_H__ +#define __KEYVEILCONNECTOR_H__ + +#include "OpenVEIL.h" +#include + +class KeyVEILConnector : public Nan::ObjectWrap +{ +public: + static NAN_MODULE_INIT(Init) + { + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("KeyVEILConnector").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + // Prototype + Nan::SetPrototypeMethod(tpl, "connect", Connect); + Nan::SetPrototypeMethod(tpl, "disconnect", Disconnect); + + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("isConnected").ToLocalChecked(), IsConnected); + Nan::SetPrototypeMethod(tpl, "sendJsonRequest", SendJsonRequest); + Nan::SetPrototypeMethod(tpl, "sendRequest", SendRequest); + + + Nan::SetPrototypeMethod(tpl, "refresh", Refresh); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("tokenCount").ToLocalChecked(), TokenCount); + Nan::SetPrototypeMethod(tpl, "tokenByIndex", TokenByIndex); + Nan::SetPrototypeMethod(tpl, "tokenByName", TokenByName); + Nan::SetPrototypeMethod(tpl, "tokenBySerialNumber", TokenBySerialNumber); + Nan::SetPrototypeMethod(tpl, "tokenById", TokenById); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("favoriteCount").ToLocalChecked(), FavoriteCount); + Nan::SetPrototypeMethod(tpl, "favoriteByIndex", FavoriteByIndex); + Nan::SetPrototypeMethod(tpl, "favoriteByName", FavoriteByName); + Nan::SetPrototypeMethod(tpl, "favoriteById", FavoriteById); + Nan::SetPrototypeMethod(tpl, "createFavorite_token", CreateFavorite_token); + Nan::SetPrototypeMethod(tpl, "createFavorite_serial", CreateFavorite_serial); + Nan::SetPrototypeMethod(tpl, "createFavorite_id", CreateFavorite_id); + Nan::SetPrototypeMethod(tpl, "deleteFavorite", DeleteFavorite); + Nan::SetPrototypeMethod(tpl, "updateFavoriteName", UpdateFavoriteName); + Nan::SetPrototypeMethod(tpl, "updateFavorite", UpdateFavorite); + Nan::SetPrototypeMethod(tpl, "tokenCountForEnterpriseId", TokenCountForEnterpriseId); + Nan::SetPrototypeMethod(tpl, "tokenForEnterprise", TokenForEnterprise); + Nan::SetPrototypeMethod(tpl, "favoriteCountForEnterprise", FavoriteCountForEnterprise); + Nan::SetPrototypeMethod(tpl, "favoriteForEnterprise", FavoriteForEnterprise); + + + + constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); + target->Set(Nan::New("KeyVEILConnector").ToLocalChecked(), tpl->GetFunction()); + } + +private: + explicit KeyVEILConnector(); + ~KeyVEILConnector(); + + std::shared_ptr _value; + ConnectionStatus connect(const tsAscii& url, const tsAscii& username, const tsAscii& password) + { + if (!isReady()) + { + return connStatus_NoServer; + } + + return _value->connect(url, username, password); + } + void disconnect() + { + if (isConnected()) + { + _value->disconnect(); + } + } + bool isConnected() + { + if (isReady()) + { + return _value->isConnected(); + } + else + { + return false; + } + } + bool sendJsonRequest(const tsAscii& verb, const tsAscii& cmd, const tsAscii& inData, tsAscii& outData, int& status) + { + if (isReady()) + { + JSONObject inObj, outObj; + + if (inObj.FromJSON(inData.c_str()) <= 0) + return false; + + bool retVal = _value->sendJsonRequest(verb, cmd, inObj, outObj, status); + outData = outObj.ToJSON(); + return retVal; + } + else + { + return false; + } + } + bool sendRequest(const tsAscii& verb, const tsAscii& cmd, const tsAscii& inData, tsAscii& outData, int& status) + { + if (isReady()) + { + tsData inObj, outObj; + + inObj = inData.Base64ToData(); + + bool retVal = _value->sendRequest(verb, cmd, inObj, outObj, status); + outData = outObj.ToBase64(); + return retVal; + } + else + { + return false; + } + } + bool isReady() + { + return !!_value; + } + + bool refresh() + { + if (!isReady()) + return false; + return _value->refresh(); + } + size_t tokenCount() + { + if (!isReady()) + return 0; + return _value->tokenCount(); + } + size_t favoriteCount() + { + if (!isReady()) + return 0; + return _value->favoriteCount(); + } + tsAscii createFavorite(Token* token, const tsData& headerData, const tsAscii& name) + { + if (!isReady()) + return ""; + return ToString()(_value->CreateFavorite(token->handle(), headerData, name)); + } + tsAscii createFavorite(const tsAscii& tokenId, const tsData& headerData, const tsAscii& name) + { + if (!isReady()) + return ""; + return ToString()(_value->CreateFavorite(ToGuid()(tokenId), headerData, name)); + } + tsAscii createFavorite(const tsData& tokenSerial, const tsData& headerData, const tsAscii& name) + { + if (!isReady()) + return ""; + return ToString()(_value->CreateFavorite(tokenSerial, headerData, name)); + } + bool deleteFavorite(const tsAscii& id) + { + if (!isReady()) + return false; + return _value->DeleteFavorite(ToGuid()(id)); + } + bool updateFavoriteName(const tsAscii& id, const tsAscii& name) + { + if (!isReady()) + return false; + return _value->UpdateFavoriteName(ToGuid()(id), name); + } + bool updateFavorite(const tsAscii& id, const tsData& setTo) + { + if (!isReady()) + return false; + return _value->UpdateFavorite(ToGuid()(id), setTo); + } + size_t tokenCountForEnterpriseId(const tsAscii& enterpriseId) + { + if (!isReady()) + return 0; + return _value->tokenCountForEnterprise(ToGuid()(enterpriseId)); + } + size_t favoriteCountForEnterprise(const tsAscii& enterpriseId) + { + if (!isReady()) + return 0; + return _value->favoriteCountForEnterprise(ToGuid()(enterpriseId)); + } + + + static NAN_METHOD(New) + { + if (info.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + //double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + KeyVEILConnector* obj = new KeyVEILConnector(/*value*/); + obj->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + } + else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + v8::Local argv[argc] = { info[0] }; + v8::Local cons = Nan::New(constructor()); + info.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } + } + static NAN_METHOD(Connect) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto url = Nan::To(info[0]).ToLocalChecked(); + auto username = Nan::To(info[1]).ToLocalChecked(); + auto password = Nan::To(info[2]).ToLocalChecked(); + switch (obj->connect(*Nan::Utf8String(url), *Nan::Utf8String(username), *Nan::Utf8String(password))) + { + case connStatus_Connected: + info.GetReturnValue().Set(Nan::New("Connected").ToLocalChecked()); + break; + case connStatus_NoServer: + info.GetReturnValue().Set(Nan::New("NoServer").ToLocalChecked()); + break; + case connStatus_BadAuth: + info.GetReturnValue().Set(Nan::New("BadAuth").ToLocalChecked()); + break; + case connStatus_WrongProtocol: + info.GetReturnValue().Set(Nan::New("WrongProtocol").ToLocalChecked()); + break; + case connStatus_UrlBad: + info.GetReturnValue().Set(Nan::New("UrlBad").ToLocalChecked()); + break; + default: + info.GetReturnValue().Set(Nan::New("unknown").ToLocalChecked()); + break; + } + } + static NAN_METHOD(Disconnect) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + obj->disconnect(); + } + static NAN_GETTER(IsConnected) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->isConnected()); + } + static NAN_METHOD(SendJsonRequest) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto verb = Nan::To(info[0]).ToLocalChecked(); + auto cmd = Nan::To(info[1]).ToLocalChecked(); + auto inData = Nan::To(info[2]).ToLocalChecked(); + + tsAscii outData; + int status = 0; + bool retVal = obj->sendJsonRequest(*Nan::Utf8String(verb), *Nan::Utf8String(cmd), *Nan::Utf8String(inData), outData, status); + + v8::Local outObj = Nan::New(); + outObj->Set(Nan::New("status").ToLocalChecked(), Nan::New(status)); + outObj->Set(Nan::New("retVal").ToLocalChecked(), Nan::New(retVal)); + outObj->Set(Nan::New("outData").ToLocalChecked(), Nan::New(outData.c_str()).ToLocalChecked()); + + info.GetReturnValue().Set(outObj); + } + static NAN_METHOD(SendRequest) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto verb = Nan::To(info[0]).ToLocalChecked(); + auto cmd = Nan::To(info[1]).ToLocalChecked(); + auto inData = Nan::To(info[2]).ToLocalChecked(); + + tsAscii outData; + int status = 0; + bool retVal = obj->sendRequest(*Nan::Utf8String(verb), *Nan::Utf8String(cmd), *Nan::Utf8String(inData), outData, status); + + v8::Local outObj = Nan::New(); + outObj->Set(Nan::New("status").ToLocalChecked(), Nan::New(status)); + outObj->Set(Nan::New("retVal").ToLocalChecked(), Nan::New(retVal)); + outObj->Set(Nan::New("outData").ToLocalChecked(), Nan::New(outData.c_str()).ToLocalChecked()); + + info.GetReturnValue().Set(outObj); + } + + + static NAN_METHOD(Refresh) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->refresh()); + } + static NAN_GETTER(TokenCount) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->tokenCount()); + } + static NAN_METHOD(TokenByIndex); + static NAN_METHOD(TokenByName); + static NAN_METHOD(TokenBySerialNumber); + static NAN_METHOD(TokenById); + static NAN_GETTER(FavoriteCount) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->favoriteCount()); + } + static NAN_METHOD(FavoriteByIndex); + static NAN_METHOD(FavoriteByName); + static NAN_METHOD(FavoriteById); + static NAN_METHOD(CreateFavorite_token) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3 || !info[0]->IsObject() || !info[1]->IsObject()) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto tokObj = Nan::To(info[0]).ToLocalChecked(); + auto headerData = Nan::To(info[1]).ToLocalChecked(); + auto name = Nan::To(info[2]).ToLocalChecked(); + + Token* tok = ObjectWrap::Unwrap(info[0]); + + char* content = node::Buffer::Data(headerData); + int contentlength = node::Buffer::Length(headerData); + + info.GetReturnValue().Set(Nan::New(obj->createFavorite(tok, tsData((uint8_t*)content, contentlength), *Nan::Utf8String(name)).c_str()).ToLocalChecked()); + } + static NAN_METHOD(CreateFavorite_serial) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3 || !info[1]->IsObject()) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto serial = Nan::To(info[0]).ToLocalChecked(); + auto headerData = Nan::To(info[1]).ToLocalChecked(); + auto name = Nan::To(info[2]).ToLocalChecked(); + + Token* tok = ObjectWrap::Unwrap(info[0]); + + char* content = node::Buffer::Data(headerData); + int contentlength = node::Buffer::Length(headerData); + + info.GetReturnValue().Set(Nan::New(obj->createFavorite(tsAscii(*Nan::Utf8String(serial)).HexToData(), tsData((uint8_t*)content, contentlength), *Nan::Utf8String(name)).c_str()).ToLocalChecked()); + } + static NAN_METHOD(CreateFavorite_id) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 3 || !info[1]->IsObject()) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + auto headerData = Nan::To(info[1]).ToLocalChecked(); + auto name = Nan::To(info[2]).ToLocalChecked(); + + Token* tok = ObjectWrap::Unwrap(info[0]); + + char* content = node::Buffer::Data(headerData); + int contentlength = node::Buffer::Length(headerData); + + info.GetReturnValue().Set(Nan::New(obj->createFavorite(tsAscii(*Nan::Utf8String(id)), tsData((uint8_t*)content, contentlength), *Nan::Utf8String(name)).c_str()).ToLocalChecked()); + } + static NAN_METHOD(DeleteFavorite) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + info.GetReturnValue().Set(obj->deleteFavorite(*Nan::Utf8String(id))); + } + static NAN_METHOD(UpdateFavoriteName) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 2) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + auto name = Nan::To(info[1]).ToLocalChecked(); + info.GetReturnValue().Set(obj->updateFavoriteName(*Nan::Utf8String(id), *Nan::Utf8String(name))); + } + static NAN_METHOD(UpdateFavorite) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 2) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + auto data = Nan::To(info[1]).ToLocalChecked(); + + char* content = node::Buffer::Data(data); + int contentlength = node::Buffer::Length(data); + + info.GetReturnValue().Set(obj->updateFavorite(*Nan::Utf8String(id), tsData((uint8_t*)content, contentlength))); + } + static NAN_METHOD(TokenCountForEnterpriseId) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + info.GetReturnValue().Set(obj->tokenCountForEnterpriseId(*Nan::Utf8String(id))); + } + static NAN_METHOD(TokenForEnterprise); + static NAN_METHOD(FavoriteCountForEnterprise) + { + KeyVEILConnector* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number of arguments"); + return; + } + auto id = Nan::To(info[0]).ToLocalChecked(); + info.GetReturnValue().Set(obj->favoriteCountForEnterprise(*Nan::Utf8String(id))); + } + static NAN_METHOD(FavoriteForEnterprise); + + static inline Nan::Persistent & constructor() { + static Nan::Persistent my_constructor; + return my_constructor; + } +}; + +#endif // __OPENVEILADDON_H__ \ No newline at end of file diff --git a/src/Session.cpp b/src/Session.cpp new file mode 100644 index 0000000..b3a81a5 --- /dev/null +++ b/src/Session.cpp @@ -0,0 +1,53 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include "Session.h" + +using namespace v8; + +Session::Session() { +} + +Session::~Session() { +} + +Nan::NAN_METHOD_RETURN_TYPE Session::Duplicate(Nan::NAN_METHOD_ARGS_TYPE info) +{ + Session* obj = ObjectWrap::Unwrap(info.This()); + + std::shared_ptr sessionPtr = obj->handle()->Duplicate(); + + v8::Local cons = Nan::New(constructor()); + v8::Local sessObj = Nan::NewInstance(cons).ToLocalChecked(); + Session* sess = ObjectWrap::Unwrap(sessObj); + sess->handle(sessionPtr); + info.GetReturnValue().Set(sessObj); +} + diff --git a/src/Session.h b/src/Session.h new file mode 100644 index 0000000..9eaf42f --- /dev/null +++ b/src/Session.h @@ -0,0 +1,502 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __SESSION_H__ +#define __SESSION_H__ + +#include "OpenVEIL.h" +#include +#include "Favorite.h" + +// Used in the file encrypt and decrypt routines +class StatusClass : public IFileVEILOperationStatus, public tsmod::IObject +{ +public: + StatusClass() {} + virtual bool Status(const tsAscii& taskName, int taskNumber, int ofTaskCount, int taskPercentageDone) + { + //if (g_doStatus) + //{ + // ts_out << "Task " << taskNumber << " of " << ofTaskCount << " " << taskName << " " << taskPercentageDone << "%" << endl; + //} + return true; + } + virtual void FailureReason(const tsAscii&failureText) + { + //ERROR(failureText); + } + +private: + virtual ~StatusClass() {} +}; + + +class Session : public Nan::ObjectWrap +{ +public: + static NAN_MODULE_INIT(Init) + { + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Session").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + Nan::SetPrototypeMethod(tpl, "release", Release); + Nan::SetPrototypeMethod(tpl, "close", Close); + Nan::SetPrototypeMethod(tpl, "login", Login); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("isLoggedIn").ToLocalChecked(), GetIsLoggedIn); + Nan::SetPrototypeMethod(tpl, "logout", Logout); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("profile").ToLocalChecked(), GetProfile); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("isLocked").ToLocalChecked(), GetIsLocked); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("retriesLeft").ToLocalChecked(), GetRetriesLeft); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("isValid").ToLocalChecked(), GetIsValid); + Nan::SetPrototypeMethod(tpl, "duplicate", Duplicate); + Nan::SetPrototypeMethod(tpl, "encryptFileUsingFavorite", EncryptFileUsingFavorite); + Nan::SetPrototypeMethod(tpl, "decryptFile", Decrypt_File); + Nan::SetPrototypeMethod(tpl, "encryptDataUsingFavorite", EncryptDataUsingFavorite); + Nan::SetPrototypeMethod(tpl, "decryptData", DecryptData); + Nan::SetPrototypeMethod(tpl, "encryptStringUsingFavorite", EncryptStringUsingFavorite); + Nan::SetPrototypeMethod(tpl, "decryptString", DecryptString); + + constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); + target->Set(Nan::New("Session").ToLocalChecked(), tpl->GetFunction()); + } + explicit Session(std::shared_ptr val) : _value(val) {} + + std::shared_ptr handle() { return _value; } + void handle(std::shared_ptr val) { _value = val; } + + static inline Nan::Persistent & constructor() { + static Nan::Persistent my_constructor; + return my_constructor; + } + +private: + explicit Session(); + ~Session(); + + std::shared_ptr _value; + + void release() + { + _value.reset(); + } + + void close() + { + if (!isReady()) + return; + _value->Close(); + } + LoginStatus login(const tsAscii& pin) + { + if (!isReady()) + return loginStatus_NoServer; + return _value->Login(pin); + } + bool isLoggedIn() + { + if (!isReady()) + return false; + return _value->IsLoggedIn(); + } + bool logout() + { + if (!isReady()) + return true; + return _value->Logout(); + } + //bool GenerateWorkingKey(Asn1::CTS::CkmCombineParameters& params, std::function headerCallback, tsData &WorkingKey); + //bool RegenerateWorkingKey(Asn1::CTS::CkmCombineParameters& params, tsData &WorkingKey); + tsAscii getProfile() + { + if (!isReady()) + return ""; + return _value->GetProfile()->toJSON().ToString(); + } + bool isLocked() + { + if (!isReady()) + return false; + return _value->IsLocked(); + } + size_t retriesLeft() + { + if (!isReady()) + return 0; + return _value->retriesLeft(); + } + bool isValid() + { + if (!isReady()) + return false; + return _value->IsValid(); + } + Session* duplicate() + { + if (!isReady()) + return nullptr; + + + return new Session(_value->Duplicate()); + } + bool encryptFileUsingFavorite(Favorite* fav, const tsAscii& sourceFile, bool compress, const tsAscii& encryptedFile) + { + if (!isReady()) + return false; + return fav->encryptFile(this, sourceFile, compress, encryptedFile); + } + bool decryptFile(const tsAscii& encryptedFile, const tsAscii& decryptedFile) + { + if (!isReady()) + throw tsAscii("Session not ready"); + + if (!InitializeCmsHeader()) + return false; + + std::shared_ptr fileOps; + std::shared_ptr status; + + if (xp_GetFileAttributes(encryptedFile) == XP_INVALID_FILE_ATTRIBUTES || xp_IsDirectory(encryptedFile)) + { + throw (tsAscii() << "File -> " << encryptedFile << " <- does not exist Decrypt operation aborted"); + } + + status = ::ServiceLocator()->Finish(new StatusClass()); + + if (!(fileOps = CreateFileVEILOperationsObject()) || + !(fileOps->SetStatusInterface(status)) || + !(fileOps->SetSession(handle()))) + { + throw tsAscii("An error occurred while building the file decryptor. The OpenVEIL installation may be damaged."); + } + + if (!fileOps->DecryptFileAndStreams(encryptedFile, decryptedFile)) + { + throw tsAscii("Decrypt failed."); + } + + return true; + } + tsData encryptDataUsingFavorite(Favorite* fav, const tsData& sourceData, bool compress) + { + if (!isReady()) + throw tsAscii("Session not ready"); + return fav->encryptData(this, sourceData, compress); + } + tsData decryptData(const tsData& encryptedData) + { + if (!isReady()) + throw tsAscii("Session not ready"); + + if (!InitializeCmsHeader()) + return tsData(); + + std::shared_ptr fileOps; + std::shared_ptr status; + tsData destData; + + status = ::ServiceLocator()->Finish(new StatusClass()); + + if (!(fileOps = CreateFileVEILOperationsObject()) || + !(fileOps->SetStatusInterface(status)) || + !(fileOps->SetSession(handle()))) + { + throw tsAscii("An error occurred while building the file decryptor. The OpenVEIL installation may be damaged."); + } + + if (!fileOps->DecryptCryptoData(encryptedData, destData)) + { + throw tsAscii("Decrypt failed."); + } + + return destData; + } + + + bool isReady() + { + return !!_value; + } + + static NAN_METHOD(New) + { + if (info.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + //double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + Session* obj = new Session(/*value*/); + obj->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + } + else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + v8::Local argv[argc] = { info[0] }; + v8::Local cons = Nan::New(constructor()); + info.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } + } + static NAN_METHOD(Release) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + obj->release(); + } + static NAN_METHOD(Close) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + obj->close(); + } + static NAN_METHOD(Login) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + auto pin = Nan::To(info[0]).ToLocalChecked(); + switch (obj->login(*Nan::Utf8String(pin))) + { + case loginStatus_Connected: + info.GetReturnValue().Set(Nan::New("Connected").ToLocalChecked()); + break; + case loginStatus_NoServer: + info.GetReturnValue().Set(Nan::New("NoServer").ToLocalChecked()); + break; + case loginStatus_BadAuth: + info.GetReturnValue().Set(Nan::New("BadAuth").ToLocalChecked()); + break; + default: + info.GetReturnValue().Set(Nan::New("unknown").ToLocalChecked()); + break; + } + } + static NAN_GETTER(GetIsLoggedIn) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->isLoggedIn()); + } + static NAN_METHOD(Logout) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->logout()); + } + static NAN_GETTER(GetProfile) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->getProfile().c_str()).ToLocalChecked()); + } + static NAN_GETTER(GetIsLocked) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->isLocked()); + } + static NAN_GETTER(GetRetriesLeft) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->retriesLeft()); + } + static NAN_GETTER(GetIsValid) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(obj->isValid()); + } + static NAN_METHOD(Duplicate); + static NAN_METHOD(EncryptFileUsingFavorite) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 4 || !info[0]->IsObject() || !info[1]->IsString() || !info[2]->IsBoolean() || !info[3]->IsString()) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + Favorite* fav = ObjectWrap::Unwrap(info[0]->ToObject()); + auto sourceFile = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + auto destFile = Nan::To(info[3]).ToLocalChecked(); + try + { + bool retVal = fav->encryptFile(obj, *Nan::Utf8String(sourceFile), compress->BooleanValue(), *Nan::Utf8String(destFile)); + info.GetReturnValue().Set(retVal); + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } + } + static NAN_METHOD(Decrypt_File) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 2) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + auto sourceFile = Nan::To(info[0]).ToLocalChecked(); + auto destFile = Nan::To(info[1]).ToLocalChecked(); + + try + { + bool retVal = obj->decryptFile(*Nan::Utf8String(sourceFile), *Nan::Utf8String(destFile)); + info.GetReturnValue().Set(retVal); + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } + } + static NAN_METHOD(EncryptDataUsingFavorite) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 3 || !info[0]->IsObject() || (!info[1]->IsString() && !info[1]->IsObject()) || !info[2]->IsBoolean()) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + try + { + Favorite* fav = ObjectWrap::Unwrap(info[0]->ToObject()); + if (info[1]->IsObject()) + { + auto sourceData = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + + char* content = node::Buffer::Data(sourceData); + int contentlength = node::Buffer::Length(sourceData); + + tsData retVal = fav->encryptData(obj, tsData((uint8_t*)content, contentlength), compress->BooleanValue()); + info.GetReturnValue().Set(Nan::CopyBuffer((char*)retVal.c_str(), retVal.size()).ToLocalChecked()); + } + else + { + auto sourceData = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + tsData retVal = fav->encryptData(obj, tsAscii(*Nan::Utf8String(sourceData)).Base64ToData(), compress->BooleanValue()); + info.GetReturnValue().Set(Nan::New(retVal.ToBase64().c_str()).ToLocalChecked()); + } + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } + } + static NAN_METHOD(EncryptStringUsingFavorite) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 3 || !info[0]->IsObject() || !info[1]->IsString() || !info[2]->IsBoolean()) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + + Favorite* fav = ObjectWrap::Unwrap(info[0]->ToObject()); + auto sourceData = Nan::To(info[1]).ToLocalChecked(); + auto compress = Nan::To(info[2]).ToLocalChecked(); + try + { + tsData retVal = fav->encryptData(obj, tsAscii(*Nan::Utf8String(sourceData)).ToUTF8Data(), compress->BooleanValue()); + info.GetReturnValue().Set(Nan::New(retVal.ToBase64().c_str()).ToLocalChecked()); + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } + } + static NAN_METHOD(DecryptData) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + try + { + if (info[0]->IsObject()) + { + auto sourceData = Nan::To(info[0]).ToLocalChecked(); + + char* content = node::Buffer::Data(sourceData); + int contentlength = node::Buffer::Length(sourceData); + + tsData retVal = obj->decryptData(tsData((uint8_t*)content, contentlength)); + info.GetReturnValue().Set(Nan::CopyBuffer((char*)retVal.c_str(), retVal.size()).ToLocalChecked()); + } + else + { + auto sourceData = Nan::To(info[0]).ToLocalChecked(); + + tsData retVal = obj->decryptData(tsAscii(*Nan::Utf8String(sourceData)).Base64ToData()); + info.GetReturnValue().Set(Nan::New(retVal.ToBase64().c_str()).ToLocalChecked()); + } + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } + } + static NAN_METHOD(DecryptString) + { + Session* obj = ObjectWrap::Unwrap(info.This()); + + if (info.Length() < 1) + { + Nan::ThrowTypeError("Wrong number or type of arguments"); + return; + } + auto sourceData = Nan::To(info[0]).ToLocalChecked(); + + try + { + tsData retVal = obj->decryptData(tsAscii(*Nan::Utf8String(sourceData)).Base64ToData()); + info.GetReturnValue().Set(Nan::New(retVal.ToUtf8String().c_str()).ToLocalChecked()); + } + catch (tsAscii& ex) + { + Nan::ThrowError(ex.c_str()); + return; + } + } +}; + + +#endif // __SESSION_H__ \ No newline at end of file diff --git a/src/Token.cpp b/src/Token.cpp new file mode 100644 index 0000000..a6dedab --- /dev/null +++ b/src/Token.cpp @@ -0,0 +1,65 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include "Token.h" +#include "Session.h" + +using namespace v8; + +//Persistent Token::constructor; + +Token::Token() { +} + +Token::~Token() { +} + +static tsAscii StringToTsAscii(v8::Local& string) +{ + tsAscii tmp; + const int length = string->Utf8Length() + 1; // Add one for trailing zero byte. + tmp.resize(length); + string->WriteOneByte((uint8_t*)tmp.rawData(), /* start */ 0, length); + return tmp; +} + +Nan::NAN_METHOD_RETURN_TYPE Token::OpenSession(Nan::NAN_METHOD_ARGS_TYPE info) +{ + Token* obj = ObjectWrap::Unwrap(info.This()); + + std::shared_ptr sessionPtr = obj->handle()->openSession(); + + v8::Local cons = Nan::New(Session::constructor()); + v8::Local sessObj = Nan::NewInstance(cons).ToLocalChecked(); + Session* sess = ObjectWrap::Unwrap(sessObj); + sess->handle(sessionPtr); + info.GetReturnValue().Set(sessObj); +} + diff --git a/src/Token.h b/src/Token.h new file mode 100644 index 0000000..6c9cd69 --- /dev/null +++ b/src/Token.h @@ -0,0 +1,216 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#ifndef __TOKEN_H__ +#define __TOKEN_H__ + +#include "OpenVEIL.h" +#include + +class Token : public Nan::ObjectWrap +{ +public: + static NAN_MODULE_INIT(Init) + { + v8::Local tpl = Nan::New(New); + tpl->SetClassName(Nan::New("Token").ToLocalChecked()); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + + Nan::SetPrototypeMethod(tpl, "release", Release); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("tokenName").ToLocalChecked(), GetTokenName, SetTokenName); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("serialNumber").ToLocalChecked(), SerialNumber); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("id").ToLocalChecked(), Id); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("enterpriseName").ToLocalChecked(), EnterpriseName); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("memberName").ToLocalChecked(), MemberName); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("tokenType").ToLocalChecked(), TokenType); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("enterpriseId").ToLocalChecked(), EnterpriseId); + Nan::SetAccessor(tpl->InstanceTemplate(), Nan::New("memberId").ToLocalChecked(), MemberId); + + Nan::SetPrototypeMethod(tpl, "openSession", OpenSession); + + constructor().Reset(Nan::GetFunction(tpl).ToLocalChecked()); + target->Set(Nan::New("Token").ToLocalChecked(), tpl->GetFunction()); + } + + explicit Token(std::shared_ptr val) : _value(val) {} + + std::shared_ptr handle() { return _value; } + void handle(std::shared_ptr val) { _value = val; } + + static inline Nan::Persistent & constructor() { + static Nan::Persistent my_constructor; + return my_constructor; + } + +private: + explicit Token(); + ~Token(); + + std::shared_ptr _value; + + void release() + { + _value.reset(); + } + + tsAscii getTokenName() + { + if (!isReady()) + return ""; + return _value->tokenName(); + } + void setTokenName(const tsAscii& setTo) + { + if (!isReady()) + return; + _value->tokenName(setTo); + } + tsData serialNumber() + { + if (!isReady()) + return tsData(); + return _value->serialNumber(); + } + tsAscii id() + { + if (!isReady()) + return ""; + return ToString()(_value->id()); + } + tsAscii enterpriseName() + { + if (!isReady()) + return ""; + return _value->enterpriseName(); + } + tsAscii memberName() + { + if (!isReady()) + return ""; + return _value->memberName(); + } + tsAscii tokenType() + { + if (!isReady()) + return ""; + return _value->tokenType(); + } + tsAscii enterpriseId() + { + if (!isReady()) + return ""; + return ToString()(_value->enterpriseId()); + } + tsAscii memberId() + { + if (!isReady()) + return ""; + return ToString()(_value->memberId()); + } + + bool isReady() + { + return !!_value; + } + + static NAN_METHOD(New) + { + if (info.IsConstructCall()) { + // Invoked as constructor: `new MyObject(...)` + //double value = args[0]->IsUndefined() ? 0 : args[0]->NumberValue(); + Token* obj = new Token(/*value*/); + obj->Wrap(info.This()); + info.GetReturnValue().Set(info.This()); + } + else { + // Invoked as plain function `MyObject(...)`, turn into construct call. + const int argc = 1; + v8::Local argv[argc] = { info[0] }; + v8::Local cons = Nan::New(constructor()); + info.GetReturnValue().Set(cons->NewInstance(argc, argv)); + } + } + static NAN_METHOD(Release) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + obj->release(); + } + + static NAN_GETTER(GetTokenName) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->getTokenName().c_str()).ToLocalChecked()); + } + static NAN_SETTER(SetTokenName) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + auto name = Nan::To(value).ToLocalChecked(); + obj->setTokenName(*Nan::Utf8String(name)); + } + static NAN_GETTER(SerialNumber) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->serialNumber().ToHexString().c_str()).ToLocalChecked()); + } + static NAN_GETTER(Id) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->id().c_str()).ToLocalChecked()); + } + static NAN_GETTER(EnterpriseName) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->enterpriseName().c_str()).ToLocalChecked()); + } + static NAN_GETTER(MemberName) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->memberName().c_str()).ToLocalChecked()); + } + static NAN_GETTER(TokenType) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->tokenType().c_str()).ToLocalChecked()); + } + static NAN_GETTER(EnterpriseId) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->enterpriseId().c_str()).ToLocalChecked()); + } + static NAN_GETTER(MemberId) + { + Token* obj = ObjectWrap::Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(obj->memberId().c_str()).ToLocalChecked()); + } + static NAN_METHOD(OpenSession); + +}; + +#endif // __TOKEN_H__ \ No newline at end of file diff --git a/src/addon.cc b/src/addon.cc new file mode 100644 index 0000000..190afe3 --- /dev/null +++ b/src/addon.cc @@ -0,0 +1,116 @@ +// Copyright (c) 2015, TecSec, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of TecSec nor the names of the contributors may be +// used to endorse or promote products derived from this software +// without specific prior written permission. +// +// ALTERNATIVELY, provided that this notice is retained in full, this product +// may be distributed under the terms of the GNU General Public License (GPL), +// in which case the provisions of the GPL apply INSTEAD OF those given above. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL TECSEC BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +#include +#include +#include "KeyVEILConnector.h" +#include "GenericConnector.h" +#include "Favorite.h" +#include "Token.h" +#include "Session.h" + +using namespace v8; + + +// (function(exports) { +// function copyOwnFrom(target, source) { +// Object.getOwnPropertyNames(source).forEach(function(propName) { +// Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName)); +// }); +// return target; +// } +// +// function Symbol(name, props) { +// this.name = name; +// if (props) { +// copyOwnFrom(this, props); +// } +// Object.freeze(this); +// } +// /** We don’t want the mutable Object.prototype in the prototype chain */ +// Symbol.prototype = Object.create(null); +// Symbol.prototype.constructor = Symbol; +// /** +// * Without Object.prototype in the prototype chain, we need toString() +// * in order to display symbols. +// */ +// Symbol.prototype.toString = function() { +// return "|" + this.name + "|"; +// }; +// Object.freeze(Symbol.prototype); +// +// Enum = function(obj) { +// if (arguments.length == = 1 && obj != = null && typeof obj == = "object") { +// Object.keys(obj).forEach(function(name) { +// this[name] = new Symbol(name, obj[name]); +// }, this); +// } +// else { +// Array.prototype.forEach.call(arguments, function(name) { +// this[name] = new Symbol(name); +// }, this); +// } +// Object.freeze(this); +// } +// Enum.prototype.symbols = function() { +// return Object.keys(this).map(function(key) { +// return this[key]; +// }, this); +// } +// Enum.prototype.contains = function(sym) { +// if (!sym instanceof Symbol) +// return false; +// return this[sym.name] == = sym; +// } +// exports.Enum = Enum; +// exports.Symbol = Symbol; +// }(typeof exports === "undefined" ? this.enums = {} : exports)); + + + + +NAN_MODULE_INIT(InitAll) +{ + //Local obj; + //const char* k = "HEADERS_RECEIVED"; + //int v = 1; + //obj->Set(v8::String::NewSymbol(k), v8::Int32::New(v), ReadOnly); // Use PropertyAttribute ReadOnly so that value won't be changed by javascript. + + KeyVEILConnector::Init(target); + GenericConnector::Init(target); + Favorite::Init(target); + Token::Init(target); + Session::Init(target); + node::AtExit([](void*) { + TerminateVEILSystem(); + }); +} + +NODE_MODULE(OpenVEIL, InitAll)