레이블이 gcc인 게시물을 표시합니다. 모든 게시물 표시
레이블이 gcc인 게시물을 표시합니다. 모든 게시물 표시

pip install gcc error

# pip 설치 중 다음과 같은 에러가 발생했다.
pip install cryptography
... 
/opt/homebrew/bin/gcc-13 -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -I/opt/homebrew/opt/zlib -I/opt/homebrew/opt/zlib -DFFI_BUILDING=1 -DUSE__THREAD -DHAVE_SYNC_SYNCHRONIZE -I/Library/Developer/CommandLineTools/SDKs/MacOSX14.sdk/usr/include/ffi -I/Users/ysoftman/.pyenv/versions/3.12.0/include/python3.12 -c src/c/_cffi_backend.c -o build/temp.macosx-14.1-arm64-cpython-312/src/c/_cffi_backend.o -iwithsysroot/usr/include/ffi
...
gcc-13: error: unrecognized command-line option '-iwithsysroot/usr/include/ffi'

# 컴파일러를 clang 으로 변경하면 된다.
CC=clang pip install cryptography

# 참고로 python 환경을 보니 CC 가 gcc 로 설정되어 있었다.
# 예전 pyenv 로 python 설치시 clang 에 문제가 있어 gcc 로 변경해서 설치했던게 문제였다.
python -m sysconfig | rg 'CC = '
40:     CC = "/opt/homebrew/bin/gcc-13"
647:    LINKCC = "/opt/homebrew/bin/gcc-13"

replace intel app to apple app

mac intel -> M1(apple silicon)으로 마이그레이션 후
intel kind의 프로세서들은 rosetta2 에뮬레이터가 변환해서 apple silicon 에서도 동작한다.
하지만 변환과정으로 비효율적이다.
activity Monitor.app > kind 로 intel 프로세스를 확인할 수 있다.

아직 apple silicon(arm64) 바이너리가 많이 없지만 있다면 대체해보자.

# file 명령으로 바이너리가 어떤 환경에서 실행 되는지 알 수 있다.
file /bin/sh

# bin/zsh 는 arm64, x86_64 둘다 지원하는 universal binary 다.
file /bin/zsh

# intel 용으로 zsh 를 실행하기
arch -x86_64 /bin/zsh

# arm64 용으로 zsh 를 실행하기
arch -arm64 /bin/zsh

# 그런데 /usr/local/bin/zsh 는 x86_64 바이너리다.
file /usr/local/bin/zsh

# 아래 사이트에서 brew 설치 스크립트를 실행하면
# apple silicon 용(/opt/Homebrew/bin 에 설치) homebrew 로 설치 된다.
# 설후 설정을 보면 HOMEBREW_PREFIX: /opt/Homebrew 로 되어 있다.
brew config

# apple silicon 용 brew 등의 바이너리를 우선 실행할 수 있도록 한다.
export PATH=/opt/Homebrew/bin:$PATH

# 이제 쉘을 재시작하고 zsh 설치해 보자.
# bash 도 arm64 으로 설치하자.
brew install zsh bash

# 새로 설치된 zsh 는 arm64 버전이다.
which zsh
/opt/Homebrew/bin/zsh
file /opt/Homebrew/bin/zsh
/opt/Homebrew/bin/zsh: Mach-O 64-bit executable arm64

# 이제 brew 로 arm64 버전의 프로그램을 설치 할 수 있다.
brew install vim fzf git lsd wegt dog 등등

# 참고로 x86_64 용(/usr/local/bin 에 설치) brew 를 사용하려면
# x86_64 용(/usr/local/bin 에 설치) homebrew 설치하고
arch --x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/
install/HEAD/install.sh)"

# 다음과 같이 사용한다.
arch --x86_64 /usr/local/Homebrew/bin/brew install {패키지이름}

#####

arm64 zellij (/opt/Homebrew/bin/zellij) 0.39.1 을 사용하면 status-bar 등의 코드에서 에러가 발생한다.
SSE2 명령셋등 intel cpu 종속적인 코드가 있어 보인다.

# 당분간은 x86_64 zellij 사용하기 위해 arm64 로 설치된 zellij 는 제거한다.
brew uninstall zellij

# 몇주 후 0.39.2 버전이 나왔고 설치하니 해결되었다.
arch -arm64 brew install zellij

# 버전확인
/opt/homebrew/bin/zellij --version
zellij 0.39.2

# arm64 바이너리 확인
file /opt/homebrew/bin/zellij
/opt/homebrew/bin/zellij: Mach-O 64-bit executable arm64

#####

# 마이그레이션 후 파이썬 설치시
brew install python

# 또는 uname -m 이 x86_64 라면
arch -arm64 brew install python

# 다음과 같은 에러가 발생했다.
Error: An exception occurred within a child process:
  FormulaUnavailableError: No available formula with the name "/opt/Homebrew/Library/Taps/homebrew/homebrew-core/Aliases/python".

# 확인해보니 다음 경로 자체가 없었다.
/opt/Homebrew/Library/Taps/homebrew/homebrew-core

# homebrew/core 를 다시 구성후 설치하면 된다.
# 구성에 시간이 좀 걸린다.
brew tap homebrew/core

# 만약 /opt/Homebrew/Library/Taps/homebrew/homebrew-core 경로가 있는 상태에서도 안되면 삭제후 시도해보자.
rm -rf /opt/Homebrew/Library/Taps/homebrew/homebrew-core

#####

# 마이그레이션 후 
# pyenv 로 python 설치하면 다음과 같은 이유로 실패 한다.
pyenv install -v 3.12
ld: warning: duplicate -rpath '/Users/ysoftman/.pyenv/versions/3.12.0/lib' ignored
ld: warning: duplicate -rpath '/opt/homebrew/lib' ignored
ld: warning: search path '/Users/ysoftman/.pyenv/versions/3.12.0/lib' not found
ld: warning: search path '/Users/ysoftman/.pyenv/versions/3.12.0/lib' not found
ld: Undefined symbols:
ld: Undefined symbols:
  _libintl_bindtextdomain, referenced from:
      __locale_bindtextdomain in _localemodule.o
      __locale_bindtextdomain in _localemodule.o
  _libintl_dcgettext, referenced from:
      __locale_dcgettext in _localemodule.o
  _libintl_dgettext, referenced from:
      __locale_dgettext in _localemodule.o
  _libintl_gettext, referenced from:
      __locale_gettext in _localemodule.o
  _libintl_setlocale, referenced from:
      __locale_setlocale in _localemodule.o
      __locale_setlocale in _localemodule.o
      __locale_localeconv in _localemodule.o
      __locale_localeconv in _localemodule.o
      __locale_localeconv in _localemodule.o
      __locale_localeconv in _localemodule.o
  _libintl_textdomain, referenced from:
      __locale_textdomain in _localemodule.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Programs/_freeze_module] Error 1
make: *** Waiting for unfinished jobs....

# libintl.a 라이브러리에 있는 심볼들이 보인다.
# /opt/homebrew/lib/libintl.a 를 참조하지 않는게 문제 같다.
nm /opt/homebrew/lib/libintl.a | rg  "_libintl_(bindtextdomain|dcgettext|dgettext|gettext|setlocale)$"

# 구글링으로 여러 방법들을 시도...
# gettext library 를 찾지 못한다고 해서 다시 설치했지만 안된다.
brew reinstall gettext

# arm64 library 을 찾도록 LDFLAG 를 설정해도 안된다.
export LDFLAGS="-L/opt/homebrew/lib"
export CPPFLAGS="-I/opt/homebrew/include"

# 기존 x86_64 라이브러를 우선 참조하게 되는것 같아 해당 path 를 강제 삭제해도 안된다.
rm -rf /usr/local/Cellar/{gettext,readline}

# arm64 용으로 make gcc 등 컴파일러 최신으로 설치해도 안된다.
arch -arm64 brew install cmake make gcc

# 이번에는 실제 파이썬 소스를 다운받아 다음과 같이 빌드하면 잘된다.
# 아래처럼 configure 로 Makefile 이 생성하면 CC=gcc CXX=g++ 로 설정되어 있다.
git clone https://github.com/python/cpython
cd cpython; ./configure && make -j10

# pyenv 빌드시 clang (Apple clang version 15.0.0) 대신 
# 컴파일러를 gcc(없다면 설치 brew install gcc)로 변경하니 된다.
CC=/opt/homebrew/bin/gcc-13 pyenv install -v 3.12

# 몇달 후 zellij, /opt/homebrew 패키지들을 arm64 로 다시 설치등의 변화가 있었는데,
# 별도 CC 설정없이 clang (Apple clang version 15.0.0) 로도 됐다.
pyenv install -v 3.12

g++ warning missing initializer for member

다음과 같이 time struct(tm) 생성시 초기화를 하지 않은 상태의 c++코드가 있을때

#include <iostream>
#include <sys/time.h>
int main() {
    struct tm aaa{};
    std::cout << aaa.tm_sec << std::endl;
    return 0;
}

다음과 같이 빌드 하면 괜찮은데,
g++ -std=c++11 ysoftman.cpp
또는
g++ -std=c++11 -Wall ysoftman.cpp

다음과 같이 -Wextra 옵션을 주면�warning 이 발생한다.
g++ -std=c++11 -Wextra ysoftman.cpp

ysoftman.cpp:5:16: warning: missing initializer for member ‘tm::tm_sec’ [-Wmissing-field-initializers]
  struct tm aaa{};
                ^
ysoftman.cpp:5:16: warning: missing initializer for member ‘tm::tm_min’ [-Wmissing-field-initializers]
ysoftman.cpp:5:16: warning: missing initializer for member ‘tm::tm_hour’ [-Wmissing-field-initializers]
...

참고로 -Wextra 는 -Wall 에 포함되지 않는 warning 에 대한것으로
위와 같이 초기화 누락이나 포인터를 정수형과 비교할때 발생하는 경고(comparison between pointer and integer) 를 활성화 한다.
그리고 -W 옵션 대신 -Wextra 를 사용하라고 한다.
g++ -v --help | grep Wextra
-W switch is deprecated; use -Wextra instead

[해결방법1]
-Wextra 를 사용하지 않기
찾아보니 사실 기본 0값으로 초기화되는데 gcc 는 너무 과도하게 warning 을 발생한다는 의견도 있다.

[해결방법2]
다음과 같이 모든 멤버를 초기화한다. (struct 내의 생성자()를 두고 초기화하면 편한데, tm 은 standard library라 그럴 수 없다.)
    struct tm aaa{
    .tm_sec=0,
    .tm_min=0,
    .tm_hour=0,
    .tm_mday=0,
    .tm_mon=0,
    .tm_year=0,
    .tm_wday=0,
    .tm_yday=0,
    .tm_isdst=0,
    .tm_gmtoff=0,
    .tm_zone=NULL};

[해결방법3]
경고 메시지대로 -Wno-missing-field-initializers 를 추가해서 초기화 경고만 제외시킨다.
g++ -std=c++11 -Wextra -Wno-missing-field-initializers ysoftman.cpp

make -j option in docker container

# 6cores(12threads), 32GB RAM 맥북에서
# 도커 컨테이너를 띄우고 c++ make 속도를 높이기 위해
# make -j 4 -> make -j 8 로 같이 병렬 컴파일 잡 개수를 높였다.
# 그런데 다음과 같은 에러가 발생한다.
g++: internal compiler error: Killed (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
make[1]: *** [util/utf8_string_bounder.o] Error 4
make[1]: *** Waiting for unfinished jobs....

# 위와 같은 에러는 빌드시 메모리 부족으로 스왑 파일을 사용하는데
# 스왑파일도 1GB 로 적어 컴파일을 끝낼 수 없어 발생한 에러다.
# 컨테이너의 메모리가 2GB 로 설정되어 있었다.
# 컨테이너에서 사용할 cpu, memory 를 늘려야 한다.(스왑파일도 늘리 수 있다.)
# 도커 setting -> resources -> advanced 에서 변경한다.


# 이제 컨테이너를 run 하고
docker run --name ysoftman_centos -dit ysoftman/centos

# 컨테이너에 접속해서
docker exec -u root -e COLUMNS=$(tput cols) -e LINES=$(tput lines) -it ysoftman_centos /bin/bash

# cpu, memroy 를 확인해 보면
# cpu 6, memory 8G 로 설정된것을 볼 수 있다.
cat /proc/cpuinfo  | \grep processor
processor : 0
processor : 1
processor : 2
processor : 3
processor : 4
processor : 5

free -h
              total        used        free      shared  buff/cache   available
Mem:           7.8G        326M        7.1G        868K        384M        7.2G
Swap:          1.0G          0B        1.0G

# 이제 make -j 8 을 수행하면 잘 된다.
time make -j8

# 컨테이너 리소스 증가에 따라 make 빌드 소요 시간도 줄지만
# 같은 리소스상태에서는 -j 값이 어느정도 부터는 시간이 더 이상 줄지 않는다.
# 2CPUs, 2GB mem, make -j 8 --> (2:12초)
# 6CPUs, 8GB mem, make -j 8 --> (1:42초)
# 10CPUs, 16GB mem, make -j 10 --> (1:39초)
# 10CPUs, 16GB mem, make -j 12 --> (1:39초)

# 참고
# make -j 옵션 사용시 값을 명시하지 않으면 무한대로 설정된다.
make --help | \grep  '\-j'
  -j [N], --jobs[=N]          Allow N jobs at once; infinite jobs with no arg.

# 무한대로 하면 모든 cpp 파일이 동시 컴파일 되고 더 많은 메모리를 필요로 해서
# 에러가 또 발생할 수 있어 memory 리소스에 따른 적절한 -j 수치를 정해야 한다.

mac clang

# 맥은 gcc, g++ 등은 LLVM 기반의 clang 을 사용한다.
# c/c++ 컴파일러들은 모두 clang 을 사용하고 있다.
# 단순 링크를 보면 다음과 같다.
which -a gcc g++ clang llvm-g++ llvm-gcc cc c++ | grep -v "alias" | xargs ls -ahl
lrwxr-xr-x  1 root  wheel     7B 11 26 10:40 /usr/bin/c++ -> clang++
lrwxr-xr-x  1 root  wheel     5B 11 26 10:40 /usr/bin/cc -> clang
-rwxr-xr-x  1 root  wheel    18K  1 16 10:21 /usr/bin/clang
-rwxr-xr-x  1 root  wheel    18K  1 16 10:21 /usr/bin/g++
-rwxr-xr-x  1 root  wheel    18K  1 16 10:21 /usr/bin/gcc
lrwxr-xr-x  1 root  wheel     7B 11 26 10:40 /usr/bin/llvm-g++ -> clang++
lrwxr-xr-x  1 root  wheel     5B 11 26 10:40 /usr/bin/llvm-gcc -> clang

# 사용하는 프로그램과 라이브러리를 보면 gcc, g++ 도 clang 을 참조만 하고 있다.
gcc --print-search-dirs
install: /Library/Developer/CommandLineTools/usr/lib/llvm-gcc/4.2.1
programs: =/Library/Developer/CommandLineTools/usr/bin
libraries: =/Library/Developer/CommandLineTools/usr/lib/clang/10.0.0:/Library/Developer/CommandLineTools/usr/lib/llvm-gcc/4.2.1
llvm-gcc --print-search-dirs
programs: =/Library/Developer/CommandLineTools/usr/bin
libraries: =/Library/Developer/CommandLineTools/usr/lib/clang/10.0.0

zsh nocorrect

# zsh 에서 gcc 는 nocorrect 로 alias 되어 있다고 나오면서 위치가 안나온다.
which gcc
gcc: aliased to nocorrect gcc

# -a 으로 모든 실행 가능한 인스턴스 리스트를 출력하면 보이긴 한다.
which -a gcc
gcc: aliased to nocorrect gcc
/usr/bin/gcc

# zsh 에서 gcc 다음과 같이 alias 하고 있다.
gcc='nocorrect gcc'

# zsh 은 기본적으로 오타에 대해 다음처럼 교정할 수 있다.
cleary
zsh: correct cleary to clear [nyae]?

# nocorrect 를 사용하면 명령어 오타 교정을 물어보지 않고 있는 그대로 수행한다.
# nocorrect cleary
zsh: command not found: cleary

# nocorrect 는 zsh 에서 명령어 앞에 선언하는 수정자로
# gcc 글자에 대해선 스펠 교정을 하지 않게 한다.
http://bolyai.cs.elte.hu/zsh-manual/zsh_5.html#SEC19
which nocorrect
nocorrect: shell reserved word

ycmd server SHUT DOWN 에러 해결하기

# youcompleteme(ycm) 플러그인을 설치 후 vim 시작시 다음과 같은 에러가 발생한다.
# 참고로 ycm 은 클라이언트이고 third_party/ycmd 에 서버 소스가 있다.
The ycmd server SHUT DOWN (restart with ':YcmRestartServer')

# 다음과 같이 인스톨을 다시 해줘야 한다.
cd ~/.vim/plugged/youcompleteme
git submodule update --init --recursive
./install.py --all --verbose

# 만약 ./install.py 수행시 c++11 지원 안된다는 에러가 발생하는 경우
CMake Error at CMakeLists.txt:247 (message):
  Your C++ compiler does NOT fully support C++11.

# gcc 는 있지만 g++ 이 설치되어 있지 않아서다.
# 다음과 같이 g++ 를 설치 후 ./install.py
sudo yum install gcc-c++

# 만약 다음과 같은 에러가 발생하는 경우
fatal error: pyconfig.h:

# python-devel 을 설치 후 ./install.py
sudo yum install python-devel

#####

# M1(arm64) 맥북 환경에서 다음과 같이 빌드시 clang 에러가 발생했다.
./install.py --all --verbose

# 원인은 pyenv 로 설치한 python3.12(~/.pyenv/shims/python)가
# 설치시 다음과 같이 gcc 로 빌드해서였다.
CC=/opt/homebrew/bin/gcc-13 pyenv install -v 3.12

# clang 으로 다시 빌드해 설치 후
pyenv install -v 3.12

# ycmd 를 다시 빌드하면 된다.
./install.py --all --verbose

python gcc 로 빌드

# gcc 가 버전업 된경우 python 을 해당 gcc 로 빌드해야 하는 경우가 생긴다.
# centos6 에서 gcc 4.4.x -> 4.9.x 로 업그레이 후 4.9.x 로 python 빌드
# 현재 gcc 버전 확인
gcc --version

# python 소스 다운 받기
wget https://www.python.org/ftp/python/2.7.13/Python-2.7.13.tar.xz
tar xvf Python-2.7.13.tar.xz
cd Python-2.7.13
./configure --prefix=/usr/local/python-2.7.13
make -j4
sudo make install

# 환경변수 경로에 추가
vi ~/.bashrc
export PATH=/usr/local/python-2.7.13/bin:$PATH:

# 참고
# centos 등에서 python3 이 없는 경우가 많을때 설치하자.(위 내용과 같음)
wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
cd Python-3.8.1
./configure --prefix=/usr/local/python3 --enable-optimizations
make -j4
sudo make install
vi ~/.bashrc
export PATH=/usr/local/python3/bin:$PATH:

centos6 gcc 4.8 이상 설치

centos 6.x 의 기본 gcc 버전은 4.4.x 다.
최근의 프로그램들은 gcc 4.8 이상에서 빌드되는 경우가 많은데 os 업그레이드 없이 gcc 버전을 업데이트 해보자.

# repo 추가
# 혹시 보안상의 이유로 proxy 가 필요하다면 proxy 설정을 export 한다.
# sudo 에서 export 된 proxy 설정을 사용하기 위해 -E 추가
sudo -E wget http://people.centos.org/tru/devtools-2/devtools-2.repo -O /etc/yum.repos.d/devtools-2.repo

# 패키지 설치
sudo -E yum install centos-release-scl-rh
sudo -E yum install devtoolset-3-gcc devtoolset-3-gcc-c++

# gcc, g++ 위치
/opt/rh/devtoolset-3/root/usr/bin/

# devtoolset 활성화
# .bashrc 에 추가해서 사용하자.
source /opt/rh/devtoolset-3/enable

build boost

# boost 최신 파일 다운
wget https://sourceforge.net/projects/boost/files/boost/1.62.0/boost_1_62_0.tar.gz

# 또는
curl -OLv https://sourceforge.net/projects/boost/files/boost/1.62.0/boost_1_62_0.tar.gz

# 압축풀고 bootstrap.sh 실행
tar zxvf boost_1_62_0.tar.gz
cd boost_1_62_0/
./bootstrap.sh

# b2, bjam 등의 생성되며, b2 에 옵션 프로퍼티 타겟으로 빌드 후 설치
# b2 [options] [properties] [targets]
# target : install
# option : /usr/local에 설치(default)
# properties : gcc컴파일러, c++11사용, 디버그, 64비트머신, 멀티쓰레드
sudo ./b2 --prefix="/usr/local" toolset=gcc cxxflags="-std=c++11" variant=debug address-model=64 threading=multi install

# 타겟 파일 삭제
# 옵션 설명은 ./b2 --help
./b2 --clean-all

# 라이브러리 경로 추가
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

# 참고
http://www.boost.org/build/doc/html/bbv2/overview/invocation.html
http://stackoverflow.com/questions/18452723/change-boost-build-jamfile-for-c11-support

#####

# 패키지 관리자를 이용한 boost 설치
# centos
sudo yum install boost boost-devel

# ubuntu
sudo apg-get install libboost-all-dev

C Coding Convention and Naming Notation

# BSD Convention(style)
# 버클리 대학교 Eric Allman 프로그램머의 이름을 따 Allman 스타일이라고도 한다.
# 함수와 조건문 반복문 모두 중괄호 시작 위치가 뉴라인에서 시작한다.
# 장점: 중괄호의 시작 위치가 일관적이라 코드 읽기가 쉽다.
# 단점: 라인 수 증가

int funcA()
{
 if (condition > 0)
 {
  result = 1 + 1;
 }
}

# K&R(Kernighan and Ritchie) Convention(style)
# C 언어를 만드신 두분의 이름을 딴 스타일로
# 함수에는 BSD 와 같이 중괄호 시작위치가 뉴라인에서 시작하지만
# 조건문과 반복문에서는 공백후 시작한다.
# 장점: 코드량(라인수) 감소
# 단점: 중괄호 시작 위치에 일관성이 없어 BSD 에 비해 코드 읽기가 어렵다.
int funcA()
{
 if (condition > 0) {
  result = 1 + 1;
 }
}

# 참고로 함수 이름 과 { 시작 전에 파라미터를 선언하는 것으로
# K&R(Kernighan and Ritchie) old(obsolete)스타일로 거의 사용하지 않는다.
int func1(int_param, char_param)
int int_param;
char *char_param;
{
    printf("%s int_param=%d char_param=%s\n", __FUNCTION__, int_param, char_param);
    return 0;
}

# 기타 스타일
https://en.wikipedia.org/wiki/Indentation_style

# 헝가리언 표기법
# MS 프로그래머인 Charles Simonyi  가 사용한 이름 표기 방식으로 특수한 prefix 를 사용한다.
bool bFlag;
char *pName;
char cChar;
char szName[10];
int nIndex;
float fNum;
class CClass

# 카멜(Camel) 표기법
# 소문자로 시작해서 단어 사이를 대소문자로 구별한다.
void myTestFunction() {}

# 파스칼(Pascal) 표기법
# 첫번째 문자를 대문자로 시작한다.
void MyTestFunction() {}

Mac OS gcc 설치

우선 xcode 를 설치한다.(상황에 따라선 Mac OS 업데이트가 필요)
https://developer.apple.com/xcode/

xcode 를 설치했지만 터미널에서는 gcc 를 실행하면 다음과 같이 gcc 가 없다고 나온다.
"gcc: command not found"

이경우 xcode 를 실행하고 gcc 및 명령줄에서 실행될 수 있는 개발 도구 설치해야 한다.
XCode 실행 -> 메뉴 -> Preferences -> Downloads -> Command Line Tools -> Install

Mac 패키지 관리자 brew 사용하기

Mac 에서 리눅스의 yum, apt-get 같은 기능을 해주는게 port 와 brew 라는 프로그램이다.
의존성이 있는 프로그램들을 알아서 설치해주니 필수로 설치하도록 하자.
port 보단 brew 를 더 많이 사용하는것 같다.

# brew
# 자세한 사용방법 :http://brew.sh/index_ko.html
# 설치하기(ruby 사용)
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

# brew 로 설치된 프로그램(패키지) 보기
# list 또는 ls
brew ls

# 패키지 path 보기
brew ls nmap

# 패키지 검색
brew search nmap

# brew 로 nmap 설치
brew install nmap

# 설치 후 과정만 다시 수행
brew postinstall nmap

# 설치된 패키지 중 old 버전 삭제
brew clean

# 패키지 삭제
brew remove nmap

# dead symlinks 인경우 제거
brew prune

# 패키지 정보(등록된 url 을 확인할 수 있다.)
brew info nmap

# curl 설치(http2 사용할 수 있도록)
# 2019년부터 --with-nghttp2 옵션 제거됐다.
# https://github.com/Homebrew/homebrew-core/issues/31510
# brew install curl --with-nghttp2
# http2 를 사용하려면 대신 curl-openssl 을 설치해야 한다.
brew install curl-openssl

# brew 로 설치된 프로그램은
# /usr/local/Cellar 에 다운로드되고
# /usr/local/bin 에 링크 파일을 생성한다.
# 원래 맥에서 기본 제공하는 /usr/bin/ 의 curl 같은 프로그램은
# brew 로 설치하면 /usr/local/bin 에 링크 파일이 생성되지 않는다.
# 이런 경우를 다음과 같이 keg-only 라고 한다.
"This formula is keg-only, which means it was not symlinked into /usr/local"

# 이렇게 설치시 자동으로 링크가 되지 않는 경우
# link --force 옵션으로 링크 파일을 강제 생성할 수 있다.
# /usr/local/bin/curl 링크 파일이 강제 생성
# 참고로 brew unlink 는 /usr/local/bin 링크 파일이 삭제한다.
brew link --force curl-openssl

# 그런데 macOS 에서 link --force 도 거부된다.
Warning: Refusing to link macOS-provided software: curl-openssl

# 대신 PATH 환경변수를 사용해야 한다.
export PATH=/usr/local/opt/curl-openssl/bin:$PATH

# 서비스(백그라운드) 작업시
brew services list
brew services start mysql@5.7
brew services stop mysql@5.7

build and install openssl

# OpenSSL 윈도우 빌드
1. openssl-1.0.1c.tar.gz 압축 해제
2. cd openssl-1.0.1c
3. 콘솔창에서 VC++ 사용할 수 있도록 환경 설정
   "c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
4. perl 로 설정파일 만들기(perl 설치파일 http://downloads.activestate.com/ActivePerl/releases/)
   win32 경우 ==> perl Configure VC-WIN32 --openssldir=C:\OpenSSL1.0.1
   win64 경우 ==> perl Configure VC-WIN64A --openssldir=C:\OpenSSL1.0.1
5. 컴파일 환경 설정 배치 실행
   win32 경우 ==> ms\do_ms.bat
   win64 경우 ==> ms\do_win64a.bat
6. 빌드
   .lib 빌드 ==> nmake -f ms\nt.mak install
   .dll 빌드 ==> nmake -f ms\ntdll.mak install
7. 결과 확인
   include 파일 ==> C:\OpenSSL1.0.1\include\openssl
   .lib(.dll) 파일 ==> C:\OpenSSL1.0.1\lib

#####

# OpenSSL 리눅스 빌드
1. openssl-1.0.1c.tar.gz 압축 해제
   tar zxvf openssl-1.0.1c.tar.gz
2. cd openssl-1.0.1c
3. 설정파일 만들기
   ./config --prefix=/home/ysoftman/openssl1.0.1
4. 빌드 후 테스트
   make && make test
5. 설치
   make install
6. 결과 확인
   include 파일 ==> /home/ysoftman/openssl1.0.1/include/openssl
   .a 파일 ==> /home/ysoftman/openssl1.0.1/lib

#####

# redhat, centos 에서 설치
sudo yum install -y pcre-devel
sudo yum install -y openssl-devel

# debian, ubuntu 에서 설치
sudo apt-get install -y libpcre3-dev
sudo apt-get install -y libssl-dev
sudo apt-get install -y libz-dev

#####

# mac(darwin) 에서 설치
brew install openssl
# openssl-devel 가 없기 때문에 openssl 의 include, lib 파일을 링크해준다.
echo 'y' | ln -s /usr/local/opt/openssl/include/openssl /usr/local/include
echo 'y' | ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib

# mac 기본 openssl(LibreSSL) 이 있다.
# /usr/bin/openssl # openssl(LibreSSL)
# openssl(OpenSSL) 을 설치하면 다음 경로에 생성된다.
# /usr/local/opt/openssl/bin/openssl  # openssl(OpenSSL)
brew install openssl

# /usr/local/opt/openssl/bin/openssl 이 우선 하는지 확인
which -a openssl
/usr/local/opt/openssl/bin/openssl
/usr/bin/openssl

# openssl(OpenSSL) 경로를 우선하지 않다면 우선하도록 PATH 환경변수 변경하자.
export PATH=/usr/local/opt/openssl/bin/openssl:$PATH

#####

# 다음 옵션들로 현재 참고하고 있는 include <...>, LIBRARY_PATH 설정을 파악할 수 있다.
# -x 언어
# -v verbose
# -E 지정된 장치(stage)에서 preprocessor 만 수행한다.
g++ -x c++ -v -E /dev/null

Linux yum 저장소(repository) 설정

yum 이 참조하는 저장소는 /etc/yum.repos.d 에서 설정할 수 있다.
보통 CentOS 경우 CentOS-Base.repo CentOS-Debuginfo.repo CentOS-Media.repo 3개가 있으며 패키지 저장소 위치는 CentOS-Base.repo 에 아래와 같이 설정된다.

[base]
name=CentOS-$releasever - Base
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os
#baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#released updates
[updates]
name=CentOS-$releasever - Updates
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates
#baseurl=http://mirror.centos.org/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=extras
#baseurl=http://mirror.centos.org/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=centosplus
#baseurl=http://mirror.centos.org/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
mirrorlist=http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=contrib
#baseurl=http://mirror.centos.org/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6

# 참고로 gcc/g++ 개발 툴 패키지를 기본으로 설치해놓도록 한다.
# 패키지 확인
sudo yum groupinfo -v 'development tools'

# 설치
sudo yum groupinstall -y 'development tools'

Linux odbc / sqlite mysql oracle 설치 및 환경 설정

// unixODBC 설치
sudo yum -y install glibc-devel.i686 unixODBC-devel.i686 glibc-devel.x86_64 unixODBC-devel.x86_64

// oracle odbc 드라이버 설치
(64bit일경우, 다운로드 : http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html)
sudo rpm -ivh oracle-instantclient11.2-basic-11.2.0.3.0-1.x86_64.rpm
sudo rpm -ivh oracle-instantclient11.2-odbc-11.2.0.3.0-1.x86_64.rpm

//mysql odbc 드라이버 설치
sudo yum -y install mysql-connector-odbc mysql-devel

// sqlite 드라이버 설치
sudo yum -y install sqlite-*

// sqliteodbc-0.94 설치(gcc 4.1.2 이하에선 sqliteodbc-0.89 이하 버전설치)
./configure
make
sudo make install

// odbcinst.ini 및 odbc.ini 설정파일 위치 파악
odbcinst -j

// odbc driver 설정
// driver 를 찾을 수 없다는 실패 메시지가 발생하면 /usr/local/etc/odbcinst.ini 에 만들도록 한다.
sudo vi /etc/odbcinst.ini 또는 /usr/local/etc/odbcinst.ini
[SQLite]
Description=SQLite ODBC Driver
Driver=/usr/local/lib/libsqlite3odbc.so
Setup=/usr/local/lib/libsqlite3odbc.so
Threading=2

[MySQL]
Description     = ODBC for MySQL
Driver          = /usr/lib/libmyodbc3_r.so
Setup           = /usr/lib/libodbcmyS.so
Driver64        = /usr/lib64/libmyodbc3_r.so
Setup64         = /usr/lib64/libodbcmyS.so
FileUsage       = 1

[OracleODBC-11g]
Description = Oracle ODBC driver for Oracle 11g
Driver = /usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1
FileUsage = 1
Driver Logging = 7

// DSN 설정하기
sudo vi /etc/odbc.ini 또는 /usr/local/etc/odbc.ini
[oracle]
Description=ODBC for oracle client 64
Driver=OracleODBC-11g

// odbc driver 파악
odbcinst -q -d

// odbc dsn 파악
odbcinst -q -s

// 참고 ORACLE 클라이언트 환경 설정(.bashrc 에 설정)
export ORACLE_SID=ysoftman_service_id
export TNS_ADMIN=/usr/lib/oracle/11.2/client64/
export PATH=/usr/lib/oracle/11.2/client64/bin:$PATH
export NLS_LANG="AMERICAN_AMERICA.UTF8"
export TWO_TASK=ysoftman_service_id

// isql 로 접속해보기
isql oracle userid password

// sqlplus 로 접속해보기(TWO_TASK로 접속대상을 설정해서 호스트는 생략)
sqlplus userid/password

Linux 라이브러리 정보 확인 유틸 objdump, nm, ldd

# objdump 로 등의 오브젝트(라이브러리)의 정보를 확인할 수 있다.
objdump -a ./ysoftman.a

# nm 으로 오브젝트 파일의 심볼 목록을 볼 수 있다.
# (컴파일시 -g 옵션이 포함되어 있어야 함)
nm ./ysoftman.a

# ldd 로 프로그램에서 사용하는 공유 라이브러리를 확인할 수 있다.
ldd ./ysoftman.a

# mac 에선 ldd 대신 otool -L 을 사용하자
otool -L ./ysoftman.a

# assembly 코드 보기
# -c : 컴파일만하여 오브젝트 파일 생성
# -g : 소스레벨의 디버깅 정보 포함(소스 내용을 포함한다.)
g++ -c -g ysoftman.cpp

# -d : disassemble
# -S : disassembly 코드에 해당하는 소스코드 표시
objdump -dS ysoftman.o

# mac 에서는
objdump -disassemble -source ysoftman.o

build MongoDB C++ Client

[윈도우 빌드]
boost : http://sourceforge.net/projects/boost/files/boost-binaries/1.42.0/
python : http://www.python.org/download/
scons : http://www.scons.org/
SpiderMonkey : http://www.mongodb.org/download/attachments/1474760/js.zip
mongodb source : http://www.mongodb.org/downloads
mongovue: http://www.mongovue.com/downloads/

vcvarsall.bat 위치를 환경변수에 추가 (C:\Program Files (x86)\Microsoft Visual Studio 9.0\vc\)
scons 위치를 환경변수에 추가(C:\Python26\Scripts)
콘솔에서 visual c++ 컴파일러를 사용하기 위해서 vcvarsall.bat 실행
D:\ysoftman\Project\mongodb-src-r2.0.2\js 에 SpiderMonkey 압축 풀기
D:\ysoftman\Project\mongodb-src-r2.0.2\SConstruct 에서 find_boost() 부분 수정
    def find_boost():
        for x in ('', ' (x86)'):
            #boostDir = "C:/Program Files" + x + "/boost/latest"
     boostDir = "D:/ysoftman/Project/mongodb-src-r2.0.2/boost_1_42_vs2008_partial_prebuilt/"

mongoclient.lib 생성(release 버전 32bit 용으로)
D:\ysoftman\Project\mongodb-src-r2.0.2\scons mongoclient --release --32

SConstruct 파일의 /MDd --> /MTd 로 수정
mongoclient.lib 생성(debug 버전 32bit 용으로)
D:\ysoftman\Project\mongodb-src-r2.0.2\scons mongoclient --dd --32
D:\ysoftman\Project\mongodb-src-r2.0.2\client\*.h 헤더파일 사용

[빌드 후 신경써야 할것들]
멀티바이트환경에서는 log.h 파일의 399 line LPTSTR --> LPWSTR 로 변경
pch.h 파일 위부분에 보면 에 다음의 내용이 있다.
#define WIN32_LEAN_AND_MEAN
# include <winsock2.h> //this must be included before the first windows.h include
# include <ws2tcpip.h>
# include <wspiapi.h>
# include <windows.h>
WIN32_LEAN_AND_MEAN 는 중복되는 파일을 줄여 주는 역할로 처음에 컴파일된 파일이후에 같은 내용을 무시하도록 한다.
MongoDB 는 윈속2(windosock2.h) 를 사용하지만 windows.h 에는 기본적으로 윈속1(winsock2)를 사용한다.
따라서 WIN32_LEAN_AND_MEAN 를 정의하고 아래처럼 winsock2.h 가 windows.h 보더 먼저 오게된다.
그리고 .pch.h 파일을 가장 먼저 컴파일되어야 한다.

[리눅스 빌드]
1. mongodb 압축 풀기
   unzip mongodb-src-r2.0.4.zip
2  필요한 툴 설치
   sudo yum install scons gcc-c++ glibc-devel boost boost-devel pcre-devel js-devel readline-devel
3. libmongoclient.a 생성(참고로 mongodb 빌드시:  scons all)
   scons mongoclient -j 8

Linux gprof 를 이용한 소스코드 프로파일링

# 소스코드의 함수별 경과시간을 프로파일링 할때 가장 간단한 방법 중의 하나가 gprof 를 이용한 것이다.
# 우선 컴파일과 링크시 -pg 옵션을 준다.
# 만약 Makefile 을 사용해서 컴파일 후 링크가 이뤄진다면 각각 -pg 옵션을 준다.
gcc -pg -o ysoftman ysoftman.c

# gprof 을 이용하여 프로파일링 결과를 출력한다.
gprof ysoftman > profile.txt

# 만약 실행프로그램이 인자를 입력받는 경우라면 우선 실행 프로그램만을 실행한다.
ysoftman -arg1 -arg2

# 그러면 현재 디렉토리에 실행프로그램(ysoftman)에 대한 gmon.out 이라는 프로파일링 정보파일이 생성된다.

# 아래와 같이 실행프로그램과 프로파일링 정보파일을 사용하여 프로파일 결과를 출력한다.
gprof ZoneAnal gmon.out > profile.txt

Linux gcc 링크시 .a .so 우선순위

# 리눅스 환경에서 정적(.a) 라이브러리와 동적(.so) 라이브러리가
# 같은 디렉토리에 존재하면 gcc 링크시 .so 가 우선적으로 지정된다.
# ./lib 에 libysoftman.a 와 libysoftman.so 존재할때
# libysoftman.so 를 기본으로 사용한다.
gcc -o yoon yoon.o -L./lib -lysoftman

# libysoftman.a 를 지정하고 싶다면 -static 옵션을 사용하도록 한다.
gcc -static -o yoon yoon.o -L./lib -lysoftman

# libxxxx.a(so) 같은 형태가 아니라면 파일명으로 직접 명시할 수도 있다.
gcc -o yoon yoon.o -L./lib -l:mod_ysoftman.so