나의 가장 오래된 컴퓨터

삼보에서 판매된 인텔 8088 CPU가 탑재된 젬파워 디럭스 XT 모델이다.
물론 정비를 다 해놓아서 깔끔히 잘 돌아간다.

이 모델은 네이버 카페 [도스 박물관] 에도 올려 두었다..
https://cafe.naver.com/olddos

전면이다.. 아주 심플하다.
3.5인치 FDD, 5.25인치 FDD 뿐.. ^^

이건 윗면.. 요즘에 본체의 각종 포트및 구멍 조차 없는 아주 심플한 본체다..

요건 뒷면..
하드대신에 CF카드를 사용하도록 CF2IDE를 장착하고.. CF카드를 달아주었다.
사블 2.0 (CT1350B) 을 꼽아두었고.. 애드립 음원을 아주 잘 지원한다..
그리고 본래 달려있던 허큘리스 카드를 빼버리고.. 8bit 슬롯을 지원하는 VGA카드로 교체하였다.

이제 상판을 벗겨내면..

SBC 보드인데.. 이게 핵심인 인텔의 8088 CPU이다..
물론 인텔의 라이센스를 받아 지멘스에서 만든듯하다.

다음 RTC 밧데리가 방전이 되어서 코인 밧데리를 꼽을수 있게 정비하였다.

Trident VGA카드.. 8비트 슬롯을 지원해서 구매해서 꼽았다.

XTIDE이다. 이건 IDE 장치를 지원하지 않는 XT에 꼽아서 IDE 하드나 CD롬을 사용할수 있다.
물론 여기에 CF2IDE 장치를 꼽아놨다.

사블 2.0 이다.. 아주 레어한.. 놈이다.

실제 작동 동영상입니다.

스트링 offset 파싱 속도 비교

다음과 같은.. 스트링이 있을때..

char *s = "10000001   1201712009430120094781202507512025075";

8,8,8,8,8,8,8 자리로 끊어서 읽고 싶은데..
sscanf는 공백을 무시고 읽어.. 원하는데로 동작되지 않음..
하여 찾다보니.. boost에 offset_separator 라는것이 있음..
테스트 하는 김에 속도 비교를 해봄..

sscanf의 경우.. (대략 88.637946초)

std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
for(int i=0; i<100000000; i++) {
	char *s = "10000001   1201712009430120094781202507512025075";
	unsigned int eid, pid, n1, n2, n3, n4;
	int cnt = sscanf(s, "%8u%8u%8u%8u%8u%8u", &eid, &pid, &n1, &n2, &n3, &n4);
}
std::chrono::system_clock::time_point end = std::chrono::system_clock::now();
std::chrono::duration<double> sec = end - start;
printf("%f(sec)}", sec.count());

boost의 offset_separator (대략 72.378287초)

std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
for(int i=0; i<100000000; i++) {
	std::string s = "10000001   1201712009430120094781202507512025075";

   int offsets[] = {8,8,8,8,8,8};
   boost::offset_separator f(offsets, offsets+6);
   boost::tokenizer<boost::offset_separator> tok(s,f);
   //for(boost::tokenizer<boost::offset_separator>::iterator beg=tok.begin(); beg!=tok.end();++beg){
	 //  std::cout << *beg << "\n";
  // }
   const size_t count = std::distance(tok.begin(), tok.end());
   //std::cout << count << "\n";
   boost::tokenizer<boost::offset_separator>::iterator it1 = tok.begin();
   //std::cout << *it1 << "\n";
   ++it1;
   //std::cout << *it1 << "\n";
   ++it1;
   //std::cout << *it1 << "\n";
   ++it1;
   //std::cout << *it1 << "\n";
   ++it1;
   //std::cout << *it1 << "\n";
   ++it1;
   //std::cout << *it1 << "\n";
}
std::chrono::system_clock::time_point end = std::chrono::system_clock::now();
std::chrono::duration<double> sec = end - start;
printf("%f(sec)}", sec.count());

역시.. 구글링을 해보면 sscanf의 속도가 느리다고 하는데.. 맞는가봄..
일단 boost의 경우 자리수를 지정해서 그 만큼 짤라내는게 아주 잘 되고..
sscanf보다 빠르니.. 요걸 쓰기로 결정..

gmsh를 이용한 Meshing..

자.. 우선 gmsh 의 입력 geometry를 작성..

이건 cube 형태의 geometry..

//test.geo
Point(1) = {1, 0, 0, 1.0};
Point(2) = {1, 1, 0, 1.0};
Point(3) = {0, 1, 0, 1.0};
Point(4) = {0, 0, 1, 1.0};
Point(5) = {1, 0, 1, 1.0};
Point(6) = {1, 1, 1, 1.0};
Point(7) = {0, 1, 1, 1.0};
Point(8) = {0, 0, 0, 1.0};
Line(1) = {7, 6};
Line(2) = {6, 5};
Line(3) = {5, 1};
Line(4) = {1, 8};
Line(5) = {8, 3};
Line(6) = {3, 7};
Line(7) = {7, 4};
Line(8) = {4, 8};
Line(9) = {4, 5};
Line(10) = {2, 1};
Line(11) = {2, 6};
Line(12) = {2, 3};
Line Loop(1) = {6, 1, -11, 12};
Plane Surface(1) = {1};
Line Loop(2) = {11, 2, 3, -10};
Plane Surface(2) = {2};
Line Loop(3) = {2, -9, -7, 1};
Plane Surface(3) = {-3};
Line Loop(4) = {6, 7, 8, 5};
Plane Surface(4) = {-4};
Line Loop(5) = {8, -4, -3, -9};
Plane Surface(5) = {5};
Line Loop(6) = {10, 4, 5, -12};
Plane Surface(6) = {6};
Physical Surface(1) = {4, 3, 2, 6};
Physical Surface(2) = {1};
Physical Surface(3) = {5};
Surface Loop(1) = {6, 2, 1, 4, 3, 5};
Volume(1) = {1};

이제 gmsh 옵션으로.. 2d (-2), 알고리즘은 meshadapt를.. 아웃풋 포맷은 LsDyna의 key 포맷으로..
요소 최소/최대 사이즈를 지정하면..

gmsh.exe test.geo -2 -algo meshadapt -o test.key -format key -clmin 0.01 -clmax 0.05
...
Info    : Meshing 2D...
Info    : Meshing surface 1 (Plane, Frontal Quad)
Info    : Meshing surface 2 (Plane, Frontal Quad)
Info    : Meshing surface 3 (Plane, Frontal Quad)
Info    : Meshing surface 4 (Plane, Frontal Quad)
Info    : Meshing surface 5 (Plane, Frontal Quad)
Info    : Meshing surface 6 (Plane, Frontal Quad)
Info    : Done meshing 2D (0.109375 s)
Info    : 2402 nodes 5048 elements
Info    : Writing 'test.key'...
Info    : Done writing 'test.key'

짜잔~

요렇게 생성이 됨.

자.. 이제 quad 메싱은 맨 위의 입력 geom 파일 끝 줄에 아래를 추가..

Recombine Surface "*";

다음.. 아래와 같이..하고 algorithm은 delquad를 사용하여 매싱을 하면..

gmsh.exe test.geo -2 -algo delquad -o test.key -format key -clmin 0.01 -clmax 0.05
...
Info    : Meshing surface 6 (Plane, Frontal Quad)
Info    : Blossom: 1160 internal 76 closed
Info    : Blossom recombination completed (0 s): 400 quads, 0 triangles, 0 invalid quads, 0 quads with Q < 0.1, avg Q = 1, min Q = 1
Info    : Done meshing 2D (0.09375 s)
Info    : 2402 nodes 2648 elements
Info    : Writing 'test.key'...
Info    : Done writing 'test.key'

오… 꽤 쓸만함..

근데.. 문제는 gmsh의 경우 tria + quad 의 mixed 는 안된다고함..
단 한 surface는 tria를.. 다른 surface는 quad 는 가능함..

무슨 말이냐하면.. 아래와 같이 특정 1번 surface만 recombine을 적용하면..

//Recombine Surface "*";
Recombine Surface{1};

한면만 quad로 meshing이된다..

다음 tetra 는 직접 step 캐드 파일로부터 해봄..
다음과 같은 test.step 파일이 있을때..

아래와 같이 geom 파일을 작성하고..

// stl2msh.geo
Merge "test.step";
Surface Loop(1) = 1;
Volume(1) = 1;
Physical Volume("obj") = {1};

//Mesh.Algorithm3D = 4; //(1=tetgen, 4=netgen, 7=MMG3D, 9=R-tree)
Mesh.Recombine3DAll=1;
Mesh.Smoothing=0;
Mesh.Optimize=1;
Mesh.OptimizeNetgen=1;

gmsh를 아래와 같이 돌리면..

gmsh.exe stl2msh.geo -3 -o test.key -format key -clmax 1.0 -clmin 0.1

짜잔.. 잘 된것 같은데.. 문제는 형상이 몇개 빠진듯.. -_-;;
암튼.. 메시 사이즈를 0.4 정도로 주고 다시 해보면..

잘되는듯하다..

gmsh의 경우 hexa가 안되는게 제일 문제..

종합해보면..

1. quad, tria 지원 (mixed 미지원)
2. tetra 지원
3. hexa 미지원

아래는 각 메시 라이브러리별 지원 항목..

크롬 확장 프로그램 설치된 폴더

%LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions\

가끔 크롬이 설치된 확장 프로그램으로 인하여..
부러우저 띄울때 “확장이 다운되었습니다?” 라는 문구를 내뱉으면서..
안되는 경우가 있는데.. 깔끔하게 저 폴더내의 모든 폴더들을 다 지워준다..
확장 프로그램이야 다시 깔면되고..

ReactPhysics3D 의 광선 교차 테스트

ReactPhysics3D 의 광선 교차 테스트..

#include "reactphysics3d.h"

#include <iostream>
#include <stdexcept>
#include <vector>
#include <map>
#include <sstream>
#include <iomanip>
#include <memory>
#include <algorithm>
#include <set>
#include <string>
#include <fstream>

#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/string_cast.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/transform.hpp> 
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/normal.hpp>


// https://github.com/DanielChappuis/reactphysics3d/blob/master/test/tests/collision/TestAABB.h
using namespace reactphysics3d;


class DynamicTreeRaycastCallback : public DynamicAABBTreeRaycastCallback {

    public:

        std::vector<int> mHitNodes;

        // Called when the AABB of a leaf node is hit by a ray
        virtual decimal raycastBroadPhaseShape(int32 nodeId, const Ray& ray) override {
			printf("--hit-- %d\n", nodeId);
            mHitNodes.push_back(nodeId);
            return 1.0;
        }

        void reset() {
            mHitNodes.clear();
        }

        bool isHit(int nodeId) const {
            return std::find(mHitNodes.begin(), mHitNodes.end(), nodeId) != mHitNodes.end();
        }
};


int main(void)
{
	DynamicTreeRaycastCallback mRaycastCallback;

	DynamicAABBTree tree(MemoryManager::getBaseAllocator());

	AABB aabb;

	std::vector<glm::vec3> vertices;

	int solverId = 1;
	vertices.push_back(glm::vec3(0, -2.5, 0));
	vertices.push_back(glm::vec3(-2.5, 2.5, 0));
	vertices.push_back(glm::vec3(2.5, 2.5, 0));
	aabb = AABB::createAABBForTriangle((Vector3*)&vertices[0]);
	int objectId = tree.addObject(aabb, &solverId);
	printf("%d\n", objectId);

	solverId = 2;
	glm::vec3 points2[] = {
		glm::vec3(0, -2.5, 2), glm::vec3(-2.5, 2.5, 2), glm::vec3(2.5, 2.5, 2)
	};
	aabb = AABB::createAABBForTriangle((Vector3*)points2);
	objectId = tree.addObject(aabb, &solverId);
	printf("%d\n", objectId);
	
	solverId = 3;
	vertices.clear();
	vertices.push_back(glm::vec3(0, -2.5, 4));
	vertices.push_back(glm::vec3(-2.5, 2.5, 4));
	vertices.push_back(glm::vec3(2.5, 2.5, 4));
	aabb = AABB::createAABBForTriangle((Vector3*)&vertices[0]);
	objectId = tree.addObject(aabb, &solverId);
	printf("%d\n", objectId);


	printf("Press any key to ray hit test..\n"); fflush(stdout);
	getchar();

	Ray ray(Vector3(0, 0, 10), Vector3(0, 0, -10));

	// hit test 
	printf("Hit test..\n");
	mRaycastCallback.reset();
	tree.raycast(ray, mRaycastCallback);

	// hit test after remove
	printf("Hit test after remove..\n");
	tree.removeObject(1);
	mRaycastCallback.reset();
	tree.raycast(ray, mRaycastCallback);

#if 0
	printf("%f\n", tree.getMin().x);
	printf("%f\n", tree.getMin().y);
	printf("%f\n", tree.getMin().z);
	printf("%f\n", tree.getMax().x);
	printf("%f\n", tree.getMax().y);
	printf("%f\n", tree.getMax().z);
#endif

#if 0
	printf("%d\n", aabb.testRayIntersect(ray));
#endif

	return 0;
}

determining if a point is inside a polyhedron

#include <vector>
#include <cassert>
#include <iostream>
#include <cmath>

struct Vector {
  double x, y, z;

  Vector operator-(Vector p) const {
    return Vector{x - p.x, y - p.y, z - p.z};
  }

  Vector cross(Vector p) const {
    return Vector{
      y * p.z - p.y * z,
      z * p.x - p.z * x,
      x * p.y - p.x * y
    };
  }

  double dot(Vector p) const {
    return x * p.x + y * p.y + z * p.z;
  }

  double norm() const {
    return std::sqrt(x*x + y*y + z*z);
  }
};

using Point = Vector;

struct Face {
  std::vector<Point> v;

  Vector normal() const {
    assert(v.size() > 2);
    Vector dir1 = v[1] - v[0];
    Vector dir2 = v[2] - v[0];
    Vector n  = dir1.cross(dir2);
    double d = n.norm();
    return Vector{n.x / d, n.y / d, n.z / d};
  }
};

bool isInConvexPoly(Point const& p, std::vector<Face> const& fs) {
  for (Face const& f : fs) {
    Vector p2f = f.v[0] - p;         // f.v[0] is an arbitrary point on f
    double d = p2f.dot(f.normal());
    d /= p2f.norm();                 // for numeric stability

    constexpr double bound = -1e-15; // use 1e15 to exclude boundaries
    if (d < bound)
      return false;
  }

  return true;
}

int main(int argc, char* argv[]) {
  Point p;
  p.x = 0.5;
  p.y = 0.5;
  p.z = 0.5;
  /*
  p.x = 2;
  p.y = 2;
  p.z = 2;
  */

  std::vector<Face> cube{ // faces with 4 points, last point is ignored
    Face{{Point{0,0,0}, Point{1,0,0}, Point{1,0,1}, Point{0,0,1}}}, // front
    Face{{Point{0,1,0}, Point{0,1,1}, Point{1,1,1}, Point{1,1,0}}}, // back
    Face{{Point{0,0,0}, Point{0,0,1}, Point{0,1,1}, Point{0,1,0}}}, // left
    Face{{Point{1,0,0}, Point{1,1,0}, Point{1,1,1}, Point{1,0,1}}}, // right
    Face{{Point{0,0,1}, Point{1,0,1}, Point{1,1,1}, Point{0,1,1}}}, // top
    Face{{Point{0,0,0}, Point{0,1,0}, Point{1,1,0}, Point{1,0,0}}}, // bottom
  };

  std::cout << (isInConvexPoly(p, cube) ? "inside" : "outside") << std::endl;

  return 0;
}

Docker Engine 설치

참고: https://docs.docker.com/install/linux/docker-ce/centos/

요즘 핫한.. (요즘 이라기엔.. 2013년도에 처음 나온 기술이라..) CentOS 7 에서 docker engine 을 설치해봄. 아래는 sudo 를 통하지않고 root 계정에서 직접 설치.

$ uname -a
Linux xxx 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

CentOS를 최신으로 업데이트함.

$ yum update

기존 docker engine이 설치되어 있을경우 최신 버전의 docker engine을 설치하기위해 삭제함.

$ yum remove docker docker-client docker-client-latest docker-common docker-latest 
 docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine

docker engine을 설치하는데 필요한 종속 프로그램 설치. 이미 최신 버전이 설치되어 있을수 있음

$ yum install -y yum-utils device-mapper-persistent-data lvm2

docker engine 공식 repository 추가

$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

설치가능한 docker engine 버전 확인.. ce는 Community Edition 인데 무료버전임.

$ yum list docker-ce --showduplicates | sort -r
....
docker-ce.x86_64            3:19.03.2-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.1-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.0-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.5-3.el7                     docker-ce-stable
.....
docker-ce.x86_64            18.06.2.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.1.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.0.ce-3.el7                    docker-ce-stable
....
....
 * base: mirror.kakao.com
Available Packages

docker engine 최신 버전 설치

$ yum install docker-ce
....
---> Package container-selinux.noarch 2:2.107-1.el7_6 will be installed
---> Package containerd.io.x86_64 0:1.2.6-3.3.el7 will be installed
---> Package docker-ce-cli.x86_64 1:19.03.2-3.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

==================================
 Package                         Arch                 Version                          Repository                      Size
==================================
Installing:
 docker-ce                       x86_64               3:19.03.2-3.el7                  docker-ce-stable                24 M
Installing for dependencies:
 container-selinux               noarch               2:2.107-1.el7_6                  extras                          39 k
 containerd.io                   x86_64               1.2.6-3.3.el7                    docker-ce-stable                26 M
 docker-ce-cli                   x86_64               1:19.03.2-3.el7                  docker-ce-stable                39 M

Transaction Summary
==================================
Install  1 Package (+3 Dependent packages)

Total download size: 90 M
Installed size: 368 M
Is this ok [y/d/N]: 

y눌러서 설치… 조금 기다리면 아래와 같이 설치가 완료됨.

Running transaction
  Installing : 2:container-selinux-2.107-1.el7_6.noarch  1/4 
  Installing : containerd.io-1.2.6-3.3.el7.x86_64        2/4 
  Installing : 1:docker-ce-cli-19.03.2-3.el7.x86_64      3/4 
  Installing : 3:docker-ce-19.03.2-3.el7.x86_64          4/4 
  Verifying  : 3:docker-ce-19.03.2-3.el7.x86_64          1/4 
  Verifying  : containerd.io-1.2.6-3.3.el7.x86_64        2/4 
  Verifying  : 2:container-selinux-2.107-1.el7_6.noarch  3/4 
  Verifying  : 1:docker-ce-cli-19.03.2-3.el7.x86_64      4/4 

Installed:
  docker-ce.x86_64 3:19.03.2-3.el7                                                                                          

Dependency Installed:
  container-selinux.noarch 2:2.107-1.el7_6   containerd.io.x86_64 0:1.2.6-3.3.el7   docker-ce-cli.x86_64 1:19.03.2-3.el7  

Complete!

참고로 특정 버전의 docker engine을 설치하고자 한다면 아래와 같이..

$ yum install docker-ce-18.09.0

자 이제.. docker engine 서비스를 실행하고..

$ systemctl start docker

다음 docker version 을 확인함.

$ docker version
Client: Docker Engine - Community
 Version:           19.03.2
 API version:       1.40
 Go version:        go1.12.8
 Git commit:        6a30dfc
 Built:             Thu Aug 29 05:28:55 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.2
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.8
  Git commit:       6a30dfc
  Built:            Thu Aug 29 05:27:34 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.6
  GitCommit:        894b81a4b802e4eb2a91d1ce216b8817763c29fb
 runc:
  Version:          1.0.0-rc8
  GitCommit:        425e105d5a03fabd737a126ad93d62a9eeede87f
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

“hello world” docker 이미지 설치

$ docker run hello-world
Unable to find image 'hello-world:latest' locally

latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.
....
For more examples and ideas, visit:
 https://docs.docker.com/get-started/

설치된 이미지 확인..

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        8 months ago        1.84kB

CentOS 부팅시 docker engine 서비스가 자동으로 실행되게 하면 좋음.

$ systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

이로써 CentOS 7 에서 docker engine을 설치완료. 굿!!

참고로 난 docker engine 을 root 계정에서 설치를 했는데..
일반 유저 계정에서 실행하려니.. 아래와 같이 에러가 발생..

$ docker version
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/version: dial unix /var/run/docker.sock: connect: permission denied

이런 경우 아래와 같이 해결. 만약 유저 계정 id가 ihmin 이라면..

$ usermod -a -G docker ihmin
$ service docker restart

다음 완전히 로그아웃한다음 다시 로그인하면 잘됨..

msys2 – gcc/g++ 업데이트 및 설치

msys2 를 처음 설치하고 아래와 같이 기본 gcc/g++ 컴파일러와 필요한 유용한 라이브러리들을 설치한다.

pacman -Syu

pacman -S base-devel
pacman -S gcc
pacman -S development
pacman -S compression

pacman -S mingw-w64-i686-toolchain mingw-w64-x86_64-toolchain

pacman -Sy git
pacman -Sy cmake

아래와 같이 설치된 컴파일러를 확인한다.

$ pacman -Ss gcc
mingw32/mingw-w64-i686-gcc 9.1.0-3 (mingw-w64-i686-toolchain)
GNU Compiler Collection (C,C++,OpenMP) for MinGW-w64
mingw32/mingw-w64-i686-gcc-ada 9.1.0-3 (mingw-w64-i686-toolchain)
GNU Compiler Collection (Ada) for MinGW-w64
...
mingw64/mingw-w64-x86_64-gcc 9.1.0-3 (mingw-w64-x86_64-toolchain) [설치함]
GNU Compiler Collection (C,C++,OpenMP) for MinGW-w64
mingw64/mingw-w64-x86_64-gcc-ada 9.1.0-3 (mingw-w64-x86_64-toolchain) [설치함]
GNU Compiler Collection (Ada) for MinGW-w64
...
msys/mingw-w64-cross-gcc 9.1.0-1 (mingw-w64-cross-toolchain mingw-w64-cross)
Cross GCC for the MinGW-w64

내가 자주사용하는 개발 패키지들도 설치한다.

pacman -Sy mingw-w64-i686-fontconfig mingw-w64-x86_64-fontconfig
pacman -Sy mingw-w64-i686-freeimage mingw-w64-x86_64-freeimage
pacman -Sy mingw-w64-i686-gl2ps mingw-w64-x86_64-gl2ps
pacman -Sy mingw-w64-i686-freetype mingw-w64-x86_64-freetype
pacman -Sy mingw-w64-i686-libpng mingw-w64-x86_64-libpng
pacman -Sy mingw-w64-i686-libtiff mingw-w64-x86_64-libtiff

pacman -Sy mingw-w64-i686-tcl mingw-w64-x86_64-tcl
pacman -Sy mingw-w64-i686-tk mingw-w64-x86_64-tk
pacman -Sy mingw-w64-i686-python2 mingw-w64-x86_64-python2
pacman -Sy mingw-w64-i686-python3 mingw-w64-x86_64-python3

pacman -Sy mingw-w64-i686-qt-creator mingw-w64-x86_64-qt-creator
pacman -Sy mingw-w64-i686-qtbinpatcher mingw-w64-x86_64-qtbinpatcher
# dynamic 버전이 필요하면 아래를 설치..
pacman -Sy mingw-w64-i686-qt5 mingw-w64-x86_64-qt5
# static 버전이 필요하면 아래를 설치..
pacman -Sy mingw-w64-i686-qt5-static mingw-w64-x86_64-qt5-static

pacman -Sy mingw-w64-i686-mpfr mingw-w64-x86_64-mpfr
pacman -Sy mingw-w64-i686-gmp mingw-w64-x86_64-gmp

pacman -Sy mingw-w64-i686-SDL2 mingw-w64-x86_64-SDL2
pacman -Sy mingw-w64-i686-allegro mingw-w64-x86_64-allegro

pacman -Sy mingw-w64-i686-boost mingw-w64-x86_64-boost
pacman -Sy mingw-w64-i686-cgal mingw-w64-x86_64-cgal
pacman -Sy mingw-w64-i686-freeglut mingw-w64-x86_64-freeglut
pacman -Sy mingw-w64-i686-glm mingw-w64-x86_64-glm
pacman -Sy mingw-w64-i686-glfw mingw-w64-x86_64-glfw
pacman -Sy mingw-w64-i686-oce mingw-w64-x86_64-oce
pacman -Sy mingw-w64-i686-glew mingw-w64-x86_64-glew

pacman -Sy mingw-w64-i686-ffmpeg mingw-w64-x86_64-ffmpeg

pacman -Sy mingw-w64-i686-zlib mingw-w64-x86_64-zlib
pacman -Sy mingw-w64-i686-readline mingw-w64-x86_64-readline
pacman -Sy mingw-w64-i686-pdcurses mingw-w64-x86_64-pdcurses

pacman -Sy mingw-w64-i686-libmariadbclient mingw-w64-x86_64-libmariadbclient

참고로 저장소에서 제공하는 패키지는 무엇이 잇는지는 아래의 싸이트에서 검색..
https://packages.msys2.org/search?t=binpkg

만약 옛 버전을 설치 해야 하는 경우는 pacman 은 버전을 지정하여 설치를 할 수 없다.
아래의 페이지에서 옛 버전을 받아서..
http://repo.msys2.org/mingw/x86_64/
다음과 같이 설치한다.

pacman -U mingw-w64-x86_64-qt5-5.10.0-1-any.pkg.tar.xz

이미 상위 버전이 설치되어 있는 경우 자동으로 다운그레이드를 함.. 굿!!

참고로 설치된 패키지의 정보들은 아래의 폴더에 위치해있음.

/var/lib/pacman/local

또.. 다운 받아진 원본 패키지들은 아래에 있음.

/var/cache/pacman/pkg

msys2 개발 환경으로 인해서 개발이 편해지고 개발 비용도 줄일수있긴하지만..
편해진 만큼 개발자들이 게을러지지 않을까.. 생각이든다. -_-;;