2025년 6월 10일 화요일

sqlcipher community windows build with vs 2022

1. openssl 을 static 라이브러리 방식으로 빌드한다.

설치 경로 : D:\MyProjects\OpenSSL\build\Win64-static


2. tcl 을 설치한다.

설치 경로 : c:\tcl

tcl 빌드 및 설치 : tcl 소스코드 다운로드 후 아래 실행

call "%ProgramFiles%\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvarsall.bat" x64 && cd D:\MyProjects\Download\tcl9.0.1\win && nmake -f makefile.vc INSTALLDIR=C:\tcl release && nmake -f makefile.vc INSTALLDIR=C:\tcl install


3. sqlcipher 소스 코드를 다운 받는다.


4. x64 Native Tools Command Prompt for VS 2022 실행


5. 환경 변수 설정 및 Makefile.msc 수정

SET PATH=%PATH%;c:\tcl\bin

SET PLATFORM=x64


Makefile.msc 제일 상단에 아래와 같이 추가










SQLITE_TEMP_STORE=2


TCC = $(TCC) -DSQLITE_HAS_CODEC -I"D:\MyProjects\OpenSSL\build\Win64-static\include"


LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR) /LIBPATH:"D:\MyProjects\OpenSSL\build\Win64-static\lib"

LTLIBS = $(LTLIBS) libcrypto.lib libssl.lib ws2_32.lib shell32.lib advapi32.lib gdi32.lib user32.lib crypt32.lib kernel32.lib


출처 : https://www.domstamand.com/compiling-sqlcipher-sqlite-encrypted-for-windows-using-visual-studio-2022/


6. sqlite3.dll과 sqlite3.exe을 각각 아래와 같이 빌드한다.

nmake /f Makefile.msc sqlite3.dll USE_NATIVE_LIBPATHS=1 OPTS="-DSQLITE_HAS_CODEC -DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown -I\"D:\MyProjects\OpenSSL\build\Win64-static\include\""


nmake /f Makefile.msc sqlite3.exe USE_NATIVE_LIBPATHS=1 OPTS="-DSQLITE_HAS_CODEC -DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown -I\"D:\MyProjects\OpenSSL\build\Win64-static\include\""


* 아래와 같은 에러 발생 시 sqlite3.c 파일을 열어서 소스코드 제일 위에 아래 코드를 추가한다.


























sqlite3.c
sqlite3.c(109878): warning C4431: 형식 지정자가 없습니다. int로 가정합니다. 참고: C에서는 더 이상 기본 int를 지원하지 않 습니다.
sqlite3.c(109878): error C2061: 구문 오류: 식별자 'xoshiro_s'
sqlite3.c(109878): error C2059: 구문 오류: ';'
sqlite3.c(109878): error C2059: 구문 오류: '['
sqlite3.c(109880): error C2061: 구문 오류: 식별자 'xoshiro_rotl'
sqlite3.c(109880): error C2059: 구문 오류: ';'
sqlite3.c(109880): error C2059: 구문 오류: '<cv-qualifier>'
sqlite3.c(109884): error C2061: 구문 오류: 식별자 'xoshiro_next'
sqlite3.c(109884): error C2059: 구문 오류: ';'
sqlite3.c(109884): error C2059: 구문 오류: '<parameter-list>'
sqlite3.c(109901): warning C4431: 형식 지정자가 없습니다. int로 가정합니다. 참고: C에서는 더 이상 기본 int를 지원하지 않 습니다.
sqlite3.c(109901): error C2146: 구문 오류: ';'이(가) 'val' 식별자 앞에 없습니다.
sqlite3.c(109901): error C2065: 'val': 선언되지 않은 식별자입니다.
sqlite3.c(109904): error C2065: 'val': 선언되지 않은 식별자입니다.
sqlite3.c(109904): warning C4013: 'xoshiro_next'이(가) 정의되지 않았습니다. extern은 int형을 반환하는 것으로 간주합니다.
sqlite3.c(109905): error C2065: 'val': 선언되지 않은 식별자입니다.
sqlite3.c(109905): error C2065: 'val': 선언되지 않은 식별자입니다.
sqlite3.c(109906): error C2065: 'val': 선언되지 않은 식별자입니다.
sqlite3.c(110141): warning C4267: '함수': 'size_t'에서 'int'(으)로 변환하면서 데이터가 손실될 수 있습니다.
sqlite3.c(110145): warning C4267: '=': 'size_t'에서 'u32'(으)로 변환하면서 데이터가 손실될 수 있습니다.
sqlite3.c(110198): error C2065: 'xoshiro_s': 선언되지 않은 식별자입니다.
sqlite3.c(110198): warning C4312: '형식 캐스트': 'int'에서 더 큰 'void *'(으)로의 변환입니다.
sqlite3.c(110198): error C2065: 'xoshiro_s': 선언되지 않은 식별자입니다.
sqlite3.c(110208): warning C4267: '함수': 'size_t'에서 'int'(으)로 변환하면서 데이터가 손실될 수 있습니다.
NMAKE : fatal error U1077: 'cl -nologo -W4 -DINCLUDE_MSVC_H=1   -DSQLITE_OS_WIN=1 -I. -I. -I.\src -fp:precise -MT -DNDEBUG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -DSQLITE_THREADSAFE=1 -DSQLITE_THREAD_OVERRIDE_LOCK=-1  -DSQLITE_MAX_TRIGGER_DEPTH=100  -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_STMTVTAB=1 -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_BYTECODE_VTAB=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_ENABLE_MATH_FUNCTIONS  -DSQLITE_HAS_CODEC -DSQLCIPHER_CRYPTO_OPENSSL -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_EXTRA_INIT=sqlcipher_extra_init -DSQLITE_EXTRA_SHUTDOWN=sqlcipher_extra_shutdown -I"D:\MyProjects\OpenSSL\build\Win64-static\include" -O2 -Zi -Fosqlite3.lo -Fdsqlite3.pdb  -c sqlite3.c' : '0x2' 반환 코드입니다.
Stop.

D:\MyProjects\Download\sqlcipher>


sqlite3.c 제일 상단에 아래 코드 추가



2025년 5월 23일 금요일

리눅스 gstreamer 개발 라이브러리 설치

 sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

2025년 2월 26일 수요일

ffmpeg v4l2m2m 디코더 사용법

AVCodec* m_pCodec;
AVCodecContext* m_pCodecCtx;
...

// v4l2m2m 디코더 찾기
m_pCodec = (AVCodec*)avcodec_find_decoder_by_name("h264_v4l2m2m");

// 코덱 컨텍스트 할당
m_pCodecCtx = avcodec_alloc_context3(m_pCodec);

// 픽셀포멧, width, height 지정
m_pCodecCtx->pix_fmt = AV_PIX_FMT_NV12;
m_pCodecCtx->width = 1920;
m_pCodecCtx->height = 1080;

// 코덱 열기
avcodec_open2(m_pCodecCtx, m_pCodec, NULL);

// 디코딩
retLen = avcodec_send_packet(m_pCodecCtx, &m_avPacket);
if (retLen == 0) retLen = avcodec_receive_frame(m_pCodecCtx, frame);


* 디코더 찾기, 픽셀포멧/width/height 지정 외 일반 디코딩 방법과 동일

2024년 7월 11일 목요일

SDL2 리눅스 빌드

 ./configure --prefix=/oem/app/kimdh/DXMediaPlayer/build/SDL2-2.28.5/
make
make install

export SDL2_CONFIG=/oem/app/kimdh/DXMediaPlayer/build/SDL2-2.28.5/bin/sdl2-config

./configure --prefix=/oem/app/kimdh/DXMediaPlayer/build/SDL2_image-2.6.3/
make
make install

./configure --prefix=/oem/app/kimdh/DXMediaPlayer/build/SDL2_ttf-2.20.2/
make
make install

2024년 3월 26일 화요일

Avalonia Weston 지원 확인

X11 이 아닌 Weston(Wayland reference compositor) 에서 Avalonia 로 빌드한 프로그램이 실행가능함을 확인하였다. 

실행환경 : i.MX8 시리즈 CPU, Debian 11, Weston

sudo apt install xwayland => 반드시 설치
export DISPLAY=:0 => 환경변수에 추가








2024년 2월 28일 수요일

C++ 우측값 참조와 std::move 의 실제 동작 원리

 우측값 참조에 대해 검색해보면 보통 아래와 같이 설명한다.

1. 좌측값/우측값에 대한 설명
2. 좌측값 참조/우측값 참조에 대한 설명
3. std::move 를 통한 자원 이동에 대한 설명

설명을 읽어보고 대략적인 의미와 적용방법은 알 수 있었으나 실체적인 동작원리를 알 수 없었다.
예를 들어 std::move 를 사용하면 해당 변수를 좌측값->우측값 으로 변환한다 고 설명하는데 구체적인 설명은 보통 없다.

먼저 우측값 참조를 간단하게 설명하자면,

int a = 10;
int b = 20;
int&& c = a + b;

위와같은 코드가 있을때 마지막 줄에서 메모리 상에 어떤 일이 발생하는가하면
CPU가 a+b(30)를 계산한 후 해당 값을 임시 메모리 변수에 저장을 하게되고 우측값 참조변수 c가 이 메모리를 참조하게된다.
int c = a + b; 였으면 컴파일러에 따라 생성되지않거나 혹은 바로 사라질 임시 변수(우측값)를 해제하지 않고 c가 참조하게 함으로써 메모리에서 해제를 하지않게된다.
사실 int같은 기본타입에서는 별다른 사용 용도가 없으며 실제로는 클래스(구조체)에서 사용된다.

먼저 std::move 함수를 보자.
std::move(변수) 는 static_cast<변수타입&&>(변수) 와 같은 의미이다. 그러니까 그냥 우측값 참조형으로 타입 캐스팅을 하는것이지
실제로 메모리 상에 뭐가 이동하고 어쩌고 그런것과 아무 상관이 없다.

그리고 우측값 참조는 int 같은 기본형에서는 메모리 이동의 효과가 전혀 없다.(당연하게도)
아래 코드와 같이 클래스(구조체)인 경우에 우측값 참조를 받는 이동 생성자/이동 대입 연산자에 우측값 참조를 받아서
깊은 복사없이 포인터만 변경하게 해주는 것으로 그 용도가 전부이다.

 class MoveTest  
 {  
 private:  
   char* str = nullptr;  
   
 public:  
   MoveTest()  
   {  
     str = nullptr;  
   }  
   
   MoveTest(const char* str1)  
   {  
     int len = strlen(str1);  
     str = new char[len + 1];  
     strcpy_s(str, len+1, str1);  
   }  
   
   MoveTest(const MoveTest& lhs)  
   {  
     int len = strlen(lhs.str);  
     str = new char[len + 1];  
     strcpy_s(str, len+1, lhs.str);  
   }  
   
   // 이동 생성자  
   MoveTest(MoveTest&& rhs) noexcept : str(rhs.str)  
   {  
     rhs.str = nullptr;  
   }  
   
   MoveTest& operator=(const MoveTest& lhs)  
   {  
     int len = strlen(lhs.str);  
     str = new char[len + 1];  
     strcpy_s(str, len + 1, lhs.str);  
     return *this;  
   }  
   
   // 이동 대입 연산자  
   MoveTest& operator=(MoveTest&& rhs) noexcept  
   {  
     str = rhs.str;  
     rhs.str = nullptr;  
     return *this;  
   }  
   
   ~MoveTest()  
   {  
     delete[] str;  
   }  
 };  
위 코드에서 

MoveTest m1("abc");
MoveTest m2(std::move(m1)); // 이동 생성자 호출, m1->m2 로 이동
// MoveTest m2(static_cast<MoveTest&&>(m1)); 와 같음

MoveTest m3;
m3 = std::move(m2); // 이동 대입 연산자 호출, m2->m3 로 이동
// m3 = static_cast<MoveTest&&>(m2); 와 같음

와 같이 해당 이동 생성자/이동 대입 연산자를 호출하게되고 호출을 받은쪽은 포인터 이동을 하면 되는것이다.

그러면 왜 하필 굳이 std::move 를 통해 우측값 참조 타입으로 이 기능을 구현하는가?
그냥 위 코드에서 참조(const MoveTest& lhs)를 받는 복사 생성자와 대입 연산자에서도 처리가 가능할텐데 말이다.
몇 가지 이유가 있지만 제일 큰 이유는 자원이 이동한다는 것을 명시적으로 표현함으로써 표준을 정하고 혼란을 없애기 위함이다.
일반 복사 생성자/대입 연산자에서 이것을 처리하게 되면 실제 깊은 복사가 일어나야 하는 것인지 자원이동만 일어나야하는지 구분이 어렵기 때문이다.

2024년 2월 5일 월요일

윈도우 x265 빌드

* nasm 설치
nasm 설치 후 환경변수에 경로 추가 (https://www.nasm.us/) (구글에서 nasm download 검색)

* cmake 설치
구글에서 windows cmake 검색(https://cmake.org/download/)

* x265 소스 다운로드
git clone https://bitbucket.org/multicoreware/x265_git.git

* 32 비트 빌드
Visual Studio 메뉴에서 x86 Native Tools Command Prompt for VS 2022 실행

x265_git\build\vc15-x86 에서 아래실행
cmake -G "Visual Studio 17 2022" -T v143 -A Win32 ..\..\source && cmake-gui ..\..\source

cmake-gui 뜨면 아래 Configure 클릭

x265.sln VS2022 로 열어서 빌드하면 x265_git\build\vc15-x86\Release(Debug) 아래에 빌드 파일 생성됨

* 64 비트 빌드
Visual Studio 메뉴에서 x64 Native Tools Command Prompt for VS 2022 실행

x265_git\build\vc15-x86_64 에서 아래실행
cmake -G "Visual Studio 17 2022" -T v143 ..\..\source && cmake-gui ..\..\source

cmake-gui 뜨면 아래 Configure 클릭

x265.sln VS2022 로 열어서 빌드하면 x265_git\build\vc15-x86_64\Release(Debug) 아래에 빌드 파일 생성됨