C++/Python 환경에서 Coveralls + Travis-CI로 코드커버리지 테스트

코드 커버리지에 대한 설명들. https://blog.outsider.ne.kr/954

코드 커버리지를 테스트하기 위한 방법들을 정리해본다.


C++에서 코드커버리지 테스트

C++이나 gcc를 사용하고 있다면 g++ 컴파일 옵션에 --coverage 를 넣는다. 만약, cmake를 사용한다면, 다음과 같은 코드로 코드커버리지 테스트와 coveralls까지 연동 가능하다

https://github.com/dongbum/DServer/blob/master/.travis.yml

language: cpp

os:
- linux

compiler:
- gcc

dist: bionic

before_install:
- pip install --user cpp-coveralls
- sudo add-apt-repository ppa:mhier/libboost-latest -y
- sudo apt update
- sudo apt-get install libjemalloc-dev libjemalloc1 libjemalloc-dev libjsoncpp-dev libjsoncpp1 libmysqlcppconn-dev libmysql++-dev libboost1.70-dev

env:
  global:
  - MAKEFLAGS=-j 2

script:
- cmake CMakeLists.txt
- make
- ./GameServer

after_success:
- coveralls --exclude external_library --exclude make_gcc --exclude vs_solution --exclude CMakeFiles --gcov-options '\-lp'
© 2019 GitHub, Inc.

cmake로는 따로 옵션이 필요 없었다.


Python에서 코드커버리지 테스트

https://docs.coveralls.io/python 와 coveralls-python 두가지를 추천하고 있다. python-coveralls로 설정하던 중 다음과 같은 에러를 만났다.

다음과 같이 간단한 Traivs-CI 스크립트로 커버리지 테스트를 성공했다.

language: python
python:
  - 3.6
install:
  - pip install -r requirements.txt
  - pip install coverage
  - pip install coveralls
script:
  - python3 update.py
  - coverage run update.py
after_success:
  - coveralls

다만 coverage 명령은 run을 같이 해야되기 때문에 프로그램 실행되어야만 한다. 그래서 이 방법은 바로 실행되는 파이썬 프로그램에 한해서만 가능하다.


Python Flask에서 코드커버리지 테스트

Flask 프레임워크를 사용하면 웹서버를 바로 실행시키는 형태로 프로그램이 작동하는지라 위의 coverage run 명령어로 테스트를 할 수가 없다. 이 명령으로 테스트를 하면 웹서버가 실행되고 프로세스가 종료되지 않기 때문에 travis의 빌드도 영원히 계속된다. 물론 이 상태로 10분 정도가 지나면 travis가 빌드실패로 처리해버린다. 따라서 Flask를 쓸때는 travis-ci에서 실제 프로그램을 실행시키는 형태가 아니라 코드커버리지 테스트만 수행해야한다. 이렇게 작동하기 위해서는 nose라는 또다른 코드커버리지 툴이 필요했다. travis-ci 스크립트는 다음처럼 같이 작성했다.

language: python
services:
  - mysql
python:
  - 3.6
before_install:
  - mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
install:
  - pip install -r requirements.txt
  - pip install coverage
  - pip install coveralls
  - pip install nose
  - pip install nose-exclude
script:
  - nosetests --with-coverage --cover-erase --cover-package=board
after_success:
  - coveralls

nosetests는 프로그램을 실제로 수행하지 않고도 코드커버리지만 테스트할 수 있기에 Flask로 작성된 프로그램들은 nose를 이용해야할 것 같다. 번외로, Flask를 사용하면서도 위에 있는 coverage run 명령을 이용할 수도 있는데, 웹서버를 실행시킨 상태로 특정 경로(예를 들면, /exit 같은...)을 호출하면 웹서버가 스스로 종료되도록 하는 방법이다. 하지만 이 방법은 그야말로 테스트를 위해 경로를 만들고 테스트만을 위한 종료코드까지 만들어야하는 관계로 nose를 쓰는 방법이 더 나은 것 같다.


참고자료

UnityBuild와 pragma once

회사에 들어와서 쓰던 것 중, 성준씨의 도움으로 유니티빌드라는 컴파일 기법을 알게 되었는데...

https://openshortcuts.com/archives/922

이 개념은 헤더파일을 다시 컴파일하는 것을 막아보자가 중심이다. 이 내용을 읽어보며 그럼 #pragma once#ifndef 가드가 있는데 왜 이걸로 컴파일 시간이 줄어든다는 것인가...? 에 대해 생각해보다가 다음과 같은 글을 보게 되었다. https://oojjrs.tistory.com/32 이 글이 내가 궁금했던 것을 정확히 설명해두었다.

한 번만 include 하는 것은 모두 오브젝트 단위에서의 이야기다. 오브젝트가 다르면 제 아무리 이전에 8만줄짜리 파일을 포함하여 컴파일을 이미 진행했다 하더라도 컴파일러는 다시 컴파일을 진행해버린다는 이야기다.

이것이 바로 유니티빌드를 사용할 때 컴파일 속도가 올라가는 이유였던 것.

Github와 연동 가능한 LGTM.com

Github에 돌아다니다보면 다음과 같은 뱃지를 볼 수 있는데,

저기 있는 코드 퀄리티 뱃지가 무엇인지 찾아보니 LGTM.com이라는 서비스였다.

원래 LGTM은 Looks Good To Me의 약자로 깃허브에서 다른 사람의 코드를 보고 '아주 좋은 코드다.'라는 의미의 리플을 남길 때 쓰는 단어이다.

여튼 이 서비스는 깃허브 레포지토리의 소스코드를 읽어들여서 소스코드의 품질을 체크하고 보안이슈나 위험한 부분을 체크해주는 서비스이다.

https://lgtm.com 에 가서 가입하고 깃허브 레포지토리를 연동해야한다. 연동 후 소스코드의 품질을 자동으로 측정하고 위험부분을 표시해준다.

cppcheck 등의 프로그램과 거의 동일하다. 다만 깃허브와 연동하기 편하게 되어있고, 온라인으로 알아서 작동한다는 것이 편리하다.

내 레포지토리에서는

사용되지 않는 변수 등을 이렇게 지적해준다.

대략 C++, Python 등 메인 프로그래밍 언어들은 다 지원하므로 깃허브에 소스코드를 올려서 사용한다면 이러한 서비스를 같이 사용해보면 좋을 것 같다.

Flask + IIS 로 윈도우에서 서비스하기

Flask로 만든 라이센스서버를 윈도우에 올려보기로 한다. 테스트할 환경은 다음과 같다.

  • OS : Microsoft Windows 10
  • Python : 3.6.8
  • Flask로 작성된 어플리케이션

Flask와 IIS

원래는 Flask로 만들었으니 IIS에 붙이려고 했다. 그런데 그게 쉽지 않았다. IIS에 온갖 설정과 에러와 싸우며 조금씩 전진했지만 나는 지쳐갔고 정말 이게 최선인가...? 하는 생각이 들기 시작했다. 어차피 플라스크만으로도 괜찮은 웹서버 아니었던가? 굳이 IIS와 연동이 왜 필요한가? 에서 답을 찾지 못했다. 아파치나 nginx와 연동도 있었지만 이건 결국 플라스크로 만든 어플리케이션을 띄워놓은 상태에서 웹으로 들어오는 요청만 프록시 처리해주는 방식이라 더 의미 없는 것 같았다. 그래서 이걸 아예 윈도우서비스로 올릴 수 있으면 어떨까 싶었다.


Web.config 파일 생성

https://docs.microsoft.com/ko-kr/visualstudio/python/configure-web-apps-for-iis-windows?view=vs-2019

웹페이지를 보며 설정한다. 간단하게 web.config 파일만 생성해주면 되었다. ```

<?xml version=1.0 encoding=utf-8?>
<configuration>
  <system.webServer>
    <handlers>
      <add   name=PythonHandler
            path=*
            verb=*
            modules=FastCgiModule
            scriptProcessor=C:\Python\Python36\python.exe|C:\Python\Python36\Lib\site-packages\wfastcgi.py
            resourceType=Unspecified
            requireAccess=Script ></add>
    </handlers>

  </system.webServer>

  <appSettings>
      <add key=PYTHONPATH value=D:\license_server></add>
      <!-- The handler here is specific to Bottle; see the next section. -->
      <add key=WSGI_HANDLER value=runserver.application></add>
      <add key=WSGI_LOG value=D:\logs\wfastcgi.log></add>
  </appSettings>
</configuration>

wfastcgi-enable 실행

cmd를 관리자 권한으로 열고, 파이썬 프로그램이 있는 곳에 가서 wfastcgi-enable 을 실행해준다. IIS에서 사이트를 생성하고 접속해본다. 파일을 생성하고 실행하니 이상하게도 config 파일을 읽어오지 못하는 문제가 발생했다. 경로도 모두 맞는데 파일을 읽지 못하는 현상. 확인해봤더니 root 경로를 잘못 잡고 있었다. 경로 밑에 config 파일을 넣어주니 해결


참고자료

apache 2.4 + flask 설정방법

아파치에서 Flask로 만들어진 어플리케이션을 작동하기 위한 방법을 정리해둔다.

 

에러메시지는

[Mon Jul 03 19:42:27.334280 2017] [:error] [pid 14570] [client 59.10.233.103:63211] Traceback (most recent call last):
[Mon Jul 03 19:42:27.334301 2017] [:error] [pid 14570] [client 59.10.233.103:63211] File "/home/viper9/python_test/VeloWeight.wsgi", line 7, in <module>
[Mon Jul 03 19:42:27.334349 2017] [:error] [pid 14570] [client 59.10.233.103:63211] from hello import app as application
[Mon Jul 03 19:42:27.334364 2017] [:error] [pid 14570] [client 59.10.233.103:63211] File "/home/viper9/python_test/hello.py", line 1, in <module>
[Mon Jul 03 19:42:27.334392 2017] [:error] [pid 14570] [client 59.10.233.103:63211] from flask import Flask
[Mon Jul 03 19:42:27.334409 2017] [:error] [pid 14570] [client 59.10.233.103:63211] ImportError: No module named flask
[Mon Jul 03 19:42:27.432767 2017] [:error] [pid 14538] [client 59.10.233.103:63210] mod_wsgi (pid=14538): Target WSGI script '/home/viper9/python_test/VeloWeight.wsgi' cannot be loaded as Python module., referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432821 2017] [:error] [pid 14538] [client 59.10.233.103:63210] mod_wsgi (pid=14538): Exception occurred processing WSGI script '/home/viper9/python_test/VeloWeight.wsgi'., referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432848 2017] [:error] [pid 14538] [client 59.10.233.103:63210] Traceback (most recent call last):, referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432870 2017] [:error] [pid 14538] [client 59.10.233.103:63210] File "/home/viper9/python_test/VeloWeight.wsgi", line 7, in <module>, referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432904 2017] [:error] [pid 14538] [client 59.10.233.103:63210] from hello import app as application, referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432914 2017] [:error] [pid 14538] [client 59.10.233.103:63210] File "/home/viper9/python_test/hello.py", line 1, in <module>, referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432928 2017] [:error] [pid 14538] [client 59.10.233.103:63210] from flask import Flask, referer: http://python.83rpm.com/
[Mon Jul 03 19:42:27.432963 2017] [:error] [pid 14538] [client 59.10.233.103:63210] ImportError: No module named flask, referer: http://python.83rpm.com/

http://flask.pocoo.org/docs/0.12/deploying/mod_wsgi/ 를 읽어보니 다음과 같이 써있었다.

 

Working with Virtual Environments
Virtual environments have the advantage that they never install the required dependencies system wide so you have a better control over what is used where. If you want to use a virtual environment with mod_wsgi you have to modify your .wsgi file slightly.

Add the following lines to the top of your .wsgi file:

activate_this = '/path/to/env/bin/activate_this.py'
execfile(activate_this, dict(file=activate_this))
For Python 3 add the following lines to the top of your .wsgi file:

activate_this = '/path/to/env/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(file=activate_this))

 

execfile(activate_this, dict(file=activate_this)) 를 삭제하고

 

with open(activate_this) as file_:
exec(file_.read(), dict(file=activate_this))

 

를 추가했다.

 

하지만 다시 실행해도 같은 에러...

 

wsgi 파일을 다음과 같이 수정했다.

import os
import sys
import site

site.addsitedir('/home/viper9/python_test/venv/lib64/python3.4/site-packages')

sys.path.insert(0, '/home/viper9/python_test')

activate_this = '/home/viper9/python_test/venv/bin/activate_this.py'
with open(activate_this) as file_:
exec(file_.read(), dict(file=activate_this))

from hello import app as application

 

MySQL 에러가 난다면 다음의 패키지를 설치한다.

yum install MySQL-python

 

해결했더니 그 다음 에러...

UnicodeDecodeError: 'ascii' codec can't decode byte 0xae in position 8: ordinal not in range(128)

 

https://libsora.so/posts/python-hangul/ 를 찾아보니 인코딩의 문제라고 한다. 문서를 보고 해결. .wsgi 에 설정을 추가했다.

reload(sys)
sys.setdefaultencoding('utf-8')

그런데... 그래도 해결이 안된다... 아 힘들다. 다시 이런저런 정보를 찾아헤메이다 로그를 다시 읽어보니 DB를 사용하는 곳에서만 에러가 났다. DB에서 데이터 가져올 때 문제가 있구나.. 라는 생각이 들어 DB 설정을 확인했더니 utf-8로 이미 다 설정되어 있었다. 코드도 UTF-8이고 DB도 UTF-8인데 데이터 가져오는데 문제가 있다면 커넥션 자체에서 캐릭터셋을 지정해주지 않아서 그런 것 같았다. 다시 검색을 해보니 다음 문서를 발견 https://stackoverflow.com/questions/10819192/sqlalchemy-result-for-utf-8-column-is-of-type-str-why create_engine() 함수를 쓸 때

create_engine('mysql+mysqldb:///mydb?charset=utf8')

처럼 사용하라는 것이었다. 이 설정을 추가해주니 드디어 페이지가 정확하게 떴다. 아이고 힘들다...

Visual Studio 에서 cURL 설치

윈도우에서 웹페이지와 통신할 때 WinHTTP 모듈을 쓰고 있었는데 이 모듈은 윈도우 전용이므로 리눅스에서는 사용이 불가능하다.

cURL 모듈을 사용할 수 있는지 테스트.

vcpkg로 cURL을 간단히 설치할 수 있었다.

그러나....

도저히 해결이 불가능했다. 구글과 스택오버플로우를 열심히 뒤졌으나 빌드플랫폼이 맞지 않아서 그럴거라는 의견뿐. x86 라이브러리와 x64 라이브러리를 모두 받아서 테스트 해봤으나 실패했다.

vcpkg에 대한 환상이 좀 깨졌다.

 

직접 받아서 빌드해보기로 했다.

cURL은 git 에서 소스 관리를 하고 있다.

cURL을 클론한다.

git clone https://github.com/curl/curl.git curl.git

다운 받은 폴더의 projects/Windows 폴더에 가면 Visual Studio 버전별로 쭉 있다. 난 2015이므로 VC12 선택.

curl-all.sln 솔루션 파일을 더블클릭하여 VS2015로 열어본다.

왜인지 모르겠는데 프로젝트 로드가 안된다. 프로젝트 파일이 없나 해당 위치에 가서 살펴봤는데.... 진짜로 프로젝트 파일이 없다!

 

어떻게 해야되나 고민하던 중에 project 폴더를 보니 여러개의 배치파일이 보였다. 일단 checksrc.bat 파일을 실행했다. 한참 아무메시지가 없더니만 프로그램이 종료되었다. 별 문제가 없으면 별 메시지를 출력하지 않나보다. (bat 파일 내용을 읽어보진 않았다.)

이제 왠지 프로젝트를 생성해줄 것 같은 generate.bat 파일을 실행했다. 예상대로...

D:\Library\curl.git\projects>checksrc.bat

D:\Library\curl.git\projects>generate.bat

Generating prerequisite files
* D:\Library\curl.git\Makefile
* D:\Library\curl.git\src\tool_hugehelp.c

Generating VC6 project files
* D:\Library\curl.git\projects\Windows\VC6\src\curl.dsp
* D:\Library\curl.git\projects\Windows\VC6\lib\libcurl.dsp

(...중략...)

Generating VC12 project files
* D:\Library\curl.git\projects\Windows\VC12\src\curl.vcxproj
* D:\Library\curl.git\projects\Windows\VC12\lib\libcurl.vcxproj

(...중략...)

D:\Library\curl.git\projects>

예상대로 프로젝트 파일을 생성해주었다.

이제 다시 아까 VC12 폴더로 가서 솔루션 파일을 여니까 프로젝트가 보인다! 솔루션 빌드를 눌렀더니....

 

...안된다...

 

1>d:\library\curl.git\lib\ssh.h(28): fatal error C1083: 포함 파일을 열 수 없습니다. 'libssh2.h': No such file or directory
1>..\..\..\..\lib\md5.c(88): fatal error C1083: 포함 파일을 열 수 없습니다. 'openssl/md5.h': No such file or directory
1>..\..\..\..\lib\md4.c(31): fatal error C1083: 포함 파일을 열 수 없습니다. 'openssl/opensslconf.h': No such file or directory

메시지가 쭉 박혀있었다.

다시 project 폴더에 가서 왠지 ssl 문제를 해결해줄 것 같은 build-openssl.bat 파일을 실행시키니 다음과 같은 안내가 나왔다.

D:\Library\curl.git\projects>build-openssl.bat

Usage: build-openssl <compiler> [platform] [configuration] [directory] [-VSpath] ["VSpath"] [-perlpath] ["perlpath"]

Compiler:

vc6       - Use Visual Studio 6
vc7       - Use Visual Studio .NET
vc7.1     - Use Visual Studio .NET 2003
vc8       - Use Visual Studio 2005
vc9       - Use Visual Studio 2008
vc10      - Use Visual Studio 2010
vc11      - Use Visual Studio 2012
vc12      - Use Visual Studio 2013
vc14      - Use Visual Studio 2015
vc14.1    - Use Visual Studio 2017

Platform:

x86       - Perform a 32-bit build
x64       - Perform a 64-bit build

Configuration:

debug     - Perform a debug build
release   - Perform a release build

Other:

directory - Specifies the OpenSSL source directory

-VSpath - Specify the custom VS path if Visual Studio is installed at other location
          then "C:/<ProgramFiles>/Microsoft Visual Studio[version]
          For e.g. -VSpath "C:\apps\MVS14"

-perlpath - Specify the custom perl root path if perl is not located at "C:\Perl" and it is a
            portable copy of perl and not installed on the win system
            For e.g. -perlpath "D:\strawberry-perl-5.24.3.1-64bit-portable"

D:\Library\curl.git\projects>

어렵구나...

OpenSSL을 같이 연동해줘야하는것 같은데 정녕 이 방법 밖에 없는 것인지 다시 생각해봤다.

 

다시 vcpkg를 쓰는 방법을 찾아본다.

 

많은 글들을 참고로 했다. ( http://bugsfixed.blogspot.com/2017/05/vcpkg.html )

이것저것 해보던 중. 갑자기 프로그램이 정상작동 되었다. -_-;;

설정은 프로젝트 설정에서 추가 포함 디렉토리로 include와 추가 라이브러리 디렉토리로 lib 디렉토리만 설정했고 다른 설정은 모두 삭제했다.

프로그램을 빌드해봤더니 바이너리 파일과 함께 libcurl.dll, zlib1.dll 파일이 자동으로 생성되었다. 이제 cURL을 테스트 해볼 차례.

 

<참고자료>

  • cURL 사용하여 웹페이지 긁어오기 : http://sobusted.cf/221485638633
    이 예제 중 fstream 관련하여 약간 문제가 있어 수정해서 사용했다.
  • libcurl 메뉴얼 : https://curl.haxx.se/libcurl/c/
  • 테스트 해봤던 프로젝트 : https://github.com/dongbum/CURLTest

double 타입 사용시 주의할 점

오늘 삽질했던 코드. 평소에는 double을 잘 안 쓰다보니 헷갈렸다.

문제가 되었던 코드.

for (auto iter = range.first; iter != range.second; iter++)
{
    int reward_id = (*iter).second.reward_id;
    int funcsrl = (*iter).second.funcsrl;
    int reward_type = (*iter).second.reward_type;
    std::string reward_itemcode = (*iter).second.itemcode;
    double rate = (*iter).second.rate / 100;	// DB에는 만분률로 되어있으므로 백분율로 환산해야함.

    lottery_info.Add(std::make_tuple(reward_id, funcsrl, reward_type, reward_itemcode), rate);

#ifdef _DEBUG
    ServerStateLog(g_DebugTracerServer, "RewardID:[%d] FuncSRL:[%d] Rate:[%f]", reward_id, funcsrl, rate);
#endif
}

확률 계산처리를 해야하는데 DB에는 데이터가 만분율 기준(ex : 9.5% = 950)으로 들어가 있고 확률 계산처리 함수에는 백분율로 넣어줘야했다. 그래서 데이터를 가져오면서 나누기 100을 했던 것인데...

이터레이터 안의 (*iter).second.rate 값은 int 값. 950을 100으로 나누어 그 결과인 9.5를 double 형으로 얻으려는 것이었다.

확률 계산에서 문제가 계속 일어나 찾아보니 저 값이 9.5가 아닌 9.0이 들어가고 있었다.

int 와 int 를 나누어서 double 에 넣는다고 소수점 처리가 되지 않는다는 것을 깜빡했다. / 100 을 / 100.0f 로 수정하는 것으로 쉽게 해결.

 

가변인자를 string 으로 사용하기

C/C++에는 함수의 인자를 가변으로 다룰 수 있도록 되어있는데 이 때 사용하는 것이 va_list, va_start, va_arg, va_end 이렇게 네가지 함수다. 네가지 함수에 대한 설명은 이미 인터넷에 많이 나와있다. 그런데 이 가변인자를 문자열 형태로 사용하려고 하면 문제가 많아서 이를 테스트하는 코드를 만들었다.

void Test(const char* types, ...)
{
    va_list ap;

    va_start(ap, types);

    while (types)
    {
        // std::cout &lt;&lt; code :  &lt;&lt; types &lt;&lt; std::endl;
        types = va_arg(ap, const char*);
    }

    va_end(ap);
}

#define Test(...) Test(__VA_ARGS__, NULL)

int main()
{
    Test(A123, A234, A345);

    return 0;
}

가변인자로 넣을 때는 std::string 으로 하려고 했으나 이 타입이 먹히지 않아 const char* 로 받아야한다. 중간에 define 으로 함수와 같은 이름의 매크로를 선언하고 가변인자의 맨 뒤에 NULL 을 넣어주도록 했는데 이게 없다면 가변인자의 맨 끝을 알 수 없어서 문제가 생기게 된다.


참고

boost에서 OpenSSL 사용하기 (2)

빌드된 OpenSSL을 프로젝트 설정에 넣고 다시 빌드해본다.

include를 해야한다.

#include <boost/asio/ssl.hpp>

를 하면 ssl 코드들을 가져온다.

라이브러리 설정에는 빌드된 OpenSSL 폴더의 lib 폴더 경로를 포함시켜줘야한다.

 

이렇게하고 빌드를 해보니...

빌드에 오류가 생겼다.

에러 메시지를 구글에 다시 검색해보니,

https://stackoverflow.com/questions/37522654/linking-with-openssl-lib-statically

링크에서 답을 찾을 수 있었다. http://wiki.openssl.org/index.php/Compilation_and_Installation 에 가서 enable-capieng 이라는 옵션에 대해 찾아보라는 얘기였다.

해당 문서에서 enable-capieng 으로 검색해보니

Enables the Microsoft CAPI engine on Windows platforms. Used to access the Windows Certificate Store. Also see Using Windows certificate store through OpenSSL on the OpenSSL developer list.

라는 내용이 있었다.

빌드 옵션에 추가한다.

perl Configure VC-WIN64A --D:\ --openssldir=D:\Library\OpenSSL enable-capieng no-shared no-asm threads

이렇게 하고 다시 openssl을 빌드해본다.

 

이 옵션으로 해결되지 않아서 -d 옵션 추가. -d 옵션을 추가했더니 nmake 과정에서 알 수 없는 옵션이라는 에러메시지가 나오는 것을 확인했다.

 

빌드옵션을 변경했다.

perl Configure VC-WIN64A --prefix=D:\Library\OpenSSL --openssldir=D:\Library\OpenSSL --debug no-shared no-idea no-mdc2 no-rc5 no-asm no-capieng threads enable-ssl-trace enable-static-engine

 

이렇게 빌드했더니 오류가 절반 정도 사라졌다. 나머지 링킹 오류는 라이브러리 파일을 인식하는 위치에서 추가적인 라이브러리 파일을 불러들여야 했다.

.lib 파일을 불러들이는 곳에서 다음을 추가한다. (혹은 프로젝트 설정에서 해도 된다.)

#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "libcrypto.lib")
#pragma comment(lib, "libssl.lib")

이렇게하고 빌드하니 오류 없이 빌드가 되었다.

 

참고했던 자료들

  • https://github.com/openssl/openssl/blob/OpenSSL_1_1_0-stable/INSTALL
  • https://www.lesstif.com/pages/viewpage.action?pageId=6291508
  • http://www.programmersought.com/article/8711142745/
  • https://github.com/libevent/libevent/issues/59

boost에서 OpenSSL 사용하기 (1) : 윈도우에서 OpenSSL 빌드

boost에서 OpenSSL을 사용하기 위해서는 먼저 OpenSSL 설치가 필요하다. boost의 ssl 관련 파일들에서 openssl 관련 파일들을 인클루드해오기 때문이다.

검색엔진을 찾아보다가, https://jethro.tistory.com/entry/CC-Windows에서-OpenSSL-써먹기 를 참고했다.

 

Step 1. ActivePerl 설치

https://www.activestate.com/products/activeperl/ 로 이동해서 ActivePerl 을 설치한다.

 

Step 2. OpenSSL 소스 다운로드

https://www.openssl.org/source/ 에서 소스코드를 다운로드한다. 난 1.1.1j 버전을 다운로드했다.

 

Step 3. Configure 설정

perl Configure VC-WIN32 --openssldir=C:\OpenSSL-x86-debug no-shared no-asm threads

를 입력하라고 하는데 64비트 윈도우이니 VC-WIN64A 로 입력. (VC-WIN64I 도 있긴한데 아마 Itanium 아키텍쳐일 때 쓰라는 것일 것 같다.)

다음과 같은 오류가 발생.

dmake나 nmake가 필요한 것 같다.

안내 받은대로 ppm install dmake 를 입력하면, 이런저런 패키지들을 설치한다.

 

다시 configure 명령어 입력.

perl Configure VC-WIN64A --openssldir=D:\Library\OpenSSL no-shared no-asm threads

별 문제 없이 끝났다.

 

Step 4. make

그런데 참고하고 있는 블로그 글에는 ms\do_ms.bat 파일이 있다고 했는데 그 위치에 해당 파일이 없다.

구글에 검색해보니...

https://stackoverflow.com/questions/39076244/why-there-is-no-ms-do-ms-bat-after-perl-configure-vc-win64a

1.1.0 버전부터는 그 명령어가 없어졌다고 한다. 그냥 nmake 를 입력하라고 되어있다.

nmake를 해보니 그런 명령어가 없다고 한다. 일반 cmd가 아니라 VS2015 x64 네이티브 도구 명령 프롬프트를 다시 실행해야한다.

 

다시 nmake 를 입력하면 빌드가 시작된다.

다 완료된 후 nmake test 를 입력하여 테스트. 테스트도 잘 완료되었다.

nmake install 을 입력했더니...

*** Installing runtime librariesCannot create directory C:/Program Files/OpenSSL: No such file or directoryNMAKE : fatal error U1077: 'C:\Perl64\bin\perl.exe' : '0x2' 반환 코드입니다.Stop.

에러로 중지된다. 으어...

구글에 검색해보니 나만 겪는 문제는 아닌듯하다. github에 이슈로 올라와있다.

https://github.com/openssl/openssl/issues/2034

댓글을 보고 configure 명령어에 prefix를 추가한다.

perl Configure VC-WIN64A --prefix=D:\Library\OpenSSL --openssldir=D:\Library\OpenSSL no-shared no-asm threads

다시 nmake clean, nmake, nmake test 실행.

다시 make install 을 실행하니 제대로 진행되었다.

 

빌드가 성공되면 prefix로 지정된 위치에 파일들이 생성된다.

OpenSSL 빌드는 끝.