Swift Package Manager에서 C++ 소스코드 빌드
최근 개인 앱을 개발하던 도중, iOS UnrarKit이라는 프레임워크가 SPM을 지원하지 않는 등의 불편한 점이 있어서 WinRar 홈페이지에서 Unrar 프로그램의 소스코드를 받아 빌드하고자 하였습니다.
Swift 5.9 이전
Unrar의 소스코드 구성은 아래와 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
UnRAR.vcxproj extinfo.hpp pathfn.cpp smallfn.cpp UnRARDll.vcxproj extract.cpp pathfn.hpp smallfn.hpp acknow.txt extract.hpp qopen.cpp strfn.cpp arccmt.cpp filcreat.cpp qopen.hpp strfn.hpp archive.cpp filcreat.hpp rar.cpp strlist.cpp archive.hpp file.cpp rar.hpp strlist.hpp arcread.cpp file.hpp rardefs.hpp suballoc.cpp array.hpp filefn.cpp rarlang.hpp suballoc.hpp blake2s.cpp filefn.hpp raros.hpp system.cpp blake2s.hpp filestr.cpp rarpch.cpp system.hpp blake2s_sse.cpp filestr.hpp rartypes.hpp threadmisc.cpp blake2sp.cpp find.cpp rarvm.cpp threadpool.cpp cmddata.cpp find.hpp rarvm.hpp threadpool.hpp cmddata.hpp getbits.cpp rawint.hpp timefn.cpp cmdfilter.cpp getbits.hpp rawread.cpp timefn.hpp cmdmix.cpp global.cpp rawread.hpp ui.cpp coder.cpp global.hpp rdwrfn.cpp ui.hpp coder.hpp hardlinks.cpp rdwrfn.hpp uicommon.cpp compress.hpp hash.cpp readme.txt uiconsole.cpp consio.cpp hash.hpp recvol.cpp uisilent.cpp consio.hpp headers.cpp recvol.hpp ulinks.cpp crc.cpp headers.hpp recvol3.cpp unicode.cpp crc.hpp headers5.hpp recvol5.cpp unicode.hpp crypt.cpp isnt.cpp resource.cpp unpack.cpp crypt.hpp isnt.hpp resource.hpp unpack.hpp crypt1.cpp license.txt rijndael.cpp unpack15.cpp crypt2.cpp list.cpp rijndael.hpp unpack20.cpp crypt3.cpp list.hpp rs.cpp unpack30.cpp crypt5.cpp loclang.hpp rs.hpp unpack50.cpp dll.cpp log.cpp rs16.cpp unpack50frag.cpp dll.def log.hpp rs16.hpp unpack50mt.cpp dll.hpp makefile scantree.cpp unpackinline.cpp dll.rc match.cpp scantree.hpp uowners.cpp dll_nocrypt.def match.hpp secpassword.cpp version.hpp encname.cpp model.cpp secpassword.hpp volume.cpp encname.hpp model.hpp sha1.cpp volume.hpp errhnd.cpp options.cpp sha1.hpp win32acl.cpp errhnd.hpp options.hpp sha256.cpp win32lnk.cpp extinfo.cpp os.hpp sha256.hpp win32stm.cpp |
빌드하기 위해 새로운 프로젝트를 만들고, 소스코드를 Source 아래에, 헤더는 그 아래의 Include 다이렉토리 아래에 둡니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
➜ ~ mkdir Unrar ➜ ~ cd Unrar ➜ swift package init Creating library package: Unrar Creating Package.swift Creating .gitignore Creating Sources/ Creating Sources/Unrar/Unrar.swift Creating Tests/ Creating Tests/UnrarTests/ Creating Tests/UnrarTests/UnrarTests.swift ➜ tree ├── Package.swift ├── Sources │ └── Unrar │ ├── arccmt.cpp │ ├── archive.cpp │ ├── arcread.cpp │ ├── blake2s.cpp │ ├── blake2s_sse.cpp │ ├── blake2sp.cpp │ ├── cmddata.cpp │ ├── cmdfilter.cpp │ ├── cmdmix.cpp │ ├── coder.cpp │ ├── consio.cpp │ ├── crc.cpp │ ├── crypt.cpp │ ├── crypt1.cpp │ ├── crypt2.cpp │ ├── crypt3.cpp │ ├── crypt5.cpp │ ├── dll.cpp │ ├── encname.cpp │ ├── errhnd.cpp │ ├── extinfo.cpp │ ├── extract.cpp │ ├── filcreat.cpp │ ├── file.cpp │ ├── filefn.cpp │ ├── filestr.cpp │ ├── find.cpp │ ├── getbits.cpp │ ├── global.cpp │ ├── hardlinks.cpp │ ├── hash.cpp │ ├── headers.cpp │ ├── include │ │ ├── archive.hpp │ │ ├── array.hpp │ │ ├── blake2s.hpp │ │ ├── cmddata.hpp │ │ ├── coder.hpp │ │ ├── compress.hpp │ │ ├── consio.hpp │ │ ├── crc.hpp │ │ ├── crypt.hpp │ │ ├── dll.hpp │ │ ├── encname.hpp │ │ ├── errhnd.hpp │ │ ├── extinfo.hpp │ │ ├── extract.hpp │ │ ├── filcreat.hpp │ │ ├── file.hpp │ │ ├── filefn.hpp │ │ ├── filestr.hpp │ │ ├── find.hpp │ │ ├── getbits.hpp │ │ ├── global.hpp │ │ ├── hash.hpp │ │ ├── headers.hpp │ │ ├── headers5.hpp │ │ ├── isnt.hpp │ │ ├── list.hpp │ │ ├── loclang.hpp │ │ ├── log.hpp │ │ ├── match.hpp │ │ ├── model.hpp │ │ ├── options.hpp │ │ ├── os.hpp │ │ ├── pathfn.hpp │ │ ├── qopen.hpp │ │ ├── rar.hpp │ │ ├── rardefs.hpp │ │ ├── rarlang.hpp │ │ ├── raros.hpp │ │ ├── rartypes.hpp │ │ ├── rarvm.hpp │ │ ├── rawint.hpp │ │ ├── rawread.hpp │ │ ├── rdwrfn.hpp │ │ ├── recvol.hpp │ │ ├── resource.hpp │ │ ├── rijndael.hpp │ │ ├── rs.hpp │ │ ├── rs16.hpp │ │ ├── scantree.hpp │ │ ├── secpassword.hpp │ │ ├── sha1.hpp │ │ ├── sha256.hpp │ │ ├── smallfn.hpp │ │ ├── strfn.hpp │ │ ├── strlist.hpp │ │ ├── suballoc.hpp │ │ ├── system.hpp │ │ ├── threadpool.hpp │ │ ├── timefn.hpp │ │ ├── ui.hpp │ │ ├── unicode.hpp │ │ ├── unpack.hpp │ │ ├── version.hpp │ │ └── volume.hpp │ ├── isnt.cpp │ ├── list.cpp │ ├── log.cpp │ ├── match.cpp │ ├── model.cpp │ ├── options.cpp │ ├── pathfn.cpp │ ├── qopen.cpp │ ├── rar.cpp │ ├── rarpch.cpp │ ├── rarvm.cpp │ ├── rawread.cpp │ ├── rdwrfn.cpp │ ├── recvol.cpp │ ├── recvol3.cpp │ ├── recvol5.cpp │ ├── resource.cpp │ ├── rijndael.cpp │ ├── rs.cpp │ ├── rs16.cpp │ ├── scantree.cpp │ ├── secpassword.cpp │ ├── sha1.cpp │ ├── sha256.cpp │ ├── smallfn.cpp │ ├── strfn.cpp │ ├── strlist.cpp │ ├── suballoc.cpp │ ├── system.cpp │ ├── threadmisc.cpp │ ├── threadpool.cpp │ ├── timefn.cpp │ ├── ui.cpp │ ├── uicommon.cpp │ ├── uiconsole.cpp │ ├── uisilent.cpp │ ├── ulinks.cpp │ ├── unicode.cpp │ ├── unpack.cpp │ ├── unpack15.cpp │ ├── unpack20.cpp │ ├── unpack30.cpp │ ├── unpack50.cpp │ ├── unpack50frag.cpp │ ├── unpack50mt.cpp │ ├── unpackinline.cpp │ ├── uowners.cpp │ ├── volume.cpp │ ├── win32acl.cpp │ ├── win32lnk.cpp │ └── win32stm.cpp └── Tests └── UnrarTests └── UnrarTests.swift ➜ Unrar swift build |
여러 경고와 오류들과 함게 빌드가 되지 않습니다. 😢 불필요한 파일은 exclude하고 c++ 표준 설정 등을 바꿔봅니다. 하지만 빌드되지 않습니다. 알고보니 아직 C++ 헤더는 지원 외였습니다. C 헤더를 작성해서 브릿징 해줄 필요가 있습니다. 다행이도 누군가가 먼저 작성해두신 헤더를 참고복붙하여 시도해봅니다. Include 다이렉토리에 C 헤더를 배치해 놓은 뒤에야 성공적으로 빌드되는 것을 확인할 수 있었습니다.
Swift 5.9 이후
Swift 5.9에서는 C++ 상호 호환성이 개선됩니다. 따라서 C++ 헤더를 빌드할 수 있습니다. 업데이트 후, Include 다이렉토리에서 C 헤더를 지우고, C++ 헤더를 배치해 놓은 이후에 별도 C 헤더 없이 잘 빌드 되는 것을 확인할 수 있었습니다.