text:
fastFrag
=====

A simple JS library for making HTML from JSON. Include fastFrag.js and you're ready to use fastFrag.

UNLICENSE
-----

[unlicense](http://unlicense.org/)

This is free and unencumbered software released into the public domain.

see complete UNLICENSE Information below, or at [unlicense.org](http://unlicense.org/)

Overview
-----

Who, what when where why of fastFrag.

You give fastFrag JSON and it gives you back HTML (a Document Fragment) that is ready to be added to the DOM.

Convert your existing HTML to fastFrag JSON in less than a second visit [fastFrag converter](http://json.fastfrag.org), paste in HTML and get fastFrag JSON back.

You can find the fastFrag conversion utilities here, [https://github.com/gregory80/fastFrag-utils](https://github.com/gregory80/fastFrag-utils)

How does it work
----------

By using existing, stable DOM methods, fastFrag quickly converts JSON to HTML a Docment Fragment), handling all escaping concerns, making it both safe and fast.

Syntax
----------

A basic example of syntax is below, more complete examples and instructions are available below under Usage:

    {
        id : "myElemId",
        content : "hello wolrd"
    }

Complex / More Complete Options

    {
        css : "myclass1 myclass2",       // optional
        id : "the_elem_id",              // optional
        type : "span",                  // optional: any html element, defaults to DIV
        content : "the inner HTML part" // optional, string, object, boolean, array accepted (create nested structures)
        attr : {
            rel : "nofollow",
            made_up : "some_attributevalue"
        },                              // attributes for the element, optional
        text : "a string"              // optional, creates a text only node. All other attributes ignored, see usage
    }

Note: Starting in version 1.0.5 the following can be used for attributes, attr and attrs for brevity

    attributes : { .. }
    attr : { .. }
    attrs : { .. }

What is fastFrag?
----------

An extremely simple **JS helper library** for making HTML (a document fragment) from JavaScript.

        var frag_results = fastFrag.create( { id : "my_id" }  ); // return

For more complete examples see Usage below, or [convert html now](http://json.fastfrag.org).

Why do I want or need this?
----------

If you need to create HTML structure (somehow) with JavaScript, be that getting data from a server (AJAX) or rendering a button based on a certain state, injecting user data into the DOM, this library is for you.

As a benefit, it handles all the escaping worries you used to have. No more Regular Expressions to 'clean up' or escape data.

When is this useful?
----------

When you need to render / change the DOM [Document Object Model] via JavaScript.

Do I need all this stuff?
------------

Nope, you only need [fastFrag.js](http://github.com/gregory80/fastFrag/blob/master/js/fastFrag.js) or [fastFrag.min.js](http://github.com/gregory80/fastFrag/blob/master/js/fastFrag.min.js) to use fastFrag. That's it.

The remaining portion of the has been moved to fastFrag-utils and comprises samples, tests, a markdown extension, Textmate snippets, jQuery plugin sample, and finally, app engine code for converting HTML to fastFrag JSON, use it [here](http://json.fastfrag.org).

Usage
-----

// Let's start simple, how about a div with hello world

    fastFrag.create({ content : "hello world" })

// returns document fragment

hello world

// create an empty div

    fastFrag.create({})

// return document fragment:

// element 'type' is always assumed to be a div unless otherwise noted via 'type' attr

    fastFrag.create({
        type : "p",
        css : "a_class_name",
        content : "string here"
    })

//returns Document Fragment

string here

Get more complex with with nested elements:

    fastFrag.create({
        css : "a_class_name",
        content : [{
            type : "a",
            content : "child one",
            attrs : {
                href : "http://whatever.com"
            }
        }, {
            content : "child two"
        }]
    })

// returns Document Fragment

        child one

child two

Note: Starting in version 1.0.5 the following can be used for attributes, attr and attrs for brevity

    attributes : { .. }
    attr : { .. }
    attrs : { .. }

// create the below html with fastFrag

        fastFrag Repos | link two

// the code:

    fastFrag.create({
        css : "mainClass",
        content : [{
            type : "a",
            content : "fastFrag Repo",
            attrs : {
                href : "http://github.com/gregory80/fastFrag"
            }
        },{
            text : " | "
        },{
            type : "a",
            content : "link two",
            attrs : {
                href : "#"
            }
        }]
    })

More information on usage can be found [here](http://fastfrag.org/post/4cd354958803a42ed3000000)

What happened to all the other stuff?
---------
Most (if not all) non core files has been split out into their own repository. <https://github.com/gregory80/fastFrag-utils>

FAQ
-------

The Contents of the FAQ can not be found [here](http://fastfrag.org/post/4cd35c898803a434fb000000), on the new fastfrag.org *blog*

Why Does this exist?
-----------

I personally found myself needing to render HTML from JavaScript. Over the years, I have tried a variety of different techniques (fastFrag-like included) to do this. All previous iterations suffered from one of two fatal flaws.

1.  It was potentially insecure, such as using a regular expression or string matching to replace values, for example:

        var myTemplateString = "some value here $replacevalue"

    or this example

        var myTemplateString = "fo bar blah {{title}} and {{body}} etc"

1.  It was practically impossible to read or maintain, maybe it was something like this:

        jQuery("#someId").html('

foo

bar

')

That's hard to read, difficult to maintain is basically entirely specific to the project. Recovering that string of 'text' would provide very little value.

Since I like simple, easy to understand things. I wrote fastFrag in a few hours (weeks of testing). There are definitely other libraries out there, most have significantly more options or required some server side aspect to *prepare* the data and template. Since none of the existing options did what I needed, I wrote this. A purely client-side JavaScript template powered by JSON and returning valid Document Fragments for DOM insertion.

Some Stats, Is it actually fast?
--------------

Testing for innerHTML method on sample_inner_html_complex.html showed:

    5ms for layout, 5ms for paint

fastFrag showed:

    4ms for layout, 1ms for paint.

Graphs and data to come, you can run your own tests by loading the HTML files found in samples/ folder.

I am highly skeptical that any JS template library would be faster than a simple string and inner HTML across the variety of browsers on the market: Chrome, Safari, FireFox, Internet Explorer etc.

However, it is impossible to deny the expense incurred to escape data when using inner HTML methods directly, or risk possible serious attacks to your website if you accept any user-content.

When comparing both the speed of inner HTML, and it's absolute need for regular expressions to attempt and catch anything *dangerous*, with fastFrag, fastFrag has so far demonstrated itself to be faster, but again graphs to come as soon as possible.

If you have found otherwise, please tell us about it here, <http://github.com/gregory80/fastFrag/issues>. If you're skilled in creating this type of graphical data and testing, __please__ contact me info < at > fastfrag < dot > org. I would love your help!

Benefits
--------

I find the primary benefit of fastFrag, over concatenated strings specifically, is the end of unbalanced 'divs' or other elements. Each element is properly closed. Any 'errors' in the JSON show up clearly with a line number, 'Unexpected Identifier' for example, which means a comma is missing. This makes debugging even the most complex HTML structures very, very fast.

In addition, the speed benefits of the library have been shocking to me. After repeatedly finding 'innerHTML' to be fast in any environment, fastFrag beats that. I'm working on a stats chart and example to demonstrate this. Again, if you're skilled in creating this type of graphical data and testing, __please__ contact me info < at > fastfrag < dot > org. I would love your help!

fastFrag minimizes manipulation of the DOM API, which is generally considered to be *slow*. fastFrag allows for infinitely complex JSON structures, that can be appended to the DOM in a single line of code. This reduces the number of times the DOM is accessed. Updating the DOM require the browser to update its layout and paint events in order to display the new content.

    document.body.appendChild( fastFrag.create({ content : [...] }) );

or, better yet, just give it a list of elements and skip the 'wrapper'

    document.body.appendChild( fastFrag.create([....]) );

UNLICENSE
-----

[unlicense](http://unlicense.org/)

This is free and unencumbered software released into the public domain.

see complete UNLICENSE Information below

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

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 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.

For more information, please refer to http://unlicense.org/

Changelog
-------
1.1.3.1
added support for
{
    'c' : 'yer content',
    'style' : "display:none;width:500px;"
}

In addition to 'content' for brevity. Added top level style controls.

1.1.3
added in fix for ie7 that didn't set style attributes, Thanks to Jeff Tierney of bit.ly.

1.1.2.2
performance release. remove excessive DOM fragment creation.

1.1.1.01
remove extra (uneeded dom frag creation)

1.1.1
Rename functions, re-organize file, group method types

1.1
JavaScript change: move to try/catch based sub node append to handle IE errors regarding appending nodes to IMG, INPUT, BR, HR or other 'self' closed tags via the DOM.

1.0.5

Note: Starting in version 1.0.5 the following can be used for attributes, attr or attrs for brevity. A mix of any possible of the below is possible. In other words, it's fully backward compatible, future versions may deprecate the identifier property 'attributes' in favor of a more compact syntax.

    attributes : { .. }
    attr : { .. }
    attrs : { .. }

Who's Using It?
---------

If you are using fastFrag -[tell use about it](http://github.com/gregory80/fastFrag/issues)! We will list your project and a link to the project homepage here. As well as a brief description, <fastfrag.org> has also been acquired and will feature people using the template, in the future.

Currently, this project is limited to a handful of projects where I have been directly involved to some degree, for instance the bit.ly Chrome extension and fic.ly writes like as well as several projects I have yet to make public. See a list of my open projects [here on github](http://github.com/gregory80)

Thanks
-------
Thanks to Jeff Tierney of bit.ly for providing an IE7 patch on style attributes, found in release 1.1.3


text:
#/bin/bash
#
#  compile_frag.sh
#  fastFrag
#
#  Created by gregory tomlinson on 2011-03-19.
#  Copyright 2011 the public domain. All rights reserved.
#
# just a one liner to compile, based on the location of the closure jar from my machine
java -jar ../../website/tools/closure_compiler.jar --js=../js/fastFrag.js --js_output_file=../js/fastFrag.min.js

repo_name: gtzilla/fastFrag

repo_language: JavaScript

mime_type: text/plain


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

        <title>fastFrag Sample Basic</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="keywords" content="awesome" />
        <meta name="description" content="" />


text:
<!DOCTYPE HTML>

        <title>Test Fraglet</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="keywords" content="awesome" />
        <meta name="description" content="just a little test for fraglet" />

                this page assumes the root directory is fastFrag, though it tries to use relative paths


text:
        <title>fast</title>

Create Elements

InnerHTML

FastFrag

empty


text:
<!DOCTYPE HTML>

        <title>Fraglet Test 2</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="keywords" content="awesome" />
        <meta name="description" content="" />


text:
(function(){
    /*
            fastFrag
                Turn JSON into HTML, http://github.com/gregory80/fastFrag

            Usage: fastFrag.create( { content : "hello world" });
            // creates Document Fragment:
hello world

            Learn more: http://github.com/gregory80/fastFrag/blob/master/README.md or http://fastfrag.org

            Convert HTML to fastFrag (fast!): http://json.fastfrag.org/
    */

    var fastFrag = {
        create : function( params ) {
            base_frag=d.createDocumentFragment();
            return assembleHTML(params);
        },
        version : "1.1.3.1"

    };
    window.fastFrag = fastFrag;

    var d = document, base_frag=null;

    function assembleHTML( params ) {
        var el;
        if(params && params.length === undefined) {
            el = _singleNode( params );
            base_frag.appendChild( el );
        } else {
            var sub_frag=d.createDocumentFragment(), k;
            for(k in params) {
                el = _singleNode( params[k] );
                sub_frag.appendChild( el );
            }
            return sub_frag;
        }
        return base_frag;
    }

    // helpers
    function _singleNode( o ) {
        var el, txt;
        if( o.text !== undefined ) {
            el = d.createTextNode( o.text || "" );
        } else {
            el = _make_element( o );
            txt = _process_node( o );
            try{
                el.appendChild( txt );
            } catch(e){}
        }
        return el;
    }
    function _mke_attribute( el, attrs ) {
        for(var k in attrs) {
            // yuck, setting disabled to false or none still breaks browsers, skip it instead
            if(k === "disabled" && !attrs[k]) { continue; }
            // IE7 barfs if you try to set style via a style attribute on the element
            // deprecate this in favor of top level?
            if(k.toLowerCase() === "style") { el.cssText = el.style.cssText = attrs[k];}
            if(k.toLowerCase() === "value") { el.value = attrs[k]; } // IE7
            else { el.setAttribute(k, _safe( attrs[k] ) ); }
        }
    }
    function _make_element( o ) {
        var el_name, el;
        el_name = o.type || "div";
        el = _mke( el_name );
        // Starting in ver1.0.5, can use any mix of o.attributes || o.attr  || o.attrs
        if(o.attributes || o.attr || o.attrs) { _mke_attribute( el, o.attributes || o.attr  || o.attrs ); }
        el.id = (o.id) ? o.id : null;  el.className = (o.css) ? o.css : null;
        if(o.style) { el.cssText = el.style.cssText=o.style; } // add style attribute..
        if(o.value) { el.value = o.value; } // add value attr.
        return el;
    }

    function _process_node( o ) {
        var txt=null, cntnt=o.c || o.content, content_type = typeof cntnt, txt_value;
        // JS thinks both Object and Array are typeof object, let assembleHTML guide it
        if( content_type === "object") {
            txt = assembleHTML( cntnt );
        } else if(content_type === "string") {
            txt = d.createTextNode( cntnt );
        } else {
            // this might be an intger or float or boolean, it's all text to HTML..
            txt_value = (cntnt !== undefined) ? (cntnt.toString() || "")  : "";
            txt = d.createTextNode( txt_value );
        }
        return txt
    }
    // short cut / conveince methods
    function _mke(elem) {
        return d.createElement( elem );
    }
    function _safe( string ) {
        var txt_node=d.createTextNode(string);
        var txt=(txt_node.nodeValue).toString();  // put in a text node, then grab it
        txt_node=null
        return txt;
    }

})();


text:
//
//  fraglet.js
//  fastFrag
//
//  Created by gregory tomlinson on 2011-03-20.
//  Copyright 2011 the public domain. All rights reserved.
//          requires fastFrag 1.1.3.1
/*
    filename : fraglet.js
    http://unlicense.org/
    author: gregory tomlinson
    Sun Mar 20 10:10:16 EDT 2011
*/

(function(global_frame) {
    var fraglet,Fraglet,FEvent,F,_F,__ns; // declare, don't set

    /*
        A single template, stored at __ns is an F object

        Fraglet tracks the combination of all template
    */
    Fraglet=function() {
        // essentially on script load
        __ns={};
    }

    Fraglet.prototype = {

        lnk : function( href, txt ) {
            return {
                'type' : 'a',
                'attr' : {
                    'href' : href
                },
                'c' : txt || href
            }
        },
        inpt : function( opts ) {
            return [{
                'type' : 'label',
                'c' : opts.label_text || ""
            },{
                'type' : "input",
                'attr' : {
                    'type' : opts.type || "text",
                    'name' : opts.name || null,
                    'value' : opts.value || null
                }
            }]
        },

        // do stuff to the general management of templates
        all : function( key ) {
            return __ns;
        },
        c : function( key ) {

            return this.__create(key);
        },
        d : function( key  ) {
            // direct access
            return this.__create(key);
        },
        // args (key, action, p,a,y,l,o,a,d) where p,a,y,l,o,a,d is N args needs for the fn_method
        t : function( key, fn_method ) {
            var payload=[], ns=this.__create(key);
            if(!key && !action) { throw("Name and method required"); }
            if(arguments.length > 2) { payload=Array.prototype.slice.call(arguments, 2); }
            ns[fn_method].apply( ns, payload );
        },
        r : function( key, el ) {
            var ns=this.__create(key);
            if(!el) {
                throw("Element Required");
            }
            ns.draw(el);
        },
        render : function(key, el, frag ) {
            var type = typeof el, ns=this.__create(key), item;
            if( type.toLowerCase === "object" ) {

            } else if (type.toLowerCase === "string") {

            } else {
                // this is an actual dom element??
            }
            if(ns) {
                item=__ns[ns]
            } else {
               // item=el.appendChild( fastFrag.create(frag) );
               ns.append(frag);
               ns.draw(el);
            }
        },

        //
        __create : function( key ) {
            // todo, manage for periods and other special chars in key
            if(!__ns[key]) { __ns[key]=new F( key ); }
            return __ns[key]
        },
    };

    F=function( ns ){
        this.__t=[];
        this.ns=ns;
        this.__active_dom=[];
        this.__root=null;
        this.__listeners=[]; // for { el : "#whatever", type : "click mousedown", method : function(e) { ... } }
        this.dom_reference=true;
    };

    F.prototype={
        /*
            Holds data representation for fastFrag
        */
        // JS method overloading? sorta
        event : function( fn ) {
            fn.apply(this, Array.prototype.slice.call(arguments, 1) || []  );
        },
        add_root : function( clss, opts ) {
            // basically take the current list at __t
            // and make a new content node and put it in an array
            var n_frag={
                'type' : opts && opts.type || "div",
                'c' : this.__t.concat([]),
                'css' : clss
            }
            this.__t=[];
            this.__t.push(n_frag);
        },
        preprend : function( frag_item ) {
            this.__t.shift(frag_item);
            return this;
        },
        append : function( frag_item, opts ) {
            this.__t.push( frag_item  );
            return this;
        },
        insert : function(frag_item, pos ) {
            var howmany=1;
            if(pos>this.__t.length-1) {
                this.append( frag_item );
                return;
            }
            if(frag_item.length) {
                howmany=frag_item.length;
            }
            this.__t.splice(pos,howmany,frag_item);
            return this;
        },
        css : function( opts, set ) {
            var type=typeof opts;
        },
        extend : function() {
            // which element to extend??
        },
        extend_all : function() {
            //
            var f,i;
            for(i=0;i<this.__t.length; i++) {
                f=this.__t[i];
            }
        },
        draw : function( el ) {
            // todo, check the listeners
            el.appendChild( fastFrag.create( this.__t ) );
            if(this.dom_reference) this.__active_dom.push( el );
        },
        iterator : function( list, fn, opts ) {
            // 'event'ish methods
            /*
                opts = {
                    before : function(){ ... }
                    complete : function(){ ... }
                }
            */
            var i=0;
            if(opts && opts.before && (typeof opts.before).toLowerCase() === "function") opts.before.call(this);
            for(; i<list.length; i+=1) {
                fn.apply( this, [list[i]] );
            }
            if(opts && opts.complete && (typeof opts.complete).toLowerCase() === "function") opts.complete.call(this);
        },
        // a basic list
        list_basic : function( type, data, opts ) {
            var frag, i=0, items=[], f_items=[], wrapper_type="ul", t=(typeof data).toLowerCase();
            if(t === "object" && t.length) {

            } else if (t === "object" ) {
                // this is a regular object
            } else if (t !== "string" ) {
                // number
                data=new Array(data);
            } else {
                // nope..
                throw("Non valid type for data");
            }

            for( ; i<data.length; i++) {
                frag = {
                    'type' : type,
                    'c' : data[i] || "",
                    'css' : opts && opts.css || null
                }
                items.push(frag)
            }
            f_items=items;
            if(type.toLowerCase() !== "li") {  wrapper_type="div"; }
            f_items={
                'c' : items,
                'type' : wrapper_type
            };
            this.__t.push(f_items);
            return this;
        },

        list_links : function(type, data, opts) {

        },

        find : function( opts ) {
            var key = opts && opts.key || null,
                value=opts && opts.value || null;

            if(!key && !value) {
                return this.__t;
            }

            if(key) {
                // okay, loop over the object
                var t=this.__t, k;
                for(k in t) {
                    if(k===key) {
                        // match...
                    }
                }
            }
        }
    }

    FEvent=function( el, opts ){
        this.el=el;
        // todo, use extend for opts...
        if(opts&&opts.method&&(typeof opts.method).toLowerCase() === "function") { this.method=opts.method; }
        this.opts=opts;
    }
    FEvent.prototype={
        'el' : null,
        'type' : "click",
        'method' : function(){},
        'add' : function() {
            // iterate over this sucker, use something to attach the methods
            // maybe just use jquery??
            // hrm
        }
    }

    // setup the fraglet
    global_frame['fraglet'] = new Fraglet();

})(this);


text:
//
//  fraglet.js
//  fastFrag
//
//  Created by gregory tomlinson on 2011-03-19.
//  Copyright 2011 the public domain. All rights reserved.
//
// A Convience fastFrag template manager thingie
/*
    filename : fraglet.js
    http://unlicense.org/
    author: gregory tomlinson
    Sat Mar 19 18:00:14 EDT 2011
*/

(function(global_frame) {

    /*
        opts
            Options
            {
                frag : an existing fastFrag structure
                root : the root element of this fraglet
            }
    */

    var F,FragLet=function( name, opts ){
        this.name=name;
        this.frag=opts && opts.frag || null;
        this.root=opts && opts.root || null;
        this.__t;
    }, fraglet = function( name, opts ) {
        // return new F( name, opts );
        return new F(name,opts);
        // no this is bad, then i will have all this little objects every where
        // i am trying to 'MANAGE' this crap, i need to hide..
    }
     /*
        The ART of Lazy
            methods to handle methods that do stuff.. hooray

    */
    fraglet.update=function( _fragLet, name ){
            var anchor;
            if(_fragLet && name) {
                anchor=_fragLet;
                _fragLet.name=name; // this will alter the original
            } else {

                name=_fragLet;
                anchor=this(name);// if no object, create it
            }
            console.log(anchor);
            return anchor;
            // console.log( this( name ) );
    }

    /////////////////////
    F=FragLet; // set to the same so the object will say 'Fraglet' not 'F'...
    F.prototype = {
        make : function( type, opts ) {
            console.log("make is called")
        },
        extend : function() {
            //this.__t
        },
        append : function( el, frag ) {
            // el is optional
            if(el && frag) {
                if(!this.root) this.root=el; // default
            } else if(el) {
                frag=el;
            }
            this.root.append( fastFrag.create( frag  ) );
        },
        draw : function( el, frag ) {
            var r_frag=frag || this.frag;
            el.appendChild( fastFrag.create( r_frag ) );
        },
        draw_all : function(el, frag) {
            var r_frag=frag || this.frag;

        }
    }

    global_frame['fraglet'] = fraglet;

})(this);


text:
set BUILD_FOLDER=%cd%

REM Disable the warning for detached head
git config --global advice.detachedHead false

REM zlib
git clone --depth 1 --single-branch --branch v1.2.13 https://github.com/madler/zlib.git c:/3rdparty/zlib

REM libpng
git clone --depth 1 --single-branch --branch v1.6.39 https://github.com/glennrp/libpng.git c:/3rdparty/libpng

REM libjpeg
curl -O http://www.ijg.org/files/jpegsr9e.zip
7z x jpegsr9e.zip -oc:\3rdparty\
move c:\3rdparty\jpeg-9e c:\3rdparty\libjpeg

REM libtiff
git clone --depth 1 --single-branch --branch v4.5.0 https://gitlab.com/libtiff/libtiff.git c:/3rdparty/tiff

REM freetype
git clone --depth 1 --single-branch --branch VER-2-10-4 https://github.com/freetype/freetype.git c:/3rdparty/freetype

REM glut
git clone https://github.com/markkilgard/glut.git c:/3rdparty/glut
cd c:\3rdparty\glut
git reset --hard 8cd96cb440f1f2fac3a154227937be39d06efa53
cd %BUILD_FOLDER%

REM giflib
git clone --depth 1 --single-branch --branch 5.2.1 https://git.code.sf.net/p/giflib/code.git c:/3rdparty/giflib

REM curl
curl -O https://curl.se/download/curl-7.76.1.zip
7z x curl-7.76.1.zip -oc:\3rdparty\
move c:\3rdparty\curl-7.76.1 c:\3rdparty\curl

repo_language: CMake


text:
Library | Version
------- | -------
zlib | 1.2.11
libpng | 1.6.37
libjpeg | 9d
libtiff | 4.2.0
FreeType | 2.10.4
GLUT | SHA:8cd96cb440f1f2fac3a154227937be39d06efa53
GIFLIB | 5.2.1
cURL | 7.76.1


text:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(OpenscenegraphThirdParty)

# Only enable release and debug builds
if(CMAKE_CONFIGURATION_TYPES)
  set(CMAKE_CONFIGURATION_TYPES Debug Release)
  set(CMAKE_CONFIGURATION_TYPES
      "${CMAKE_CONFIGURATION_TYPES}"
      CACHE STRING "Reset the configurations to what we need" FORCE)
endif()

# Generate folder name for install
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
  set(BITS "x64")
elseif(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
  set(BITS "x86")
endif()

if(MSVC)
  if(${MSVC_VERSION} EQUAL 1600)
    set(TOOLSET "v100") # Visual Studio 2010
  elseif(${MSVC_VERSION} EQUAL 1700)
    set(TOOLSET "v110") # Visual Studio 2012
  elseif(${MSVC_VERSION} EQUAL 1800)
    set(TOOLSET "v120") # Visual Studio 2013
  elseif(${MSVC_VERSION} EQUAL 1900)
    set(TOOLSET "v140") # Visual Studio 2015
  elseif(${MSVC_VERSION} GREATER 1910 AND ${MSVC_VERSION} LESS 1920)
    set(TOOLSET "v141") # Visual Studio 2017
  elseif(${MSVC_VERSION} GREATER 1919)
    set(TOOLSET "v142") # Visual Studio 2019
  endif()
endif()

if(MINGW)
  set(TOOLSET "mingw")
endif()

set(dirname "${TOOLSET}-${BITS}")

# Set directories if not set explicitly
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX
      "${PROJECT_BINARY_DIR}/3rdParty/${dirname}"
      CACHE "Force change of path" STRING FORCE)
endif()

set(ZLIB_SOURCE_DIR CACHE PATH "Path where to find ZLIB source")
set(LIBPNG_SOURCE_DIR CACHE PATH "Path where to find LIBPNG source")
set(LIBJPEG_SOURCE_DIR CACHE PATH "Path where to find LIBJPEG source")
set(LIBTIFF_SOURCE_DIR CACHE PATH "Path where to find LIBTIFF source")
set(FREETYPE_SOURCE_DIR CACHE PATH "Path where to find FREETYPE source")
set(GLUT_SOURCE_DIR CACHE PATH "Path where to find GLUT source")
set(GIFLIB_SOURCE_DIR CACHE PATH "Path where to find GIFLIB source")
set(CURL_SOURCE_DIR CACHE PATH "Path where to find cURL source")

# Check dependencies for LIBPNG
if(LIBPNG_SOURCE_DIR)
  if(NOT ZLIB_SOURCE_DIR)
    message(
      FATAL_ERROR "Error: LIBPNG depends on ZLIB and no ZLIB path has been set")
  endif()
endif()

# Check dependencies for LIBTIFF
if(LIBTIFF_SOURCE_DIR)
  if(NOT ZLIB_SOURCE_DIR)
    message(
      FATAL_ERROR "Error: LIBTIFF depends on ZLIB and no ZLIB path has been set"
    )
  endif()

  if(NOT LIBJPEG_SOURCE_DIR)
    message(
      FATAL_ERROR
        "Error: LIBTIFF depends on LIBJPEG and no LIBJPEG path has been set")
  endif()
endif()

# Check dependencies for MINIZIP
if(MINIZIP_SOURCE_DIR)
  if(NOT ZLIB_SOURCE_DIR)
    message(
      FATAL_ERROR "Error: MINIZIP depends on ZLIB and no ZLIB path has been set"
    )
  endif()
endif()

# Add libraries
if(ZLIB_SOURCE_DIR)
  add_subdirectory(zlib)
endif()

if(LIBPNG_SOURCE_DIR)
  add_subdirectory(libpng)
endif()

if(LIBJPEG_SOURCE_DIR)
  add_subdirectory(libjpeg)
endif()

if(LIBTIFF_SOURCE_DIR)
  add_subdirectory(libtiff)
endif()

if(FREETYPE_SOURCE_DIR)
  add_subdirectory(freetype)
endif()

if(GLUT_SOURCE_DIR)
  add_subdirectory(glut)
endif()

if(GIFLIB_SOURCE_DIR)
  add_subdirectory(giflib)
endif()

if(CURL_SOURCE_DIR)
  add_subdirectory(curl)
endif()


text:
osg-3rdparty-cmake
==================

CMake scripts for building OpenSceneGraph third party libraries.

These scripts can be used to build third party libraries from source using CMake(http://www.cmake.org/).

The source code for respective library has to be downloaded separately, see download locations below.

By building the INSTALL target for both debug and release these scripts will create a folder named `3rdParty`.
Inside this folder there will folders created to represent each platform toolset.

### Status: ![Build status](https://github.com/bjornblissing/osg-3rdparty-cmake/actions/workflows/build.yml/badge.svg)

Prebuilt versions
----------------

Prebuilt version can be found under *Releases*. Version numbers if the included dependencies can be found in the [versions.md](versions.md) file.

Toolset | Prebuilt archive
------------ | -------------
Visual Studio 2017 32-bit | v141-x86.zip
Visual Studio 2017 64-bit | v141-x64.zip
Visual Studio 2019 32-bit | v142-x86.zip
Visual Studio 2019 64-bit | v142-x64.zip

License
-------

Each of the dependencies keep their original licenses since their scripts are to be considered derivative works.

The top level script is licensed according to the `Unlicense`:

http://unlicense.org/

Instructions
------------

1. Download the CMake scripts from this repository.
2. Download the source for the dependencies you would like to use from their respective location as specified below.
3. Start the CMake GUI and select the directory with the CMake scripts as your source directory. Use any desired output directory as binary directory.
4. Press **Configure** inside the CMake GUI.
5. Fill in the location of the downloaded sources of your desired dependencies and press "Configure" again. Repeat until there is no more errors and warnings in CMake.
6. Press **Generate** inside the CMake GUI. This will generate solution file inside your binary directory.
7. Open the solution file in your IDE.
8. Build the `ALL_BUILD` project for both debug and release.
9. Build the `INSTALL` project for both debug and release.

In your binary directory there will now be a folder named `3rdParty` with a sub-folder named after your target platform. Inside this folder there should be all your headers and libraries.

zlib
----
Sources for zlib can be downloaded from:

http://www.zlib.net/

libpng
------
Sources for libpng can be downloaded from:

http://www.libpng.org/pub/png/libpng.html

libjpeg
-------
Sources for libjpeg can be downloaded from:

http://www.ijg.org/

libtiff
-------
Sources for libtiff can be downloaded from:

https://gitlab.com/libtiff/libtiff

FreeType
--------
Sources for FreeType can be downloaded from:

http://www.freetype.org/

GLUT
----
Sources for GLUT can be downloaded from:

https://github.com/markkilgard/glut

GIFLIB
------
Sources for GIFLIB can be downloaded from:

http://sourceforge.net/projects/giflib/

cURL
----
Sources for cURL can be downloaded from:

http://curl.haxx.se/


text:
# Workflow to build binary artifacts for tagged versions
name: Build

# Triggers the workflow when a new tag is pushed (but disregard new branches)
on:
  push:
    tags:
    - '*'

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a matrix job called "Release"
  Release:
    # The type of runner that the job will run on
    runs-on: ${{ matrix.os }}

    strategy:
      matrix:
        include:
          - name: v141-x86
            os: windows-2016
            generator: "Visual Studio 15 2017"
            arch: Win32
          - name: v141-x64
            os: windows-2016
            generator: "Visual Studio 15 2017"
            arch: x64
          - name: v142-x86
            os: windows-2019
            generator: "Visual Studio 16 2019"
            arch: Win32
          - name: v142-x64
            os: windows-2019
            generator: "Visual Studio 16 2019"
            arch: x64

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - name: Checkout repository
        uses: actions/checkout@v2

      - name: Cache source code
        uses: actions/cache@v2
        with:
          # Cache the downloaded external source code and only update the cache when the download_dependencies.bat file is changed
          path: c:/3rdparty
          key: ${{ hashFiles('download_dependencies.bat') }}

      # Download source code
      - name: Download source code
        run: .\download_dependencies.bat

      # Compile code
      - name: Compile code
        run: |
            mkdir build
            cd build
            cmake ${env:GITHUB_WORKSPACE} -G "${{ matrix.generator }}" -A ${{ matrix.arch }} -DZLIB_SOURCE_DIR=c:/3rdparty/zlib -DLIBPNG_SOURCE_DIR=c:/3rdparty/libpng -DLIBJPEG_SOURCE_DIR=c:/3rdparty/libjpeg -DLIBTIFF_SOURCE_DIR=c:/3rdparty/tiff -DFREETYPE_SOURCE_DIR=c:/3rdparty/freetype -DGLUT_SOURCE_DIR=c:/3rdparty/glut -DGIFLIB_SOURCE_DIR=c:/3rdparty/giflib -DCURL_SOURCE_DIR=c:/3rdparty/curl -DCMAKE_INSTALL_PREFIX="C:/projects/osg-3rdparty-cmake/build/3rdParty/${{ matrix.name }}"
            cmake --build . --config "Debug" --target install
            cmake --build . --config "Release" --target install

      - name: Compress archive
        run: |
          cd C:\projects\osg-3rdparty-cmake\build\3rdParty\${{ matrix.name }}
          7z a C:\projects\osg-3rdparty-cmake\${{ matrix.name }}.zip .

      - name: Publish artifact
        uses: ncipollo/release-action@v1
        with:
          artifacts: "c:\\projects\\osg-3rdparty-cmake\\${{ matrix.name }}.zip"
          allowUpdates: true
          bodyFile: "versions.md"
          token: ${{ secrets.GITHUB_TOKEN }}


text:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(glut LANGUAGES C)

# Use GNUInstallDirs to install libraries into correct locations on all
# platforms.
include(GNUInstallDirs)

option(GLUT_BUILD_STATIC "Build static version of the GLUT library." OFF)
if(${GLUT_BUILD_STATIC})
  message(
    STATUS
      "WARNING: Static version of GLUT library will require\n changes of osgviewerGLUT projects runtime library\n from /MD to /MT to be able to link correctly.\n"
  )
endif()

mark_as_advanced(GLUT_BUILD_STATIC)

set(GLUT_PUBLIC_HEADERS ${GLUT_SOURCE_DIR}/include/GL/glut.h)

set(GLUT_SRCS
    ${GLUT_SOURCE_DIR}/lib/glut/glut_8x13.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_9x15.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_bitmap.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_bwidth.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_cindex.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_cmap.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_cursor.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_dials.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_dstr.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_event.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_ext.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_fbc.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_fullscrn.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_gamemode.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_get.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_glxext.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_hel10.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_hel12.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_hel18.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_init.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_input.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_joy.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_key.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_keyctrl.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_keyup.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_mesa.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_modifier.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_mroman.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_overlay.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_roman.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_shapes.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_space.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_stroke.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_swap.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_swidth.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_tablet.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_teapot.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_tr10.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_tr24.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_util.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_vidresize.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_warp.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_wglext.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_win.c
    ${GLUT_SOURCE_DIR}/lib/glut/glut_winmisc.c
    ${GLUT_SOURCE_DIR}/lib/glut/win32_glx.c
    ${GLUT_SOURCE_DIR}/lib/glut/win32_menu.c
    ${GLUT_SOURCE_DIR}/lib/glut/win32_util.c
    ${GLUT_SOURCE_DIR}/lib/glut/win32_winproc.c
    ${GLUT_SOURCE_DIR}/lib/glut/win32_x11.c)

set(GLUT_EXPORT_DEFINTIONS ${GLUT_SOURCE_DIR}/lib/glut/glut.def)

if(MSVC)
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS) # Disable warnings
                                                             # for unsecure CRT
                                                             # functions
  if(${GLUT_BUILD_STATIC})
    list(APPEND PRIVATE_OPTIONS $<$<CONFIG:Debug>:/MTd>
         $<$<CONFIG:Release>:/MT>) # Build static runtime library
  else()
    list(APPEND PRIVATE_OPTIONS $<$<CONFIG:Debug>:/MDd>
         $<$<CONFIG:Release>:/MD>) # Build shared runtime library
  endif()

  # Supress warnings
  list(APPEND PRIVATE_OPTIONS /wd4133) # type' : incompatible types - from
                                       # 'type1' to 'type2'
  list(APPEND PRIVATE_OPTIONS /wd4554) # operator' : check operator precedence
                                       # for possible error; use parentheses to
                                       # clarify precedence
  list(APPEND PRIVATE_OPTIONS /wd4996) # The compiler encountered a deprecated
                                       # declaration.
  list(APPEND PRIVATE_OPTIONS /wd4715) # function' : not all control paths
                                       # return a value

  set(CMAKE_DEBUG_POSTFIX "d")
endif(MSVC)

if(MINGW)
  list(APPEND PRIVATE_DEFINITIONS "-w") #
endif(MINGW)

if(${GLUT_BUILD_STATIC})
  add_library(glut32 STATIC ${GLUT_SRCS} ${GLUT_PUBLIC_HEADERS})
else()
  add_library(glut32 SHARED ${GLUT_SRCS} ${GLUT_PUBLIC_HEADERS}
                            ${GLUT_EXPORT_DEFINTIONS})
endif()

# Dependent include files
target_include_directories(
  glut32
  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
         $<BUILD_INTERFACE:${GLUT_SOURCE_DIR}/include>
         $<INSTALL_INTERFACE:include>)

target_compile_definitions(glut32 PRIVATE ${PRIVATE_DEFINITIONS})

target_compile_options(glut32 PRIVATE ${PRIVATE_OPTIONS})

if(MSVC)
  if(${GLUT_BUILD_STATIC})
    target_link_libraries(glut32 winmm.lib)
  else()
    target_link_libraries(glut32 winmm.lib OpenGL32.lib GlU32.lib)
  endif()
endif(MSVC)

# INSTALL
install(
  TARGETS glut32
  EXPORT glut32_export
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  INCLUDES
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES ${GLUT_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GL)


text:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
file(STRINGS "${FREETYPE_SOURCE_DIR}/include/freetype/freetype.h"
     FREETYPE_VERSION_FILE_CONTENTS REGEX "#define FREETYPE_[A-Z]+[ \t]+[0-9]+")

string(REGEX REPLACE ".*#define FREETYPE_MAJOR[ \t]+([0-9]+).*" "\\1"
                     FREETYPE_VERSION_MAJOR ${FREETYPE_VERSION_FILE_CONTENTS})
string(REGEX REPLACE ".*#define FREETYPE_MINOR[ \t]+([0-9]+).*" "\\1"
                     FREETYPE_VERSION_MINOR ${FREETYPE_VERSION_FILE_CONTENTS})
string(REGEX REPLACE ".*#define FREETYPE_PATCH[ \t]+([0-9]+).*" "\\1"
                     FREETYPE_VERSION_PATCH ${FREETYPE_VERSION_FILE_CONTENTS})

project(
  freetype
  VERSION
    "${FREETYPE_VERSION_MAJOR}.${FREETYPE_VERSION_MINOR}.${FREETYPE_VERSION_PATCH}"
  LANGUAGES C)

# Use GNUInstallDirs to install libraries into correct locations on all
# platforms.
include(GNUInstallDirs)

set(PUBLIC_FT2BUILD_H "${FREETYPE_SOURCE_DIR}/include/ft2build.h")

set(FREETYPE_BASE_SRCS
    ${FREETYPE_SOURCE_DIR}/src/autofit/autofit.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftbase.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftbbox.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftbdf.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftbitmap.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftcid.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftfstype.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftgasp.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftglyph.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftgxval.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftinit.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftmm.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftotval.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftpatent.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftpfr.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftstroke.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftsynth.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftsystem.c
    ${FREETYPE_SOURCE_DIR}/src/base/fttype1.c
    ${FREETYPE_SOURCE_DIR}/src/base/ftwinfnt.c
    ${FREETYPE_SOURCE_DIR}/src/bdf/bdf.c
    ${FREETYPE_SOURCE_DIR}/src/bzip2/ftbzip2.c
    ${FREETYPE_SOURCE_DIR}/src/cache/ftcache.c
    ${FREETYPE_SOURCE_DIR}/src/cff/cff.c
    ${FREETYPE_SOURCE_DIR}/src/cid/type1cid.c
    ${FREETYPE_SOURCE_DIR}/src/gzip/ftgzip.c
    ${FREETYPE_SOURCE_DIR}/src/lzw/ftlzw.c
    ${FREETYPE_SOURCE_DIR}/src/pcf/pcf.c
    ${FREETYPE_SOURCE_DIR}/src/pfr/pfr.c
    ${FREETYPE_SOURCE_DIR}/src/psaux/psaux.c
    ${FREETYPE_SOURCE_DIR}/src/pshinter/pshinter.c
    ${FREETYPE_SOURCE_DIR}/src/psnames/psnames.c
    ${FREETYPE_SOURCE_DIR}/src/raster/raster.c
    ${FREETYPE_SOURCE_DIR}/src/sfnt/sfnt.c
    ${FREETYPE_SOURCE_DIR}/src/smooth/smooth.c
    ${FREETYPE_SOURCE_DIR}/src/truetype/truetype.c
    ${FREETYPE_SOURCE_DIR}/src/type1/type1.c
    ${FREETYPE_SOURCE_DIR}/src/type42/type42.c
    ${FREETYPE_SOURCE_DIR}/src/winfonts/winfnt.c)

set(FREETYPE_PUBLIC_CONFIG_HEADERS
    ${FREETYPE_SOURCE_DIR}/include/freetype/config/ftheader.h
    ${FREETYPE_SOURCE_DIR}/include/freetype/config/ftconfig.h
    ${FREETYPE_SOURCE_DIR}/include/freetype/config/ftmodule.h
    ${FREETYPE_SOURCE_DIR}/include/freetype/config/ftoption.h
    ${FREETYPE_SOURCE_DIR}/include/freetype/config/ftstdlib.h)

if(MSVC OR MINGW)
  enable_language(RC)
  list(APPEND FREETYPE_BASE_SRCS
       "${FREETYPE_SOURCE_DIR}/builds/windows/ftdebug.c"
       "${FREETYPE_SOURCE_DIR}/src/base/ftver.rc")
else()
  list(APPEND FREETYPE_BASE_SRCS "${FREETYPE_SOURCE_DIR}/src/base/ftdebug.c")
endif()

file(GLOB FREETYPE_PUBLIC_HEADERS "${FREETYPE_SOURCE_DIR}/include/freetype/*.h")
file(GLOB FREETYPE_PUBLIC_CONFIG_HEADERS
     "${FREETYPE_SOURCE_DIR}/include/freetype/config/*.h")
file(GLOB FREETYPE_PRIVATE_HEADERS
     "${FREETYPE_SOURCE_DIR}/include/freetype/internal/*.h")

if(MSVC)
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS) # Disable warnings
                                                             # for unsecure CRT
                                                             # functions
  list(APPEND PRIVATE_DEFINITIONS -DFT2_BUILD_LIBRARY)

  list(APPEND PRIVATE_DEBUG_DEFINITIONS -DFT_DEBUG_LEVEL_ERROR)
  list(APPEND PRIVATE_DEBUG_DEFINITIONS -DFT_DEBUG_LEVEL_TRACE)

  list(APPEND PRIVATE_OPTIONS /W4) # Warning Level 4
  # Supress warnings
  list(APPEND PRIVATE_OPTIONS /wd4001) # nonstandard extension 'single line
                                       # comment' was used
  list(APPEND PRIVATE_OPTIONS /wd4244) # conversion' conversion from 'type1' to
                                       # 'type2', possible loss of data
  list(APPEND PRIVATE_OPTIONS /wd4701) # Potentially uninitialized local
                                       # variable 'name' used
  list(APPEND PRIVATE_OPTIONS /wd4702) # unreachable code
  list(APPEND PRIVATE_OPTIONS /wd4100) # identifier' : unreferenced formal
                                       # parameter

  list(APPEND PRIVATE_OPTIONS /MP) # Build with Multiple Processes

  list(APPEND PRIVATE_RELEASE_OPTIONS /GF) # Enable Function-Level Linking
  list(APPEND PRIVATE_RELEASE_OPTIONS /Gy) # Eliminate Duplicate Strings
  list(APPEND PRIVATE_RELEASE_OPTIONS /Ob1) # Allows expansion only of functions
                                            # marked inline, __inline, or
                                            # __forceinline

  set(CMAKE_DEBUG_POSTFIX "d")
endif(MSVC)

if(MINGW)
  list(APPEND PRIVATE_DEFINITIONS -DFT2_BUILD_LIBRARY)
endif(MINGW)

add_library(
  freetype STATIC
  ${PUBLIC_FT2BUILD_H} ${FREETYPE_PUBLIC_HEADERS}
  ${FREETYPE_PUBLIC_CONFIG_HEADERS} ${FREETYPE_PRIVATE_HEADERS}
  ${FREETYPE_BASE_SRCS})

# Dependent include files
target_include_directories(
  freetype
  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
         $<BUILD_INTERFACE:${FREETYPE_SOURCE_DIR}/include>
         $<INSTALL_INTERFACE:include>)

target_compile_definitions(freetype PRIVATE ${PRIVATE_DEFINITIONS})

target_compile_definitions(
  freetype PRIVATE "$<$<CONFIG:DEBUG>:${PRIVATE_DEBUG_DEFINITIONS}>")

target_compile_options(
  freetype PRIVATE ${PRIVATE_OPTIONS}
                   "$<$<CONFIG:RELEASE>:${PRIVATE_RELEASE_OPTIONS}>")

set_target_properties(freetype PROPERTIES C_VISIBILITY_PRESET hidden)

# INSTALL
install(
  TARGETS freetype
  EXPORT freetype_export
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  INCLUDES
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES ${PUBLIC_FT2BUILD_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(FILES ${FREETYPE_PUBLIC_HEADERS}
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/freetype)
install(FILES ${FREETYPE_PUBLIC_CONFIG_HEADERS}
        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/freetype/config)


text:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
file(READ ${ZLIB_SOURCE_DIR}/zlib.h _zlib_h_contents)
string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
                     "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})

project(
  zlib
  VERSION ${ZLIB_FULL_VERSION}
  LANGUAGES C)

# Use GNUInstallDirs to install libraries into correct locations on all
# platforms.
include(GNUInstallDirs)

option(ZLIB_USE_ASM686 "Enable building i686 assembly implementation" OFF)
option(ZLIB_USE_AMD64 "Enable building amd64 assembly implementation" OFF)

mark_as_advanced(ZLIB_USE_ASM686 ZLIB_USE_AMD64)

include(CheckTypeSize)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckCSourceCompiles)

#
# Check to see if we have large file support
#
check_include_file(sys/types.h HAVE_SYS_TYPES_H)
check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(stddef.h HAVE_STDDEF_H)

if(HAVE_SYS_TYPES_H)
  list(APPEND PRIVATE_DEFINITIONS -DHAVE_SYS_TYPES_H)
endif()
if(HAVE_STDINT_H)
  list(APPEND PRIVATE_DEFINITIONS -DHAVE_STDINT_H)
endif()
if(HAVE_STDDEF_H)
  list(APPEND PRIVATE_DEFINITIONS -DHAVE_STDDEF_H)
endif()

check_type_size(off64_t OFF64_T)
if(HAVE_OFF64_T)
  list(APPEND PRIVATE_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
endif()

#
# Check for fseeko
#
check_function_exists(fseeko HAVE_FSEEKO)
if(NOT HAVE_FSEEKO)
  list(APPEND PRIVATE_DEFINITIONS -DNO_FSEEKO)
endif()

#
# Check for unistd.h
#
check_include_file(unistd.h Z_HAVE_UNISTD_H)

# Visual studio options
if(MSVC)
  set(CMAKE_DEBUG_POSTFIX "d")
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_SECURE_NO_DEPRECATE) # Disable warnings
                                                              # for unsecure CRT
                                                              # functions
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_NONSTDC_NO_DEPRECATE) # Disable
                                                               # warnings for
                                                               # POSIX
                                                               # deprecated
                                                               # functions
endif()

set(ZLIB_PC zlib.pc)
configure_file(${ZLIB_SOURCE_DIR}/zlib.pc.cmakein ${ZLIB_PC} @ONLY)
configure_file(${ZLIB_SOURCE_DIR}/zconf.h.cmakein zconf.h @ONLY)
configure_file(${ZLIB_SOURCE_DIR}/zlib.h zlib.h COPYONLY)

# ============================================================================
# zlib
# ============================================================================

set(ZLIB_PUBLIC_HDRS ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
                     ${CMAKE_CURRENT_BINARY_DIR}/zlib.h)

set(ZLIB_PRIVATE_HDRS
    ${ZLIB_SOURCE_DIR}/crc32.h
    ${ZLIB_SOURCE_DIR}/deflate.h
    ${ZLIB_SOURCE_DIR}/gzguts.h
    ${ZLIB_SOURCE_DIR}/inffast.h
    ${ZLIB_SOURCE_DIR}/inffixed.h
    ${ZLIB_SOURCE_DIR}/inflate.h
    ${ZLIB_SOURCE_DIR}/inftrees.h
    ${ZLIB_SOURCE_DIR}/trees.h
    ${ZLIB_SOURCE_DIR}/zutil.h)

set(ZLIB_SRCS
    ${ZLIB_SOURCE_DIR}/adler32.c
    ${ZLIB_SOURCE_DIR}/compress.c
    ${ZLIB_SOURCE_DIR}/crc32.c
    ${ZLIB_SOURCE_DIR}/deflate.c
    ${ZLIB_SOURCE_DIR}/gzclose.c
    ${ZLIB_SOURCE_DIR}/gzlib.c
    ${ZLIB_SOURCE_DIR}/gzread.c
    ${ZLIB_SOURCE_DIR}/gzwrite.c
    ${ZLIB_SOURCE_DIR}/inflate.c
    ${ZLIB_SOURCE_DIR}/infback.c
    ${ZLIB_SOURCE_DIR}/inftrees.c
    ${ZLIB_SOURCE_DIR}/inffast.c
    ${ZLIB_SOURCE_DIR}/trees.c
    ${ZLIB_SOURCE_DIR}/uncompr.c
    ${ZLIB_SOURCE_DIR}/zutil.c)

if(NOT MINGW)
  set(ZLIB_DLL_SRCS
      ${ZLIB_SOURCE_DIR}/win32/zlib1.rc # If present will override custom build
                                        # rule below.
  )
endif()

if(CMAKE_COMPILER_IS_GNUCC)
  if(ZLIB_USE_ASM686)
    set(ZLIB_ASMS ${ZLIB_SOURCE_DIR}/contrib/asm686/match.S)
  elseif(ZLIB_USE_AMD64)
    set(ZLIB_ASMS ${ZLIB_SOURCE_DIR}/contrib/amd64/amd64-match.S)
  endif()

  if(ZLIB_ASMS)
    list(APPEND PRIVATE_DEFINITIONS -DASMV)
    set_source_files_properties(
      ${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
  endif()
endif()

if(MSVC)
  if(ZLIB_USE_ASM686)
    enable_language(ASM_MASM)
    set(ZLIB_ASMS ${ZLIB_SOURCE_DIR}/contrib/masmx86/inffas32.asm
                  ${ZLIB_SOURCE_DIR}/contrib/masmx86/match686.asm)
  elseif(ZLIB_USE_AMD64)
    enable_language(ASM_MASM)
    set(ZLIB_ASMS ${ZLIB_SOURCE_DIR}/contrib/masmx64/gvmat64.asm
                  ${ZLIB_SOURCE_DIR}/contrib/masmx64/inffasx64.asm)

    list(APPEND ZLIB_SRCS ${ZLIB_SOURCE_DIR}/contrib/masmx64/inffas8664.c)
  endif()

  if(ZLIB_ASMS)
    list(APPEND PRIVATE_DEFINITIONS -DASMV -DASMINF)
  endif()
endif()

if(MINGW)
  # This gets us DLL resource information when compiling on MinGW.
  if(NOT CMAKE_RC_COMPILER)
    set(CMAKE_RC_COMPILER windres.exe)
  endif()

  add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
    COMMAND
      ${CMAKE_RC_COMPILER} -D GCC_WINDRES -I ${ZLIB_SOURCE_DIR} -I
      ${CMAKE_CURRENT_BINARY_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj -i
      ${ZLIB_SOURCE_DIR}/win32/zlib1.rc)
  set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
endif(MINGW)

add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS}
                        ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})

# Dependent include files
target_include_directories(
  zlib PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
              $<INSTALL_INTERFACE:include>)

target_compile_definitions(zlib PRIVATE ${PRIVATE_DEFINITIONS})

set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
set_target_properties(zlib PROPERTIES SOVERSION 1)

if(NOT CYGWIN)
  # This property causes shared libraries on Linux to have the full version
  # encoded into their final filename.  We disable this on Cygwin because it
  # causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll seems to be
  # the default.
  #
  # This has no effect with MSVC, on that platform the version info for the DLL
  # comes from the resource file win32/zlib1.rc
  set_target_properties(zlib PROPERTIES ZLIB_VERSION ${ZLIB_FULL_VERSION})
endif()

if(UNIX)
  # On unix-like platforms the library is almost always called libz
  set_target_properties(zlib PROPERTIES OUTPUT_NAME z)
  if(NOT APPLE)
    set_target_properties(
      zlib PROPERTIES LINK_FLAGS
                      "-Wl,--version-script,\"${ZLIB_SOURCE_DIR}/zlib.map\"")
  endif()
elseif(BUILD_SHARED_LIBS AND WIN32)
  # Creates zlib1.dll when building shared library version
  set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
endif()

if(MINGW)
  # Static library name
  set_target_properties(zlib PROPERTIES IMPORT_PREFIX "")
  set_target_properties(zlib PROPERTIES IMPORT_SUFFIX "1.a")
  # Shared library name
  set_target_properties(zlib PROPERTIES PREFIX "")
  set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
endif()

install(
  TARGETS zlib
  EXPORT zlib_export
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  INCLUDES
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})


text:
#include <stdint.h>

/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1

/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1

/* Define as 0 or 1 according to the floating point format suported by the
   machine */
#define HAVE_IEEEFP 1

/* Define to 1 if you have the `jbg_newlen' function. */
#define HAVE_JBG_NEWLEN 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <io.h> header file. */
#define HAVE_IO_H 1

/* Define to 1 if you have the <search.h> header file. */
#define HAVE_SEARCH_H 1

/* Define to 1 if you have the `setmode' function. */
#define HAVE_SETMODE 1

/* The size of a `int', as computed by sizeof. */
#define SIZEOF_INT 4

/* The size of a `long', as computed by sizeof. */
#define SIZEOF_LONG 4

/* Signed 64-bit type formatter */
#define TIFF_INT64_FORMAT "%I64d"

/* Signed 64-bit type */
#define TIFF_INT64_T int64_t

/* Unsigned 64-bit type formatter */
#define TIFF_UINT64_FORMAT "%I64u"

/* Unsigned 64-bit type */
#define TIFF_UINT64_T  uint64_t

/* Set the native cpu bit order */
#define HOST_FILLORDER FILLORDER_LSB2MSB

#define snprintf _snprintf

/* Define to 1 if your processor stores words with the most significant byte
   first (like Motorola and SPARC, unlike Intel and VAX). */
/* #undef WORDS_BIGENDIAN */

/* Define to `__inline__' or `__inline' if that's what the C compiler
   calls it, or to nothing if 'inline' is not supported under any name.  */
#ifndef __cplusplus
# ifndef inline
#  define inline __inline
# endif
#endif

#define lfind _lfind
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 8
 * fill-column: 78
 * End:
 */


text:
/*
  Configuration defines for installed libtiff.
  This file maintained for backward compatibility. Do not use definitions
  from this file in your programs.
*/

#ifndef _TIFFCONF_
#define _TIFFCONF_
#include <stdint.h>

/* Define to 1 if the system has the type `int16'. */
/* #undef HAVE_INT16 */

/* Define to 1 if the system has the type `int32'. */
/* #undef HAVE_INT32 */

/* Define to 1 if the system has the type `int8'. */
/* #undef HAVE_INT8 */

/* The size of a `int', as computed by sizeof. */
#define SIZEOF_INT 4

/* Signed 8-bit type */
#define TIFF_INT8_T signed char

/* Unsigned 8-bit type */
#define TIFF_UINT8_T unsigned char

/* Signed 16-bit type */
#define TIFF_INT16_T signed short

/* Unsigned 16-bit type */
#define TIFF_UINT16_T unsigned short

/* Signed 32-bit type formatter */
#define TIFF_INT32_FORMAT "%d"

/* Signed 32-bit type */
#define TIFF_INT32_T signed int

/* Unsigned 32-bit type formatter */
#define TIFF_UINT32_FORMAT "%u"

/* Unsigned 32-bit type */
#define TIFF_UINT32_T unsigned int

/* Signed 64-bit type formatter */
#define TIFF_INT64_FORMAT "%I64d"

/* Signed 64-bit type */
#define TIFF_INT64_T int64_t

/* Unsigned 64-bit type formatter */
#define TIFF_UINT64_FORMAT "%I64u"

/* Unsigned 64-bit type */
#define TIFF_UINT64_T uint64_t

/* Signed size type */
#if defined(_WIN64)
#define TIFF_SSIZE_T int64_t
#else
#define TIFF_SSIZE_T signed int
#endif

/* Signed size type formatter */
#if defined(_WIN64)
#define TIFF_SSIZE_FORMAT "%I64d"
#else
#define TIFF_SSIZE_FORMAT "%ld"
#endif

/* Pointer difference type */
#define TIFF_PTRDIFF_T long

/* Compatibility stuff. */

/* Define as 0 or 1 according to the floating point format suported by the
   machine */
#define HAVE_IEEEFP 1

/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
#define HOST_FILLORDER FILLORDER_LSB2MSB

/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
   (Intel) */
#define HOST_BIGENDIAN 0

/* Support CCITT Group 3 & 4 algorithms */
#define CCITT_SUPPORT 1

/* Support JPEG compression (requires IJG JPEG library) */
/* #undef JPEG_SUPPORT */

/* Support JBIG compression (requires JBIG-KIT library) */
/* #undef JBIG_SUPPORT */

/* Support LogLuv high dynamic range encoding */
#define LOGLUV_SUPPORT 1

/* Support LZW algorithm */
#define LZW_SUPPORT 1

/* Support NeXT 2-bit RLE algorithm */
#define NEXT_SUPPORT 1

/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
   fails with unpatched IJG JPEG library) */
/* #undef OJPEG_SUPPORT */

/* Support Macintosh PackBits algorithm */
#define PACKBITS_SUPPORT 1

/* Support Pixar log-format algorithm (requires Zlib) */
/* #undef PIXARLOG_SUPPORT */

/* Support ThunderScan 4-bit RLE algorithm */
#define THUNDER_SUPPORT 1

/* Support Deflate compression */
/* #undef ZIP_SUPPORT */

/* Support strip chopping (whether or not to convert single-strip uncompressed
   images to mutiple strips of ~8Kb to reduce memory usage) */
#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP

/* Enable SubIFD tag (330) support */
#define SUBIFD_SUPPORT 1

/* Treat extra sample as alpha (default enabled). The RGBA interface will
   treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
   packages produce RGBA files but don't mark the alpha properly. */
#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1

/* Pick up YCbCr subsampling info from the JPEG data stream to support files
   lacking the tag (default enabled). */
#define CHECK_JPEG_YCBCR_SUBSAMPLING 1

/* Support MS MDI magic number files as TIFF */
/* #undef MDI_SUPPORT */

/*
 * Feature support definitions.
 * XXX: These macros are obsoleted. Don't use them in your apps!
 * Macros stays here for backward compatibility and should be always defined.
 */
#define COLORIMETRY_SUPPORT
#define YCBCR_SUPPORT
#define CMYK_SUPPORT
#define ICC_SUPPORT
#define PHOTOSHOP_SUPPORT
#define IPTC_SUPPORT

#endif /* _TIFFCONF_ */
/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 8
 * fill-column: 78
 * End:
 */


text:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

# parse the full version number from tiffvers.h and include in
# LIBTIFF_FULL_VERSION
file(STRINGS "${LIBTIFF_SOURCE_DIR}/VERSION" LIBTIFF_FULL_VERSION
     REGEX "[0-9]+\\.[0-9]+\\.[0-9]+")

project(
  libtiff
  VERSION ${LIBTIFF_FULL_VERSION}
  LANGUAGES C)

# Use GNUInstallDirs to install libraries into correct locations on all
# platforms.
include(GNUInstallDirs)

if(MSVC)
  set(tif_config "${LIBTIFF_SOURCE_DIR}/libtiff/tif_config.vc.h")
  set(tiffconf "${LIBTIFF_SOURCE_DIR}/libtiff/tiffconf.vc.h")
endif()

if(MINGW)
  set(tif_config "${CMAKE_CURRENT_SOURCE_DIR}/tif_config.mingw.h")
  set(tiffconf "${CMAKE_CURRENT_SOURCE_DIR}/tiffconf.mingw.h")
endif()

configure_file(${tif_config} tif_config.h @ONLY)
configure_file(${tiffconf} tiffconf.h @ONLY)

configure_file(${LIBTIFF_SOURCE_DIR}/libtiff/tiff.h tiff.h COPYONLY)
configure_file(${LIBTIFF_SOURCE_DIR}/libtiff/tiffio.h tiffio.h COPYONLY)
configure_file(${LIBTIFF_SOURCE_DIR}/libtiff/tiffvers.h tiffvers.h COPYONLY)

set(LIBTIFF_PUBLIC_HEADERS
    ${CMAKE_CURRENT_BINARY_DIR}/tiffconf.h ${CMAKE_CURRENT_BINARY_DIR}/tiff.h
    ${CMAKE_CURRENT_BINARY_DIR}/tiffio.h ${CMAKE_CURRENT_BINARY_DIR}/tiffvers.h)

set(LIBTIFF_PRIVATE_HEADERS
    ${CMAKE_CURRENT_BINARY_DIR}/tif_config.h
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_dir.h
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_fax3.h
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_predict.h
    ${LIBTIFF_SOURCE_DIR}/libtiff/tiffiop.h
    ${LIBTIFF_SOURCE_DIR}/libtiff/t4.h
    ${LIBTIFF_SOURCE_DIR}/libtiff/uvcode.h)

set(LIBTIFF_SRCS
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_aux.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_close.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_codec.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_color.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_compress.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_dir.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_dirinfo.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_dirread.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_dirwrite.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_dumpmode.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_error.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_extension.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_fax3.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_fax3sm.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_flush.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_getimage.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_jbig.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_jpeg.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_luv.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_lzw.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_next.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_ojpeg.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_open.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_packbits.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_pixarlog.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_predict.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_print.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_read.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_strip.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_swab.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_thunder.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_tile.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_version.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_warning.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_win32.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_write.c
    ${LIBTIFF_SOURCE_DIR}/libtiff/tif_zip.c)

# Check if we have SNPRINTF:
include(CheckFunctionExists)
check_function_exists(snprintf HAVE_SNPRINTF)

if(HAVE_SNPRINTF)
  list(APPEND PRIVATE_DEFINITIONS -DHAVE_SNPRINTF)
endif()

if(MSVC)
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS) # Disable warnings
                                                             # for unsecure CRT
                                                             # functions
  list(APPEND PRIVATE_DEFINITIONS -D_LIB)
  list(APPEND PRIVATE_OPTIONS /Gy) # Eliminate Duplicate Strings
  list(APPEND PRIVATE_OPTIONS /Oi) # Generate Intrinsic Functions
  list(APPEND PRIVATE_OPTIONS /wd4244) # conversion' conversion from 'type1' to
                                       # 'type2', possible loss of data
  set(CMAKE_DEBUG_POSTFIX "d_i")
  set(CMAKE_RELEASE_POSTFIX "_i")
endif(MSVC)

add_library(libtiff STATIC ${LIBTIFF_SRCS} ${LIBTIFF_PRIVATE_HEADERS}
                           ${LIBTIFF_PUBLIC_HEADERS})

# Dependent include files
target_include_directories(
  libtiff PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
                 $<INSTALL_INTERFACE:include>)

target_compile_definitions(libtiff PRIVATE ${PRIVATE_DEFINITIONS})

target_compile_options(libtiff PRIVATE ${PRIVATE_OPTIONS})

target_link_libraries(libtiff zlib jpeg)

if(MINGW)
  # Static library name
  set_target_properties(${TARGET_LIB} PROPERTIES PREFIX "")
  set_target_properties(${TARGET_LIB} PROPERTIES SUFFIX ".a")
endif()

# INSTALL
install(
  TARGETS libtiff
  EXPORT libtiff_export
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  INCLUDES
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES ${LIBTIFF_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})


text:
#ifndef _UNISTD_H
#define _UNISTD_H    1

/* This file intended to serve as a drop-in replacement for
 *  unistd.h on Windows
 *  Please add functionality as neeeded
 */

#include <stdlib.h>
#include <io.h>
#include <getopt.h> /* getopt at: https://gist.github.com/ashelly/7776712*/
#include <process.h> /* for getpid() and the exec..() family */
#include <direct.h> /* for _getcwd() and _chdir() */

#define srandom srand
#define random rand

/* Values for the second argument to access.
   These may be OR'd together.  */
#define R_OK    4       /* Test for read permission.  */
#define W_OK    2       /* Test for write permission.  */
//#define   X_OK    1       /* execute permission - unsupported in windows*/
#define F_OK    0       /* Test for existence.  */

#define access _access
#define dup2 _dup2
#define execve _execve
#define ftruncate _chsize
#define unlink _unlink
#define fileno _fileno
#define getcwd _getcwd
#define chdir _chdir
#define isatty _isatty
#define lseek _lseek
/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */

#define ssize_t int

#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
/* should be in some equivalent to <sys/types.h> */
typedef __int8            int8_t;
typedef __int16           int16_t;
typedef __int32           int32_t;
typedef __int64           int64_t;
typedef unsigned __int8   uint8_t;
typedef unsigned __int16  uint16_t;
typedef unsigned __int32  uint32_t;
typedef unsigned __int64  uint64_t;

#endif /* unistd.h  */


text:
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

file(READ ${GIFLIB_SOURCE_DIR}/gif_lib.h _gif_lib_h_contents)
string(REGEX REPLACE ".*#define[ \t]+GIFLIB_MAJOR[ \t]+([0-9]+).*" "\\1"
                     GIFLIB_MAJOR_VERSION ${_gif_lib_h_contents})
string(REGEX REPLACE ".*#define[ \t]+GIFLIB_MINOR[ \t]+([0-9]+).*" "\\1"
                     GIFLIB_MINOR_VERSION ${_gif_lib_h_contents})
string(REGEX REPLACE ".*#define[ \t]+GIFLIB_RELEASE[ \t]+([0-9]+).*" "\\1"
                     GIFLIB_RELEASE_VERSION ${_gif_lib_h_contents})

project(
  giflib
  VERSION
    "${GIFLIB_MAJOR_VERSION}.${GIFLIB_MINOR_VERSION}.${GIFLIB_RELEASE_VERSION}"
  LANGUAGES C)

# Use GNUInstallDirs to install libraries into correct locations on all
# platforms.
include(GNUInstallDirs)

set(GIFLIB_PUBLIC_HEADERS ${GIFLIB_SOURCE_DIR}/gif_lib.h)

set(GIFLIB_PRIVATE_HEADERS ${GIFLIB_SOURCE_DIR}/gif_lib_private.h
                           ${GIFLIB_SOURCE_DIR}/gif_hash.h)

set(GIFLIB_SRCS
    ${GIFLIB_SOURCE_DIR}/dgif_lib.c
    ${GIFLIB_SOURCE_DIR}/egif_lib.c
    ${GIFLIB_SOURCE_DIR}/gif_err.c
    ${GIFLIB_SOURCE_DIR}/gif_font.c
    ${GIFLIB_SOURCE_DIR}/gif_hash.c
    ${GIFLIB_SOURCE_DIR}/gifalloc.c
    ${GIFLIB_SOURCE_DIR}/quantize.c
    ${GIFLIB_SOURCE_DIR}/openbsd-reallocarray.c)

if(MSVC)
  # Create file to avoid include file name collision on other platforms
  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/unistd.h.in unistd.h @ONLY)

  # Add unistd.h, getopt.h, getopt.c and stdbool.h for windows build getopt
  # from: http://gist.github.com/ashelly/7776712 unistd.h from:
  # http://stackoverflow.com/questions/341817/is-there-a-replacement-for-unistd-h-for-windows-visual-c
  # stdbool.h is just a simple redefinition of bool as int
  set(GIFLIB_PUBLIC_HEADERS ${GIFLIB_PUBLIC_HEADERS}
                            ${CMAKE_CURRENT_SOURCE_DIR}/stdbool.h)

  set(GIFLIB_PRIVATE_HEADERS
      ${GIFLIB_PRIVATE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/getopt.h
      ${CMAKE_CURRENT_SOURCE_DIR}/unistd.h)

  set(GIFLIB_SRCS ${GIFLIB_SRCS} ${CMAKE_CURRENT_SOURCE_DIR}/getopt.c)
endif(MSVC)

if(MSVC)
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS) # Disable warnings
                                                             # for unsecure CRT
                                                             # functions
  list(APPEND PRIVATE_DEFINITIONS -D_LIB) #
  list(APPEND PRIVATE_DEFINITIONS -DWIN32) #

  # Supress warnings
  list(APPEND PRIVATE_OPTIONS /wd4018) # expression' : signed/unsigned mismatch
  list(APPEND PRIVATE_OPTIONS /wd4028) # formal parameter 'number' different
                                       # from declaration
  list(APPEND PRIVATE_OPTIONS /wd4244) # conversion' conversion from 'type1' to
                                       # 'type2', possible loss of data
  list(APPEND PRIVATE_OPTIONS /wd4996) # The compiler encountered a deprecated
                                       # declaration.

  set(CMAKE_DEBUG_POSTFIX "d")
endif(MSVC)

if(MINGW)
  list(APPEND PRIVATE_DEFINITIONS -D_CRT_SECURE_NO_WARNINGS) # Disable warnings
                                                             # for unsecure CRT
                                                             # functions
  list(APPEND PRIVATE_DEFINITIONS -D_LIB) #
endif(MINGW)

add_library(giflib STATIC ${GIFLIB_SRCS} ${GIFLIB_PUBLIC_HEADERS}
                          ${GIFLIB_PRIVATE_HEADERS})

# Dependent include files
target_include_directories(
  giflib
  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
         $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
         $<INSTALL_INTERFACE:include>)

target_compile_definitions(giflib PRIVATE ${PRIVATE_DEFINITIONS})

target_compile_options(giflib PRIVATE ${PRIVATE_OPTIONS})

if(MINGW)
  set_target_properties(${TARGET_LIB} PROPERTIES OUTPUT_NAME gif)
endif()

# INSTALL
install(
  TARGETS giflib
  EXPORT giflib_export
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  INCLUDES
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(FILES ${GIFLIB_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})