Code Monkey home page Code Monkey logo

mapguide-fdo-docker-build's Introduction

A docker-driven build system for MapGuide and FDO

This is a docker-driven build system for MapGuide and FDO

Requirements

  • A linux host OS that can run Docker
  • Git
  • Subversion

Usage

1. Clone this repo and checkout MapGuide/FDO repositories

git clone https://github.com/jumpinjackie/mapguide-fdo-docker-build`
./svn_checkout.sh

2. Set up your desired target environment

Suppose you want to build MapGuide/FDO for Ubuntu 22.04 (64-bit)

./env_setup.sh --target fdo --distro ubuntu --tag 16.04 --cpu x64
./env_setup.sh --target mapguide --distro ubuntu --tag 16.04 --cpu x64

This will generate a series of Dockerfile and snap.sh build scripts in:

  • docker/x64/fdo/ubuntu22/build
  • docker/x64/fdo/ubuntu22/develop_thin
  • docker/x64/fdo/ubuntu22/run
  • docker/x64/mapguide/ubuntu22/build
  • docker/x64/mapguide/ubuntu22/develop_thin
  • docker/x64/mapguide/ubuntu22/run

The --distro and --tag parameters are composed into the base docker image from which our target environment is built on top of, so in the above example, our docker environment will ultimately be based from the ubuntu:16.04 docker base image

A convenience env_setup_all.sh is provided that sets up the docker environments for all supported distros

The --distro and --tag combinations we currently recognise in this script are:

  • centos and 7
  • ubuntu and 22.04
  • generic and no tag

The generic distro is a centos:7 container geared towards building the "common libs subset" of MapGuide, whose .so binaries are bundled with a multi-platform .net API binding nuget package.

3. Run the build

Assuming you set up the target environment for Ubuntu 22.04 (64-bit), then to build FDO, run:

./build_thin.sh --target fdo --distro ubuntu --tag 22 --cpu x64

Once FDO is built, the tarballs will be copied to the top-level artifacts folder.

To build MapGuide, run:

./build_thin.sh --target mapguide --distro ubuntu --tag 22 --cpu x64

NOTE: You must build FDO first (and its SDK tarball present in artifacts) before you can build MapGuide.

A convenience build_all_thin.sh is provided that will build MapGuide/FDO for all supported distros

All MapGuide/FDO build containers are "thin" in the sense that source code and compiler output is not added to these docker images, only the development tools and libraries are added to the image. Source code and compiler output are read and written to directories referenced outside from the docker host via mounted volumes.

  • /build_area is the root of all intermediate compiler output
  • /fdo is the svn checkout of FDO trunk
  • /mapguide is the svn checkout of MapGuide trunk

All MapGuide/FDO build containers also leverage the use of ccache to store their compilation output to a volume mounted ccache cache directory (the /caches sub-directory in this repo)

These 2 combined, result in a build pipeline that is very fast for builds after the first build, allowing for a rapid developer/iteration inner-loop.

4. Running test suites

TBD

Supported build environments

target distro tag
mapguide centos 7
mapguide ubuntu 22.04
fdo ubuntu 16.04
fdo ubuntu 18.04
fdo centos 7

Building for 32-bit Linux distros is not supported.

Our canonical distros for building MapGuide releases for Linux are:

  • CentOS 7
  • Ubuntu 22.04

FDO Thirdparty matrix

On Windows, all internal thirdparty libraries are used

Distro GDAL OpenSSL libcurl mysqlclient mariadbclient libpq xalan-c xerces-c
centos7 Internal/dynamic Internal/static Internal/static N/A Internal/static Internal/static Internal/dynamic Internal/dynamic
ubuntu22 System System System System N/A System System System

MapGuide Thirdparty matrix

On Windows, all internal thirdparty libraries are used

Distro ACE dbxml berkely db xqilla geos gd libpng freetype libjpeg zlib xerces-c
centos7 Internal/dynamic Internal/dynamic Internal/dynamic Internal/dynamic Internal/static Internal/static Internal/static Internal/static Internal/static Internal/static Internal/dynamic
ubuntu22 System Internal/dynamic Internal/dynamic Internal/dynamic Internal/static^ System System System System System System

^ The version of GEOS library shipped with Ubuntu 22.04 has an incompatible C++ API that is too difficult to #ifdef around. Until MapGuide switches to using GEOS's C API we will have to build MapGuide against our internal copy for the foreseeable future

Known issues

MapGuide has not been tested to build on Ubuntu versions older than 22.04

WSL2 Notes

centos based images/containers may fail to build/run. To address this, edit %USERPROFILE%\.wslconfig as follows:

[wsl2]
kernelCommandLine = vsyscall=emulate

Also, you must use Docker Desktop for Windows as the docker engine when going the WSL2 route. Alternatives like Rancher Desktop are not suitable yet due to various unresolved bugs around volume mounting that breaks building MapGuide/FDO code within dev containers.

Credits

This docker-based build system was heavily inspired by: https://github.com/MatrixManAtYrService/lifecycle-snapshots

mapguide-fdo-docker-build's People

Contributors

jumpinjackie avatar

Stargazers

Noam Brand avatar Bruce Pinheiro de Carvalho avatar

Watchers

 avatar James Cloos avatar  avatar

mapguide-fdo-docker-build's Issues

CentOS: Build FDO against custom MySQL/PostgreSQL libs

The system provided mysql/postgresql client packages are too old for us (even if our providers build/link against them without issues) on the versions of CentOS we care to target. Thus we should build FDO on centos against custom MySQL/PostgreSQL versions:

Strip release binaries

Our CentOS 6 FDO SDK is currently 50MB undoubtedly due to it containing binaries that have not been stripped of unused symbols.

As FDO uses CPack for tarball production, we should look at activating CPACK_STRIP_FILES

For MapGuide, binaries should be manually stripped before tarball production

Support version stamping

Currently all mapguide/fdo tarballs will always built and named 4.0.0.0 and 4.2.0.0 respectively.

These version number components need to be parameterized.

Ubuntu18 MapGuide build failure

MapGuide build is failing on xqilla despite the submodule having this fix already incorporated???

libtool: compile:  ccache g++ -DHAVE_CONFIG_H -I. -I.. -I./src/config -I../include/ -I/usr/include -I../src/lexer/ -D_GNU_SOURCE -D_REENTRANT -O2 -ftemplate-depth-50 -MT XQCopy.lo -MD -MP -MF .deps/XQCopy.Tpo -c ../src/ast/XQCopy.cpp  -fPIC -DPIC -o .libs/XQCopy.o
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc: In instantiation of 'std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = ASTNode*; _Alloc = XQillaAllocator<ASTNode*>]':
../include/xqilla/ast/XQCopy.hpp:47:70:   required from here
/usr/include/c++/7/bits/vector.tcc:188:37: error: no match for 'operator!=' (operand types are 'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' and 'const _Tp_alloc_type {aka const XQillaAllocator<ASTNode*>}')
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/iosfwd:40:0,
                 from /usr/include/c++/7/ios:38,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/postypes.h:221:5: note: candidate: template<class _StateT> bool std::operator!=(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
     operator!=(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
     ^~~~~~~~
/usr/include/c++/7/bits/postypes.h:221:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::fpos<_StateT>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/stl_pair.h:456:5: note: candidate: template<class _T1, class _T2> constexpr bool std::operator!=(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
     operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     ^~~~~~~~
/usr/include/c++/7/bits/stl_pair.h:456:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::pair<_T1, _T2>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/stl_iterator.h:311:5: note: candidate: template<class _Iterator> bool std::operator!=(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
     operator!=(const reverse_iterator<_Iterator>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:311:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::reverse_iterator<_Iterator>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/stl_iterator.h:349:5: note: candidate: template<class _IteratorL, class _IteratorR> bool std::operator!=(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
     operator!=(const reverse_iterator<_IteratorL>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:349:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::reverse_iterator<_Iterator>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/stl_iterator.h:1130:5: note: candidate: template<class _IteratorL, class _IteratorR> bool std::operator!=(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)
     operator!=(const move_iterator<_IteratorL>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:1130:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::move_iterator<_IteratorL>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
                 from /usr/include/c++/7/bits/char_traits.h:39,
                 from /usr/include/c++/7/ios:40,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/stl_iterator.h:1136:5: note: candidate: template<class _Iterator> bool std::operator!=(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorL>&)
     operator!=(const move_iterator<_Iterator>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:1136:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::move_iterator<_IteratorL>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/string:41:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/allocator.h:158:5: note: candidate: template<class _T1, class _T2> bool std::operator!=(const std::allocator<_CharT>&, const std::allocator<_T2>&)
     operator!=(const allocator<_T1>&, const allocator<_T2>&)
     ^~~~~~~~
/usr/include/c++/7/bits/allocator.h:158:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::allocator<_CharT>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/string:41:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/allocator.h:164:5: note: candidate: template<class _Tp> bool std::operator!=(const std::allocator<_CharT>&, const std::allocator<_CharT>&)
     operator!=(const allocator<_Tp>&, const allocator<_Tp>&)
     ^~~~~~~~
/usr/include/c++/7/bits/allocator.h:164:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::allocator<_CharT>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/string:52:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/basic_string.h:6047:5: note: candidate: template<class _CharT, class _Traits, class _Alloc> bool std::operator!=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&, const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&)
     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
     ^~~~~~~~
/usr/include/c++/7/bits/basic_string.h:6047:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/string:52:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/basic_string.h:6060:5: note: candidate: template<class _CharT, class _Traits, class _Alloc> bool std::operator!=(const _CharT*, const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&)
     operator!=(const _CharT* __lhs,
     ^~~~~~~~
/usr/include/c++/7/bits/basic_string.h:6060:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   mismatched types 'const _CharT*' and 'XQillaAllocator<ASTNode*>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/string:52:0,
                 from /usr/include/c++/7/bits/locale_classes.h:40,
                 from /usr/include/c++/7/bits/ios_base.h:41,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/basic_string.h:6072:5: note: candidate: template<class _CharT, class _Traits, class _Alloc> bool std::operator!=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
     operator!=(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
     ^~~~~~~~
/usr/include/c++/7/bits/basic_string.h:6072:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/bits/ios_base.h:46:0,
                 from /usr/include/c++/7/ios:42,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/system_error:319:3: note: candidate: bool std::operator!=(const std::error_code&, const std::error_code&)
   operator!=(const error_code& __lhs, const error_code& __rhs) noexcept
   ^~~~~~~~
/usr/include/c++/7/system_error:319:3: note:   no known conversion for argument 1 from 'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' to 'const std::error_code&'
/usr/include/c++/7/system_error:323:3: note: candidate: bool std::operator!=(const std::error_code&, const std::error_condition&)
   operator!=(const error_code& __lhs, const error_condition& __rhs) noexcept
   ^~~~~~~~
/usr/include/c++/7/system_error:323:3: note:   no known conversion for argument 1 from 'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' to 'const std::error_code&'
/usr/include/c++/7/system_error:327:3: note: candidate: bool std::operator!=(const std::error_condition&, const std::error_code&)
   operator!=(const error_condition& __lhs, const error_code& __rhs) noexcept
   ^~~~~~~~
/usr/include/c++/7/system_error:327:3: note:   no known conversion for argument 1 from 'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' to 'const std::error_condition&'
/usr/include/c++/7/system_error:331:3: note: candidate: bool std::operator!=(const std::error_condition&, const std::error_condition&)
   operator!=(const error_condition& __lhs,
   ^~~~~~~~
/usr/include/c++/7/system_error:331:3: note:   no known conversion for argument 1 from 'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' to 'const std::error_condition&'
In file included from /usr/include/c++/7/bits/locale_facets.h:48:0,
                 from /usr/include/c++/7/bits/basic_ios.h:37,
                 from /usr/include/c++/7/ios:44,
                 from /usr/include/c++/7/istream:38,
                 from /usr/include/c++/7/sstream:38,
                 from ../src/ast/XQCopy.cpp:24:
/usr/include/c++/7/bits/streambuf_iterator.h:210:5: note: candidate: template<class _CharT, class _Traits> bool std::operator!=(const std::istreambuf_iterator<_CharT, _Traits>&, const std::istreambuf_iterator<_CharT, _Traits>&)
     operator!=(const istreambuf_iterator<_CharT, _Traits>& __a,
     ^~~~~~~~
/usr/include/c++/7/bits/streambuf_iterator.h:210:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::istreambuf_iterator<_CharT, _Traits>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/vector:64:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/stl_vector.h:1620:5: note: candidate: template<class _Tp, class _Alloc> bool std::operator!=(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)
     operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
     ^~~~~~~~
/usr/include/c++/7/bits/stl_vector.h:1620:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::vector<_Tp, _Alloc>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/set:60:0,
                 from ../include/xqilla/ast/XQElementConstructor.hpp:30,
                 from ../src/ast/XQCopy.cpp:30:
/usr/include/c++/7/bits/stl_tree.h:412:5: note: candidate: template<class _Val> bool std::operator!=(const std::_Rb_tree_iterator<_Tp>&, const std::_Rb_tree_const_iterator<_Val>&)
     operator!=(const _Rb_tree_iterator<_Val>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_tree.h:412:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::_Rb_tree_iterator<_Tp>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/set:60:0,
                 from ../include/xqilla/ast/XQElementConstructor.hpp:30,
                 from ../src/ast/XQCopy.cpp:30:
/usr/include/c++/7/bits/stl_tree.h:1553:5: note: candidate: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator!=(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
     operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_tree.h:1553:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/set:61:0,
                 from ../include/xqilla/ast/XQElementConstructor.hpp:30,
                 from ../src/ast/XQCopy.cpp:30:
/usr/include/c++/7/bits/stl_set.h:937:5: note: candidate: template<class _Key, class _Compare, class _Alloc> bool std::operator!=(const std::set<_Key, _Compare, _Alloc>&, const std::set<_Key, _Compare, _Alloc>&)
     operator!=(const set<_Key, _Compare, _Alloc>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_set.h:937:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::set<_Key, _Compare, _Alloc>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from /usr/include/c++/7/set:62:0,
                 from ../include/xqilla/ast/XQElementConstructor.hpp:30,
                 from ../src/ast/XQCopy.cpp:30:
/usr/include/c++/7/bits/stl_multiset.h:920:5: note: candidate: template<class _Key, class _Compare, class _Alloc> bool std::operator!=(const std::multiset<_Key, _Compare, _Alloc>&, const std::multiset<_Key, _Compare, _Alloc>&)
     operator!=(const multiset<_Key, _Compare, _Alloc>& __x,
     ^~~~~~~~
/usr/include/c++/7/bits/stl_multiset.h:920:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const std::multiset<_Key, _Compare, _Alloc>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from ../include/xqilla/events/EventGenerator.hpp:26:0,
                 from ../include/xqilla/ast/ASTNode.hpp:29,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
../include/xqilla/framework/ReferenceCounted.hpp:139:13: note: candidate: template<class T> bool operator!=(const RefCountPointer<T1>&, void*)
 inline bool operator!=(const RefCountPointer<T> &a, void *b)
             ^~~~~~~~
../include/xqilla/framework/ReferenceCounted.hpp:139:13: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const RefCountPointer<T1>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
In file included from ../include/xqilla/events/EventGenerator.hpp:26:0,
                 from ../include/xqilla/ast/ASTNode.hpp:29,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
../include/xqilla/framework/ReferenceCounted.hpp:127:13: note: candidate: template<class T1, class T2> bool operator!=(const RefCountPointer<T1>&, const RefCountPointer<T2>&)
 inline bool operator!=(const RefCountPointer<T1> &a, const RefCountPointer<T2> &b)
             ^~~~~~~~
../include/xqilla/framework/ReferenceCounted.hpp:127:13: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/7/vector:69:0,
                 from ../include/xqilla/ast/ASTNode.hpp:25,
                 from ../include/xqilla/ast/ASTNodeImpl.hpp:28,
                 from ../include/xqilla/ast/XQCopy.hpp:25,
                 from ../src/ast/XQCopy.cpp:26:
/usr/include/c++/7/bits/vector.tcc:188:37: note:   'std::_Vector_base<ASTNode*, XQillaAllocator<ASTNode*> >::_Tp_alloc_type {aka XQillaAllocator<ASTNode*>}' is not derived from 'const RefCountPointer<T1>'
            && _M_get_Tp_allocator() != __x._M_get_Tp_allocator())
Makefile:2264: recipe for target 'XQCopy.lo' failed
make[1]: *** [XQCopy.lo] Error 1
make[1]: Leaving directory '/usr/local/src/mapguide/build_oem/dbxml/xqilla/build'
Makefile:4939: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1

build_thin.sh option to support entering the build container

Currently, build_thin.sh autoremoves any running MapGuide/FDO thin build containers upon completion.

To speed up the dev inner loop, especially if a MapGuide/FDO build ended in an error, it should support the ability to preserve such containers so that we can docker exec into these containers ourselves to restart a failed build (after fixing whatever source errors) or to manually run mgserver within.

Add dep checking script to verify installation

This is primarily for verifying the self-containedness of the centos6 release but has general usefulness for all distros

dep_check.sh

#!/bin/sh
NOT_FOUND=$(ldd $1 | grep "not found")
if [ -n "$NOT_FOUND" ]; then
    case "$1" in
        *KingOracleProvider*) # We expect users to bring their own OCI for legal reasons so we expect dep check to fail for this library
            echo "Skipping dependency check on $1: We're expecting you to bring your own OCI"
            ;;
        *)
            echo "$1 has missing dependencies:"
            echo $NOT_FOUND
            exit 1
            ;;
    esac
else
    echo "$1: All dependencies met"
fi
exit 0
export LD_LIBRARY_PATH=/usr/local/mapguideopensource-4.0.0/lib64:/usr/local/mapguideopensource-4.0.0/server/lib64:/usr/local/mapguideopensource-4.0.0/webserverextensions/lib64:/usr/local/fdo-4.2.0/lib64
find /usr/local/mapguideopensource-4.0.0 -type f -name "*.so" | xargs -L1 ./dep_check.sh

Installer clobbers FS permissions

This resets all FS permissions to the current user, breaking httpd's ability to serve content as a result.

To fix: we need to run makeself with the --nochown and --keep-umask flags

Parameterize mapguide/snap_build.sh

FDO SDK tarball copied is hardcoded to "Ubuntu14". Either:

a) lowercase the distro name
b) Write out the scripts as heredoc from within env_setup.sh
c) uppercase the docker folders

Also print out the FDO SDK tarball name to verify we copied the right tarball in

Add custom zlib to centos6 FDO build

The centos6 build of FDO is for all intents and purposes, the "generic" linux build in that we do not build FDO and link against any system libraries.

It turns out zlib-devel is a current requirement for building FDO and the resulting libOWS.so has a reference to libz.so.

Since we've already landed the infrastructure to build additional libs provided the necessary tarballs (eg. MariaDB/PostgreSQL), we should add the tarball for zlib and make sure libOWS.so links against our custom zlib

Selective ignore of build contexts

Currently the docker image build works by copying the selected Dockerfile from the selected distro up to the root, causing the whole repo (and its submodules) to be captured in the docker build context.

When building FDO, we don't care about capturing the MapGuide sources as part of its build context, and similarly vice versa.

We can leverage .dockerignore files to specify this. This should help reduce build startup time due to capturing the build context.

Don't add sources to "develop" image

Since we're using CMake and ccache, we don't necessarily have to add sources to the develop image first as all builds are going to be out-of-source-tree (so nothing in the source dir is tainted) and as long as we make sure to volume mount the source and ccache directories we should get the same build experience as we currently do.

Linux installer enhancements

  • Make server/web tier toggle-able components
  • Make tomcat/java support optional
  • Add MgDevHttpServer as a toggle-able option
  • Add option to download and install extra coord sys grid files
  • Add option to download and install the Sheboygan sample data set
  • Add option to install msttcorefonts for applicable distros
  • Make sure that if different httpd port is specified, make sure that OgcWfsService.config.awd and OgcWmsService.config.awd are updated with the correct port numbers.
  • Add option to auto-load .mgp packages from a given directory (call mgserver loadpackage on these package files before starting the server daemon)

Add SVN checkout fallback

While git mirrors or migration to git is the desired long term solution, the current short term solution of git mirrors of svn repos is not suitable for us, especially for CS-Map where I've found out that git-lfs is a quota-limited service, making having a git clone of CS-Map impractical, which has undesirable side-effects on our MapGuide git clone that submodules it.

So in the meantime, to keep this project going along, add shells scripts to svn checkout/update MapGuide/FDO/Fusion/CS-Map from their canonical SVN repositories.

Installer: Bad ODBC/MySQL/PostgreSQL provider entries being added

The installer script still registers the ODBC/MySQL/PostgreSQL providers under their old autotools-build-based naming scheme.

CMake build of FDO changed these library target names to be consistent with other FDO providers, so this installer script needs to be updated as well to match.

Oracle provider build support

  • Volume mount /sdk
  • Update build process to check for Oracle Instant Client in volume mounted /sdk directory
    • If found, enable King Oracle provider support

Smoke test images

The old vagrant-based linux build system had a "smoke test" image that did the basic sanity check of:

  • Downloading/installing MapGuide
  • Starting httpd and the MapGuide Server daemon
  • Use curl to hit key mapagent requests and make sure they all return HTTP 200

We need equivalent docker images that do the same thing (after the main build)

Ubuntu: Generate dpkg packages

Originally I didn't want to make a series of dpkg packages like we currently do as I wanted a single monolithic executable installer, but on Ubuntu this would mean that I would have to manually express the required apt-get dependencies (by best guess).

Making dpkg packages means this step is done for us for free (via dpkg-shlibdeps)

To maintain the original vision, we'll pack the dpkg files into the final self-extracting executable instead of the raw tarball output.

CentOS 7 MapGuide build failure

This build fails because it can't find certain libpng types. If system libpng doesn't provide these types.

A sample of the build error:

[976/1140] Building CXX object Common/Renderers/CMakeFiles/MgRenderers-3.3.0.dir/AGGImageIO.cpp.o
FAILED: Common/Renderers/CMakeFiles/MgRenderers-3.3.0.dir/AGGImageIO.cpp.o 
/usr/bin/ccache /usr/bin/c++   -DCPPUNIT_MODERN_API -DDWFTK_BUILD_EXPAT -DFULLPROTO -DLINUX -DLINUX_IA32 -DMgRenderers_3_3_0_EXPORTS -DPIC -D__USE_GNU -m64 -O3 -DNDEBUG -fPIC -I/usr/local/src/mapguide/build_oem/gd/freetype/include -I/usr/local/fdo-4.2.0/include -I/usr/local/fdo-4.2.0/include/ExpressionEngine -I/usr/local/src/mapguide/MgDev/Oem/DWFTK/develop/global/src -I/usr/local/src/mapguide/MgDev/Oem/DWFTK/develop/global/src/dwf -I/usr/local/src/mapguide/MgDev/Oem/agg-2.4/include -I/usr/local/src/mapguide/MgDev/Oem/agg-2.4/font_freetype -I/usr/local/src/mapguide/MgDev/Common/Renderers -I/usr/local/src/mapguide/MgDev/Common/Renderers/../MdfModel -I/usr/local/src/mapguide/MgDev/Common/Renderers/../Stylization    -fPIC -pthread -Wno-write-strings -Wno-deprecated -MMD -MT Common/Renderers/CMakeFiles/MgRenderers-3.3.0.dir/AGGImageIO.cpp.o -MF "Common/Renderers/CMakeFiles/MgRenderers-3.3.0.dir/AGGImageIO.cpp.o.d" -o Common/Renderers/CMakeFiles/MgRenderers-3.3.0.dir/AGGImageIO.cpp.o -c /usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp
In file included from /usr/local/src/mapguide/MgDev/Common/Renderers/AGGRenderer.h:33:0,
                 from /usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:22:
/usr/local/src/mapguide/MgDev/Common/Renderers/../Stylization/BIDIConverter.h:28:93: note: #pragma message: !!WARNING!! Attempting to use BIDIConverter.h in a non-UNICODE environment
 #pragma message("!!WARNING!! Attempting to use BIDIConverter.h in a non-UNICODE environment")
                                                                                             ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp: In function 'void png_write_cb(png_structp, png_bytep, png_size_t)':
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:58:53: error: invalid use of incomplete type 'png_struct {aka struct png_struct_def}'
     png_write_context* cxt = (png_write_context*)png->io_ptr;
                                                     ^
In file included from /usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:23:0:
/usr/include/png.h:857:16: error: forward declaration of 'png_struct {aka struct png_struct_def}'
 typedef struct png_struct_def png_struct;
                ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp: In function 'void png_read_cb(png_structp, png_bytep, png_size_t)':
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:78:53: error: invalid use of incomplete type 'png_struct {aka struct png_struct_def}'
     png_write_context* cxt = (png_write_context*)png->io_ptr;
                                                     ^
In file included from /usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:23:0:
/usr/include/png.h:857:16: error: forward declaration of 'png_struct {aka struct png_struct_def}'
 typedef struct png_struct_def png_struct;
                ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp: In function 'int write_png(png_write_context*, unsigned int*, int, int, double, bool)':
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:107:43: error: 'png_infopp_NULL' was not declared in this scope
       png_destroy_write_struct(&png_ptr,  png_infopp_NULL);
                                           ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp: In function 'int read_png(png_write_context*, int&, int&, unsigned char*&)':
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:395:41: error: 'png_infopp_NULL' was not declared in this scope
       png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
                                         ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:407:52: error: 'png_infopp_NULL' was not declared in this scope
       png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
                                                    ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:441:25: error: 'int_p_NULL' was not declared in this scope
        &interlace_type, int_p_NULL, int_p_NULL);
                         ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:473:38: error: 'png_set_gray_1_2_4_to_8' was not declared in this scope
       png_set_gray_1_2_4_to_8(png_ptr);
                                      ^
/usr/local/src/mapguide/MgDev/Common/Renderers/AGGImageIO.cpp:663:49: error: 'png_infopp_NULL' was not declared in this scope
    png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);

Remove CentOS 6 build/images

CentOS 6 is now EOL (as of November 2020). As a result, yum update no longer works and breaks all CentOS 6 image builds.

  • Remove CentOS 6 image
  • Re-base CentOS 7 image to build everything in-tree
  • Re-base generic image to be based on CentOS 7 image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.