맥에서 동적 라이브러리 참조문제 (Reason: image not found)

ffmpeg를 사용해볼 겸 테스트용 프로젝트를 생성하여 아래와같이 구성.

빌드까지 문제가 없었으나 실행시키면 “Reason: image not found“라는 에러가 발생.

뜬금없이 libswresample.3.dylib를 찾을 수 없다는 에러가 발생한다. 구글링 해본 결과 otool과 install_name_tool을 사용하여 해결해야하는것으로 결론.

실행파일과 dylib파일을 otool -L 명령으로 확인해보면 라이브러리 위치를 ffmpeg를 빌드할 때 prefix 대상 위치로 참조하도록 되어있다. libswresample.3.5.100.dylib 파일을 확인하면 나타나는 항목 중 첫번째 항목은 LC_ID_DYLIB, 두번째 부터 나타나는 항목은 LC_LOAD_DYLIB으로 차이가 있다. (직접 확인하려면 otool -L 대신 otool -l 옵션으로 실행하면 확인가능) 이중 LC_ID_DYLIB는 바이너리가 생성될 때 라이브러리가 참조되는 경로로 링크가되는것으로 보인다. 이 경로는 install_name_tool -id “라이브러리 경로” “라이브러리 파일”로 지정 가능하고 LC_LOAD_DYLIB는 바이너리에서 의존하는 라이브러리며 install_name_tool -change “기존경로” “새로운경로” “라이브러리 파일” 명령으로 변경 가능하다. (경로는 상대경로를 위한 예약어 비슷한 키워드가 있다. @executable_path, @loader_path, @rpath이다. 각각 의미는 구글링으로 패스.)

install_name_tool -id @executable_path/../Frameworks/libavcodec.58.54.100.dylib libavcodec.58.54.100.dylib
install_name_tool -change /Users/iruis/OpenSource/ffmpeg-4.2.1-lgpl/output/lib/libswresample.3.dylib @executable_path/../Frameworks/libswresample.3.5.100.dylib libavcodec.58.54.100.dylib

위와같은 명령으로 라이브러리 경로를 하나하나 바꾸고나면 맥의 패키지 내 복사되는 라이브러리가 참조되어 정상 로딩되어 실행된다. 덕분에 거의 반나절을 삽질한건 안비밀.

IR 송수신 모듈 (YS-IRTM)

우리나라 쇼핑몰에서는 S148 IR이라고 붙어있는곳도 있다.

IR 신호의 인코딩/디코딩을 해주기때문에 편리할거같아서 샀지만 NEC 포맷을 지키지않는 제품이 의외로 많은거같다. LG 에어컨, 선풍기리모컨이 그러한 경우. 덕분에 신호를 디코딩하지 못한다(…). NEC 포맷와 일치하지않아도 8비트 체계로 데이터가 들어오면 포맷이 맞지않아도 출력해준다면 좋았을텐데 아쉽다.

본래는 집 밖에서 에어컨을 키고 들어가기위해 뭐 좀 만들어보고 싶었는데 아무레도 송신모듈, 수신모듈, 아두이노를 써야할지도 모르겠다는 생각이 든다.

결론은 리모컨을 편하게 만들어보려했지만 실패.

Qt5 (5.11.2 기준) MySQL 함께 빌드

1. MySQL 홈페이지에서 MySQL 서버 다운로드
https://dev.mysql.com/downloads/windows/installer/8.0.html
Connector/C++은 Qt의 SQL 플러그인에서 지원안하며, Connector/C는 서버 패키지에 포함되어있다… 다른건 다 개별로 배포하면서 C 라이브러리는 서버 패키지에서 설치하도록 변경되었는지는 이유를 모르겠다.

2. Connector/C 설치
Custom 설치로 선택 후 아래와같이 트리뷰를 펼치면 x64, x86 두가지 아키텍처가 있으며 이 중 한가지만 설치가능하다(…)

필요한 아키텍처를 선탁하여 설치하면 각각 아래 경로에 설치된다. (8버전 기준)
x86: C:\Program Files (x86)\MySQL\MySQL Connector C 6.1
x64: C:\Program Files\MySQL\MySQL Connector C 6.1
폴더가 서로 다른데 왜 둘 다 설치 못하는지는 미지수.

3. 필수 유틸 설치
Python 2.7버전, 그리고 펄을 다운받아 설치한다. 설치 후 콘솔에서 python, perl 실행해보고 INCLUDE, LIB 변수 값 수정.

4. 환경변수 설정
명령 도구모음 x86 또는 x64를 실행한 후 아래와같이 실행하여 환경변수에 추가.
x86:
set INCLUDE=%INCLUDE%;C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\include
set LIB=%LIB%;C:\Program Files (x86)\MySQL\MySQL Connector C 6.1\lib

x64:
set INCLUDE=%INCLUDE%;C:\Program Files\MySQL\MySQL Connector C 6.1\include
set LIB=%LIB%;C:\Program Files\MySQL\MySQL Connector C 6.1\lib

5. 빌드 준비
configure -opensource -confirm-license -prefix D:\OpenSource\Qt5.11.2.x86 -nomake examples -nomake tests -opengl dynamic -mediaplayer-backend wmf -force-debug-info
소스를 압축푼 후 해당 경로에서 위와같이 입력한다.
D:\OpenSource
– Qt5.11.2.x86.build
– qt-everywhere-src-5.11.2
이와같은 구조라면 ..\qt-everywhere-src-5.11.2\configure -opensource…. 와 같이 입력한다.
x86과 x64 타겟 둘 다 빌드하려면 이렇게 쉐도우빌드하는게 좋다. (이미 빌드, configure 완료 된 설정과 충돌이 발생하지 않기때문.) 또한 prefix를 지정하면 빌드 완료 후 nmake install하여 헤더와 바이너리파일을 소스와 오브젝트 파일 따로 둘 수 있다.

아래는 MySQL을 포함 한 configure 결과내용.

Configure summary:

Build type: win32-msvc (x86_64, CPU features: sse sse2)
Configuration: sse2 aesni sse3 ssse3 sse4_1 sse4_2 avx avx2 avx512f avx512bw avx512cd avx512dq avx512er avx512ifma avx512pf avx512vbmi avx512vl compile_examples f16c force_debug_info largefile precompile_header rdrnd shani x86SimdAlways shared debug_and_release release debug build_all c++11 c++14 c++1z concurrent dbus no-pkg-config release_tools stl
Build options:
  Mode ................................... debug and release (with debug info); default link: debug; optimized tools

... 중략 ...

Qt Gui:
  Accessibility .......................... yes
  FreeType ............................... yes
    Using system FreeType ................ no
  HarfBuzz ............................... yes
    Using system HarfBuzz ................ no
  Fontconfig ............................. no
  Image formats:
    GIF .................................. yes
    ICO .................................. yes
    JPEG ................................. yes
      Using system libjpeg ............... no
    PNG .................................. yes
      Using system libpng ................ no
  EGL .................................... yes
  OpenVG ................................. no
  OpenGL:
    ANGLE ................................ yes
    Combined ANGLE Library ............... no
    Desktop OpenGL ....................... no
    Dynamic OpenGL ....................... yes
    OpenGL ES 2.0 ........................ no
    OpenGL ES 3.0 ........................ no
    OpenGL ES 3.1 ........................ no
    OpenGL ES 3.2 ........................ no
  Vulkan ................................. no
  Session Management ..................... yes

... 중략 ...

Qt Sql:
  DB2 (IBM) .............................. no
  InterBase .............................. no
  MySql .................................. yes
  OCI (Oracle) ........................... no
  ODBC ................................... yes
  PostgreSQL ............................. no
  SQLite2 ................................ no
  SQLite ................................. yes
    Using system provided SQLite ......... no
  TDS (Sybase) ........................... no

... 중략 ...

Qt Multimedia:
  ALSA ................................... no
  GStreamer 1.0 .......................... no
  GStreamer 0.10 ......................... no
  Video for Linux ........................ no
  OpenAL ................................. no
  PulseAudio ............................. no
  Resource Policy (libresourceqt5) ....... no
  Windows Audio Services ................. yes
  DirectShow ............................. yes
  Windows Media Foundation ............... yes
  Media player backend ................... Windows Media Foundation
Qt WebEngine:
  Embedded build ......................... no
  Pepper Plugins ......................... yes
  Printing and PDF ....................... yes
  Proprietary Codecs ..................... no
  Spellchecker ........................... yes
  Native Spellchecker .................... no
  WebRTC ................................. yes
  Use System Ninja ....................... no
  Geolocation ............................ yes
  Use v8 snapshot ........................ yes

Note: No wayland-egl support detected. Cross-toolkit compatibility disabled.

Qt is now configured for building. Just run 'nmake'.
Once everything is built, you must run 'nmake install'.
Qt will be installed into 'D:\OpenSource\Qt5.11.2.x64'.

Prior to reconfiguration, make sure you remove any leftovers from
the previous build.

만약 MySQL 부분이 활성화 안되어 환경설정 후 그 부분만 다시 체크되도록 하려면 config.cache 파일을 메모장에서 열어 아래와 같이 cache.mysql로 시작하는 라인을 전부 지우고 다시 configure하면 된다.

cache.mysql._KEYS_ = result msgs source sources.5.libs sources.5.includedir sources.5.cflags sources.5.version sources.5.export
cache.mysql.result = true
cache.mysql.msgs = "Trying source 0 (type mysqlConfig) of library mysql ..." "mysql_config not found." "  => source produced no result." "Trying source 1 (type mysqlConfig) of library mysql ..." "mysql_config not found." "  => source produced no result." "Trying source 2 (type mysqlConfig) of library mysql ..." "mysql_config not found." "  => source produced no result." "Trying source 3 (type mysqlConfig) of library mysql ..." "mysql_config not found." "  => source produced no result." "Trying source 4 (type inline) of library mysql ..." "  => source failed condition \'!config.win32\'." "Trying source 5 (type inline) of library mysql ..." "+ cd /d D:\\OpenSource\\Qt5.11.2.x86.build\\config.tests\\mysql && D:\\OpenSource\\Qt5.11.2.x86.build\\qtbase\\bin\\qmake.exe \"CONFIG -= qt debug_and_release app_bundle lib_bundle\" \"CONFIG += shared warn_off console single_arch\" \"LIBS += -llibmysql\" D:/OpenSource/Qt5.11.2.x86.build/config.tests/mysql" "+ cd /d D:\\OpenSource\\Qt5.11.2.x86.build\\config.tests\\mysql && set MAKEFLAGS=& nmake" "> Microsoft(R) Program Maintenance Utility ���� 14.16.27024.1" "> Copyright (c) Microsoft Corporation. All rights reserved." "> $$escape_expand(\\t)cl -c -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W0 -EHsc /Fdmysql.vc.pdb -DUNICODE -D_UNICODE -DWIN32 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -I. -ID:\\OpenSource\\qt-everywhere-src-5.11.2\\qtbase\\mkspecs\\win32-msvc -Fo @C:\\Users\\star\\AppData\\Local\\Temp\\nm8248.tmp" "> main.cpp" "> $$escape_expand(\\t)link /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE \"/MANIFESTDEPENDENCY:type=\'win32\' name=\'Microsoft.Windows.Common-Controls\' version=\'6.0.0.0\' publicKeyToken=\'6595b64144ccf1df\' language=\'*\' processorArchitecture=\'*\'\" /MANIFEST:embed /OUT:mysql.exe @C:\\Users\\star\\AppData\\Local\\Temp\\nm869F.tmp" " => source accepted."
cache.mysql.source = 5
cache.mysql.sources.5.libs = -llibmysql
cache.mysql.sources.5.includedir = 
cache.mysql.sources.5.cflags = 
cache.mysql.sources.5.version = 
cache.mysql.sources.5.export = 

6. 빌드
qt에서 제공하는 jom을 쓴다면 jom, 아니라면 nmake 명령으로 빌드. 주위할 점으로 시스템 로케일을 영어(미국)으로 하는게 좋다. 웹킷은 경고도 에러로 처리하고 이 편이 훨씬 깔끔하게 한번에 빌드된다.

7. 기타
귀차니즘 덕분에 이정도로 마무리. 더 자세한 내용은 이곳 참조.

Visual Studio 2017 Community의 프롬포트 도구모음 스크립트 버그

현재 2018년 4월 19일 겪어서 하루 삽질한 내용.

부스트 라이브러리 경로를 INCLUDE, LIB 환경변수에 설정하고 Qt Creator에서 아무리 들고볶아도(최신버전을 받아서 업데이트 포함) LIB변수는 변하는데 INCLUDE 변수는 전혀 변하지않고 환경변수 값이 반영 안되는 것이였다.

구글링도해보고 뭘 해봐도 다른건 되는데(CL, _CL_변수) 이게 안되어서 IDE에서 헤더를 인식 못하였다. 그렇게 오늘 수 시간을 삽질한 결과 답을 얻었다.

일단 문제의 스크립트 내용은 아래와같다.

1분만에 눈에 들어오는것이 있다면 매의눈이라고 할 수 있겠다. __tmpwinsdk_include 환경변수를 초기화하고 INCLUDE 변수 내용을 담고 그것을 다시 환경변수에 설정하고 __tmpwinsdk_include 변수를 비우는데… 문제는 INCLUDE 환경변수를 수정하는 라인에 있었다. 그쪽만 혼자 __tmp_include변수에 할당하고 그 변수는 그냥 쓰레기가 되어버렸다.

이건 스크립트 흐름으로 보아 분명 버그임에 틀림없으니… 일단 내가 바꿔서 사용해야겠다. -_-;; 이것때문에 오전부터 지금까지 네시간 넘게 내가 왜 삽질을 해야했을까… 암튼 이 포스팅은 이것으로 끝!

아래 스크린샷은 수정한 후의 “C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\vsdevcmd\core\winsdk.bat” 파일의 내용이다.

eclipse에서 spring, maven 사용시 ClassNotFoundException 및 LOC Header 등 에러 발생시 확인해볼 사항

오랜만에 스프링 사용해볼겸 boot를 써보았다.

이전엔 maven – update project를 해보면 Invalid LOC Header (bad signature) 문제가 발생하였다며 파일이름이 나타났기때문에 바로 찾아서 지운 후 update project를 하면 되었는데…
이번엔 war이나 jar파일로 패키징까지 다 되었지만 함께 패키징 된 jar 파일이 문제있어 예외가 발생하였다.
디버그 모드로 실행하면 예외가 발생하고 해당 예외의 객체 이름부분을 콘솔 출력에서 클릭하면 Break Point를 활성화 할 수 있어 ZipException을 등록해두었더니 아래와같이 스택에서 파일명을 확인할 수 있었다.

그리고 콘솔에서 해당 경로를 보면 항상 보이는 파일이 있다.

바로 sha1-in-progress 확장자를 가진 파일이다. jar파일을 지운 후 update project를하여 jar 파일이 다 받아지면 sha1-in-progress파일이 사라진다.

이런점을 활용하면 탐색기를 띄운 후 경로표시줄에 %userprofile%\.m2 를 넣은 다음 검색에 sha1-in-progress를 입력하면 아래와같이 죽죽 뜬다. (많이도 실패했네 -_-)

콘솔이 편하면 콘솔에서, 탐색기가 편하면 탐색기에서 해당 경로에서 jar 파일을 지운 후 update project를 한번 해주자.

jar 파일을 지우고 update project를 해서 jar 파일이 완전하게 받아져도 sha1-in-progress파일이 남는경우가있다. (아마 남는경우가 더 많은거같다.) 그냥 폴더를 지우는것도 깔끔한 방법이다.

P.S.
하… 전혀 힌트도 얻지 못할 콘솔 메시지… 다운로드가 도중에 끊기는건 대체 어느시대에 일어나는 일이란 말인가… 덕분에 하루 반나절을 구글링으로 -_-;;;
수년도 더 지난 이런 문제 이제 좀 알아서 sha1 해쉬를해서 안맞는 파일은 다운받는 메뉴 좀 넣어주지. -_-;;