Category: development

  • Delven is a Domain Specific Language (DSL) designed for mining content

    Delven is a Domain Specific Language (DSL) designed for mining content from static and dynamic sources, It closely resembles SQL with features borrowed from other popular languages.

    This documentation is your guide to an advanced new world of real-time data connectivity.

    • To get an idea of what Delven is and how it can benefit your organization, visit the Introduction Section page.
    • New users and experienced users alike may refer to the Syntax section for all the information you need to create robust queries.
    • For new users, the Tutorial provides an introduction to basic query writing skills and a page of sample queries to get you started.
    • Programmers interested in embedding Delven within their application should visit the API Reference.
  • hoplin.io A lightweight RabbitMQ client for Java (built on top of rabittmq java client)

    A lightweight RabbitMQ client for Java (built on top of rabittmq java client)

    Documentation and project available at GitHub repo
    https://github.com/gregbugaj/hoplin.io

    To make working with RabbitMQ as simple as possible with minimum dependencies.

    Minimal dependencies, simple configuration and API.

    • Subscriber client
    • Publisher client
    • Async RPC Client

    Creating simple RabbitMQ client can be done in couple different ways. 

    The simplest way with minimal configuration 

    ExchangeClient client = ExchangeClient.topic(RabbitMQOptions.from("host=localhost")) 

    This creates new Exchange client bound to a Topic exchange.

    We can also specify which queue and which routing key we want to handle.

    final RabbitMQOptions options = RabbitMQOptions.from("host=localhost");
    final ExchangeClient client = ExchangeClient.topic(options, "my.exchange", "log.critical", "log.critical.*")
    

    For complete control we can use the Exchange to Queue Binding builder.

    ExchangeClient clientFromBinding(final String exchange, final String queue, final String routingKey)
        {
            final Binding binding = BindingBuilder
                    .bind(queue)
                    .to(new TopicExchange(exchange))
                    .withAutoAck(true)
                    .withPrefetchCount(1)
                    .withPublisherConfirms(true)
                    .with(routingKey)
                    .build();
    
            return ExchangeClient.topic(options(), binding);
        }

    This is the most flexible method as it allows us to control all the aspect of how messages are handled.

    Publishing and receiving messages is simple as well. Both methods provide number of overloaded methods to provide different levels of flexibility.

    // Publish message
    client.publish(new LogDetail("Msg : " + System.nanoTime()));
    
    // Consume message
     client.subscribe(LogDetail.class, msg-> log.info("Message received [{}]", msg));

    Here is example that includes both the Publisher and Subscriber

    public class SamePublisherConsumerExample extends BaseExample
    {
        private static final Logger log = LoggerFactory.getLogger(SamePublisherConsumerExample.class);
    
        private static final String EXCHANGE = "topic_logs";
    
        public static void main(final String... args) throws InterruptedException
        {
            log.info("Starting producer/consumer for exchange : {}", EXCHANGE);
            final ExchangeClient client = ExchangeClient.topic(options(), EXCHANGE);
            client.subscribe(LogDetail.class, SamePublisherConsumerExample::handle);
    
            for(int i = 0; i < 5; ++i)
            {
                client.publish(createMessage("info"), "log.info.info");
                client.publish(createMessage("debug"), "log.info.debug");
    
                Thread.sleep(1000L);
            }
        }
    
        private static void handle(final LogDetail msg)
        {
            log.info("Incoming msg : {}", msg);
        }
    
        private static LogDetail createMessage(final String level)
        {
          return new LogDetail("Msg : " + System.nanoTime(), level);
        }
    
    }

  • Extended GIT Information in bash PS1

    Extended GIT Information in bash PS1

    This will generate shell similar to this :

    Multiline version:

    ┌──┤ greg: ~/dev/discovery/discovery-agent │ master  ≡  !1 +2 -2  ≡ 2 weeks ago
    └── λ 
    

    Format `branch ≡ changes additions deletions ≡ last commit`
    Example `master ≡ !1 +2 -2 ≡ 2 weeks ago`

    Since we are interested in interactive shells only we will edit `/etc/profile` and add the following

    # Get branch name 
    parse_git_branch() {
        # git branch | grep -Po '(?<=\*\s)(.*)'	
        local branch=$(git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ \1/')
        # When there is no initial commit, git branch will not return any branches, use a fallback method
        if [ -z "$branch" ]; then 
             branch=$(git status | grep -iPo '(?<=On branch\s)(.*)')
        fi
        echo $branch
    }
    
    parse_git_status() { 
        # changes to existing files
        # 0 = Changed Files, 1 = Additions, 2 = Deletions
        local gitstat=$(git diff --shortstat 2> /dev/null | grep -Po '\d')
        if [ -z "$gitstat" ]; then
    	gitstat="0 0 0"
        fi
       
        # replate \n with blanks
        gitstat=$(echo "$gitstat" | tr '\n' ' ')
        # untracted(??) or added(A) files
        local gitfiles=$(git status --untracked-files=all -s 2> /dev/null | grep -E '??|A' | wc -l)
        echo "$gitstat $gitfiles"
    }
    
    parse_git_hascommit() {
        val=$(git log 2> /dev/null | grep -iPo 'does not have')
        echo "result :: $val"
        if [ -z "$val" ]; then
          echo 0
          return 0
        fi
    
        echo 1
    }
    
    git_status_ps1() {
    	green_light="\e[38;5;82m"                                             
    	red="\e[91m"       
    	blue="\e[34m"
    	reset="\e[0m"      
    
    	inrepo=$(git rev-parse --is-inside-work-tree 2>/dev/null)         
    	if [ -z "$inrepo" ]; then 
    	   exit
            fi
    
    	#hascommit=$(parse_git_hascommit)
    	#echo "has :: $hascommit"i
    	# can't get time unless we have a commit
    
            # capture error 'fatal: your current branch 'master' does not have any commits yet' and don't display time
    	gittime=$(git log -1 --format=%cr 2> /dev/null)                                  	
            gitstat=$(parse_git_status)                                       
    	IFS=' ' read -r -a array <<< $gitstat                               
    
    	if [ -z "${array[0]}" ]; then                                         
    		array[0]=0     
    		array[1]=0     
    		array[2]=0     
    	fi  
    
    	branch_color=$green_light
    	if [ "${array[0]}" -gt "0" ]; then
    	   branch_color=$red
    	fi
    
    	if [ -z "$gittime" ]; then
    	   gittime="never"
    	fi 
            GIT_PS1="$branch_color$(parse_git_branch) $reset ≡ $green_light ~${array[3]}  !${array[0]} +${array[1]} $red-${array[2]} $reset  ≡  $gittime"
    	echo -e $GIT_PS1
    }
    
    
    PS1='┌──┤ \[\033[01;32m\]\u:\[\033[00m\] '
    PS1=$PS1'\[\033[01;34m\]\w\e[0m │ $(git_status_ps1)\n└──  λ '
    
    

    GIST

  • Counting transitions in a bit string

    We need to count a number of transitions in a bit string from 0->1 and 1->0. I needed this in order to determine Uniform Descriptor in Local Binary Patterns(LBP)

    Samples

    0000 0000  (0 Transitions : Uniform)    0x0
    1110 0011  (2 Transitions : Uniform)    0xE3
    0101 0000  (4 Transitions : NonUniform) 0x50
    0000 1010  (4 Transitions : NonUniform) 0xA
    0000 1001  (3 Transitions : NonUniform) 0x9
    

    Sample run (0xE3)

    0x      e3 :      227 :: 00000000000000000000000011100011
    0x      71 :      113 :: 00000000000000000000000001110001
    0x      92 :      146 :: 00000000000000000000000010010010
    Transition : 3
    

    Implemenation

    We are going to shift the value to the right and then XOR it with the original value to get the number of transitions. From there we going to use population count to get the count of the on bits.

    XOR Truth table

    INPUT	         OUTPUT
    -----------------------
    A	B	A XOR B
    0	0	0
    0	1	1
    1	0	1
    1	1	0
    
    template  void bitstr(const T& out) noexcept;
    template  int  popcnt(const T& val) noexcept;
    
    int main()
    {
        // Uniform descriptors
        // 0000 0000  (0 Transitions : Uniform)    0x0
        // 1110 0011  (2 Transitions : Uniform)    0xE3
        // 0101 0000  (4 Transitions : NonUniform) 0x50
        // 0000 1010  (4 Transitions : NonUniform) 0xA
        // 0000 1001  (3 Transitions : NonUniform) 0x9
    
        int a = 0xE3;
        int b = a >> 1;
        int c = a ^ b;
        int count = popcnt(c);
    
        bitstr(a);
        bitstr(b);
        bitstr(c);
    
        std::cout << "Transition : " <<count; return="" 0;="" }="" template="" <class="" t="">
    int popcnt(const T& val) noexcept
    {
        int bitcount;
        __asm__ ("popcnt %1, %1" : "=r" (bitcount) : "0" (val));
        return bitcount;
    }
    
    template 
    void bitstr(const T& out) noexcept
    {
        std::bitset bs(out);
        auto val =  static_cast(out);
        std::cout << "0x"
                  << std::setw(8) << std::hex << val << " : "
                  << std::setw(8) << std::dec << val<< " :: " << bs << std::endl;
    }
    </count;>

    Gist

  • Fingerprint cannot be generated while adding new ssh key in GitLab

    This applies to Windows only machines.

    I have GitLab running and was adding a new ‘ssh key’ from windows that was generated using a standard ssk-keygen command but was reciving following error:

    “Fingerprint cannot be generated”

    Command used to generate key:

     ssh-keygen -t rsa -C "gbugaj@localhost" -b 4096
    

    This produces a key in ‘id_rsa.pub’ file, from there I cated that file and copies the content of if by ‘HIGHLIGHTING’ directly in the command window.

    This is the result that got when pasted it

    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDuer2ZkTKwsirssZTBaJiyr/GpALglr6X9Ct2cysvgYs05SEvz+B66US4bFv5IVwiOEXJ51oR0EF0/oDv4Juq1zzvydX44rdKFwlL7Qq7Uezxw4FCJotn/wZqpuaScNszP8/gvZY82j9HCYmITFWobwk1JGvQnezbZ
    KsaUtUEQwnptYbWvOZ9yNRRzwkntafOBS2l18wJNl6bjHHUJ6NIzRMudvd7/AjqP5qWL3GjJ9ecyHU0Dox3fIAfzlMRhKCQswPos7i35GWtLBzaOfeqJ2iZA2eGjfh1cGW71hyvO72+rxjjXk3uUvSqFP+WWSrt8VdJJqXfhk0RFqDxcUku6fRWeALp0qWna6Qm8/CbF
    rw0t0s0bF557GqaJCIyMEqj+OVMpcMYCTStnjuTNM8OIz/A3BCJbwt9GsojyFUYesfA0i/4tt9MPYAfcPxO914IYn3mq7Qcvq7RgTJPgM8SGY+SIpACjFKaF6wOf91oa105PcPY4yvISLa40GivN0K871yjo/2Jwq6w6ZE601LD0FngWhrfKejueKucvNvYtdR/aX7LL
    Oq6md0HK6ybIGKJH2qph3+GJP/AUAf85bhWe1mPw3woZ28bWjo+Kp5zeTJqtd6QTDWTkDftsQJcmMgT43lViJBqChTTA/oGiXiV62PMKMeMCDaTYNkuZZvLE8Q== gbugaj@localhost
    

    As you see here lines are split, this is the problem. To solve this we just need to open the file in some editor and copy it from there so all the text is on one line.

    ssh-rsa AAAB3NzaC1yc2EAAAADAQABAAACAQDuer2ZkTKwsirssZTBaJiyr/GpALglr6X9Ct2cysvgYs05SEvz+B66US4bFv5IVwiOEXJ51oR0EF0/oDv4Juq1zzvydX44rdKFwlL7Qq7Uezxw4FCJotn/wZqpuaScNszP8/gvZY82j9HCYmITFWobwk1JGvQnezbZ
    KsaUtUEQwnptYbWvOZ9yNRRzwkntafOBS2l18wJNl6bjHHUJ6NIzRMudvd7/AjqP5qWL3GjJ9ecyHU0Dox3fIAfzlMRhKCQswPos7i35GWtLBzaOfeqJ2iZA2eGjfh1cGW71hyvO72+rxjjXk3uUvSqFP+WWSrt8VdJJqXfhk0RFqDxcUku6fRWeALp0qWna6Qm8/CbFrw0t0s0bF557GqaJCIyMEqj+OVMpcMYCTStnjuTNM8OIz/A3BCJbwt9GsojyFUYesfA0i/4tt9MPYAfcPxO914IYn3mq7Qcvq7RgTJPgM8SGY+SIpACjFKaF6wOf91oa105PcPY4yvISLa40GivN0K871yjo/2Jwq6w6ZE601LD0FngWhrfKejueKucvNvYtdR/aX7LLOq6md0HK6ybIGKJH2qph3+GJP/AUAf85bhWe1mPw3woZ28bWjo+Kp5zeTJqtd6QTDWTkDftsQJcmMgT43lViJBqChTTA/oGiXiV62PMKMeMCDaTYNkuZZvLE8Q== gbugaj@localhost
    
  • Overloading by return value in C++

    Here we have a method that allows us to determine return parameter type using templates and operator overloading in C++. This is something that I needed for a project that I am working on where a method call would give me the expected type based on the return type.

    Usage

    There is two way of using this. First one is by calling the para method and second one is by invoking the conversion method directly parameter.
    Personally, I prefer the first one as this one allows me to use it with auto keyword.

    
    std::string p0   = param<std::string>(arguments, 0);
    auto        p0_a = param<std::string>(arguments, 0);
    
    int         p1   = param<int>(arguments, 1);
    auto        p1_a = param<int>(arguments, 1);
    
    // Invoking parameter conversion directly
    std::string p0_p = parameter(arguments, 0); 
    int         p1_p = parameter(arguments, 1);
    

    Implemenation

    struct parameter
    {
    	parameter(const CefV8ValueList & arguments, int index) 
    		:_arg (arguments.at(index)) 
    	{
    	};
    
    	operator std::string() { return _arg->GetStringValue().ToString(); }
    	operator int() { return _arg->GetIntValue();}
    	operator bool() { return _arg->GetBoolValue(); }
    	operator double() { return _arg->GetDoubleValue();}
    
    	CefRefPtr _arg;
    };
    
    template
    T param(const CefV8ValueList & arguments, int index)
    {
    	return parameter(arguments, index);
    }
    

    Reference :
    http://en.cppreference.com/w/cpp/language/cast_operator

  • EventEmitter

    Our EventEmitter in PhantomSQL is based on NodeJS version so they should be compatible. Here are couple examples on how to use the emitter.

    Basic usage of registering and listening to an event.

    "use strict";
    
    const {EventEmitter} = require('events');
    
    // Dump all the args
    em.on('hello-event', (...arg)=> {console.info("Hello event handler : " + arg)});
    // Handler without args
    em.on('hello-event', ()=> {console.info("Another handler")});
    // passed in arguments
    em.on('hello-event', (id, val)=> {console.info("Handler :"+id +", "+ val)});
    
    // emit event
    em.emit('hello-event', 123, 'ABC');
    

    A more typical example would be to extend via prototype.

    "use strict";
    const {EventEmitter} = require('events');
    
    function HelloService()
    {
    	// Extends via prototype
    	Object.setPrototypeOf(HelloService.prototype, EventEmitter.prototype);
    	
    	this.hello = function()
    	{
    		console.info("Hello service called");
    		this.emit('hello');
    	}
    }  
    
    const service = new HelloService();
    
    service.on('hello', ()=> {console.info("Hello Handler called")});
    service.hello();
    
  • Run MD5 check sum against all files in a directory

    Couple snippets that allow us to run checksum and get unique md5 checksums.

    This is two step process. First, we obtain our md5 checksum for all files

    find -type f -exec md5sum "{}" + > /opt/checklist.chk
    

    This produces file with following contents

    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif6712032974632727465.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif174464329785828524.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif6775939766281585264.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif7205305688614612348.tiff
    71cc452a8ac5a27c32a83e6a0909e7ae  ./PID_190_7344_0_47710322.tif3909999865608008175.tiff
    

    Next we parse and get only unique checksums.

    cat  /opt/checklist.chk | awk '{split($0, a, " "); if(!seen[a[1]]++) print a[1]}'
    

    This produces our distinct checksums

    71cc452a8ac5a27c32a83e6a0909e7ae
    
  • Starting jetty via command line an nohup

    Somehow I am getting problems starting Jetty via

    service jetty start
    

    We will be using unix command called nohup
    “Nohup is a unix command, used to start another program, in such a way that it does not terminate when the parent process is terminated.”

    I have opted out for using this

    nohup java -jar start.jar -Djetty.port=8085
    

    while this works it shown an message

    nohup: ignoring input and appending output to `nohup.out'
    

    to fix that up we need to redirect in put and output to /dev/null

     nohup java -jar start.jar -Djetty.port=8085  /dev/null &
    
  • Compiling Webkit on Windows using Visual Studio 2012

    Just some notes on compiling WebKit on windows with visual studio.

    Issues :

    C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xrefwrap(431): error C2064: term does not evaluate to a function taking 1 arguments (..\..\win\WebCoreSupport\WebFrameLoaderClient.cpp)
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(239) : see reference to function template instantiation '_Ret std::_Callable_obj<_Ty>::_ApplyX<_Rx,WebCore::PolicyAction>(_V0_t &&)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _Ty=int,
    25>              _Rx=void,
    25>              _V0_t=WebCore::PolicyAction
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(239) : see reference to function template instantiation '_Ret std::_Callable_obj<_Ty>::_ApplyX<_Rx,WebCore::PolicyAction>(_V0_t &&)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _Ty=int,
    25>              _Rx=void,
    25>              _V0_t=WebCore::PolicyAction
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(239) : while compiling class template member function 'void std::_Func_impl<_Callable,_Alloc,_Rx,_V0_t>::_Do_call(_V0_t &&)'
    25>          with
    25>          [
    25>              _Callable=_MyWrapper,
    25>              _Alloc=std::allocator>,
    25>              _Rx=void,
    25>              _V0_t=WebCore::PolicyAction
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(515) : see reference to class template instantiation 'std::_Func_impl<_Callable,_Alloc,_Rx,_V0_t>' being compiled
    25>          with
    25>          [
    25>              _Callable=_MyWrapper,
    25>              _Alloc=std::allocator>,
    25>              _Rx=void,
    25>              _V0_t=WebCore::PolicyAction
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _V0_t=WebCore::PolicyAction,
    25>              _Ty=int,
    25>              _Alloc=std::allocator>,
    25>              _Fty=int
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Do_alloc<_Myimpl,_Ty,_Alloc>(_Fty &&,_Alloc)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _V0_t=WebCore::PolicyAction,
    25>              _Ty=int,
    25>              _Alloc=std::allocator>,
    25>              _Fty=int
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset_alloc<_Ty,std::allocator>>(_Fty &&,_Alloc)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _V0_t=WebCore::PolicyAction,
    25>              _Ty=int,
    25>              _Fty=int,
    25>              _Alloc=std::allocator>
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(515) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset_alloc<_Ty,std::allocator>>(_Fty &&,_Alloc)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _V0_t=WebCore::PolicyAction,
    25>              _Ty=int,
    25>              _Fty=int,
    25>              _Alloc=std::allocator>
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset<_Ty>(_Fty &&)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _V0_t=WebCore::PolicyAction,
    25>              _Ty=int,
    25>              _Fty=int
    25>          ]
    25>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\functional(675) : see reference to function template instantiation 'void std::_Func_class<_Ret,_V0_t>::_Reset<_Ty>(_Fty &&)' being compiled
    25>          with
    25>          [
    25>              _Ret=void,
    25>              _V0_t=WebCore::PolicyAction,
    25>              _Ty=int,
    25>              _Fty=int
    25>          ]
    25>          ..\..\win\WebCoreSupport\WebFrameLoaderClient.cpp(97) : see reference to function template instantiation 'std::function<_Fty>::function(_Fx &&)' being compiled
    25>          with
    25>          [
    25>              _Fty=void (WebCore::PolicyAction),
    25>              _Fx=int
    25>          ]
    25>          ..\..\win\WebCoreSupport\WebFrameLoaderClient.cpp(97) : see reference to function template instantiation 'std::function<_Fty>::function(_Fx &&)' being compiled
    25>          with
    25>          [
    25>              _Fty=void (WebCore::PolicyAction),
    25>              _Fx=int
    25>          ]
    

    Patch
    WebFrameLoaderClient.cpp
    Line 97
    – : m_policyFunction(0)
    + : m_policyFunction(nullptr)

    Issue:

    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMDocumentType already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMProcessingInstruction already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMEvent already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMUIEvent already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMKeyboardEvent already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMMouseEvent already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMMutationEvent already defined in uuid.lib(i_mshtml.obj)
    25>WebKitGUID.lib(WebKit_i.obj) : error LNK2005: _IID_IDOMWheelEvent already defined in uuid.lib(i_mshtml.obj)
    

    Added linker option to WebKitGUID /FORCE:MULTIPLE
    Now we get warning instead of errors;

    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMDocumentType already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMProcessingInstruction already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMEvent already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMUIEvent already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMKeyboardEvent already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMMouseEvent already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMMutationEvent already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>WebKitGUID.lib(WebKit_i.obj) : warning LNK4006: _IID_IDOMWheelEvent already defined in uuid.lib(i_mshtml.obj); second definition ignored
    13>C:\cygwin\home\gbugaj\WebKit\WebKitBuild\Debug_WinCairo\bin32\WebKit.dll : warning LNK4088: image being generated due to /FORCE option; image may not run
    
    

    Building Dependencies

    Cairo

    Issue

    gbugaj@LTRMS7GB /cygdrive/c/cygwin/home/gbugaj/cairo
    $ make -f Makefile.win32  CFG=release
    
    make[1]: Entering directory '/cygdrive/c/cygwin/home/gbugaj/cairo/src'
    
    cairo-deflate-stream.c
    e:\source\c-libraries\zlib-1.2.3-lib\include\zconf.h(289) : fatal error C1083: Cannot open include file: 'unistd.h': No such file or directory
    ../build/Makefile.win32.common:55: recipe for target 'release/cairo-deflate-stream.obj' failed
    make[1]: *** [release/cairo-deflate-stream.obj] Error 2
    make[1]: Leaving directory '/cygdrive/c/cygwin/home/gbugaj/cairo/src'
    Makefile.win32:12: recipe for target 'cairo' failed
    make: *** [cairo] Error 2
    

    Fix is to add empty ‘unistd.h’ to zlib include directory