├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── docs ├── index.md └── kor │ ├── appendix_install.md │ ├── getting_started.md │ ├── modules_p0.md │ ├── modules_p1.md │ ├── modules_p2.md │ ├── modules_p3.md │ └── modules_p4.md ├── examples ├── .clang-format ├── .gitignore ├── Makefile ├── ReadMe.md ├── modules_p1_1.cpp ├── modules_p1_2.cpp ├── modules_p1_3.cpp └── modules_p1_5.cpp ├── mkdocs.yml ├── requirements.txt └── scripts ├── build-vs2017-cmake-clang.bat ├── build-vs2019-cmake-clang.bat ├── install-cmake-3.sh ├── install-libcxx.sh ├── install-llvm.sh ├── setup-compilers-ubuntu.sh └── setup-llvm-ubuntu.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | # THIS IS ONLY FOR THE gitattributes REPOSITORY. 2 | # Handle line endings automatically for files detected as text 3 | # and leave all files detected as binary untouched. 4 | * text=auto 5 | 6 | # 7 | # The above will handle all files NOT found below 8 | # 9 | # These files are text and should be normalized (Convert crlf => lf) 10 | *.gitattributes text 11 | .gitignore text 12 | *.md text 13 | 14 | #sources 15 | *.c text 16 | *.cc text 17 | *.cxx text 18 | *.cpp text 19 | *.c++ text 20 | *.hpp text 21 | *.h text 22 | *.h++ text 23 | *.hh text 24 | 25 | # Compiled Object files 26 | *.slo binary 27 | *.lo binary 28 | *.o binary 29 | *.obj binary 30 | 31 | # Precompiled Headers 32 | *.gch binary 33 | *.pch binary 34 | 35 | # Compiled Dynamic libraries 36 | *.so binary 37 | *.dylib binary 38 | *.dll binary 39 | 40 | # Compiled Static libraries 41 | *.lai binary 42 | *.la binary 43 | *.a binary 44 | *.lib binary 45 | 46 | # Executables 47 | *.exe binary 48 | *.out binary 49 | *.app binary 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .vscode 3 | _site 4 | 5 | # Created by https://www.gitignore.io/api/xcode,linux,macos,cmake,bazel,gradle,windows,clion+all,visualstudio,visualstudiocode 6 | # Edit at https://www.gitignore.io/?templates=xcode,linux,macos,cmake,bazel,gradle,windows,clion+all,visualstudio,visualstudiocode 7 | 8 | ### Bazel ### 9 | # gitignore template for Bazel build system 10 | # website: https://bazel.build/ 11 | 12 | # Ignore all bazel-* symlinks. There is no full list since this can change 13 | # based on the name of the directory bazel is cloned into. 14 | /bazel-* 15 | 16 | ### CLion+all ### 17 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 18 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 19 | 20 | # User-specific stuff 21 | .idea/**/workspace.xml 22 | .idea/**/tasks.xml 23 | .idea/**/usage.statistics.xml 24 | .idea/**/dictionaries 25 | .idea/**/shelf 26 | 27 | # Generated files 28 | .idea/**/contentModel.xml 29 | 30 | # Sensitive or high-churn files 31 | .idea/**/dataSources/ 32 | .idea/**/dataSources.ids 33 | .idea/**/dataSources.local.xml 34 | .idea/**/sqlDataSources.xml 35 | .idea/**/dynamic.xml 36 | .idea/**/uiDesigner.xml 37 | .idea/**/dbnavigator.xml 38 | 39 | # Gradle 40 | .idea/**/gradle.xml 41 | .idea/**/libraries 42 | 43 | # Gradle and Maven with auto-import 44 | # When using Gradle or Maven with auto-import, you should exclude module files, 45 | # since they will be recreated, and may cause churn. Uncomment if using 46 | # auto-import. 47 | # .idea/modules.xml 48 | # .idea/*.iml 49 | # .idea/modules 50 | # *.iml 51 | # *.ipr 52 | 53 | # CMake 54 | cmake-build-*/ 55 | 56 | # Mongo Explorer plugin 57 | .idea/**/mongoSettings.xml 58 | 59 | # File-based project format 60 | *.iws 61 | 62 | # IntelliJ 63 | out/ 64 | 65 | # mpeltonen/sbt-idea plugin 66 | .idea_modules/ 67 | 68 | # JIRA plugin 69 | atlassian-ide-plugin.xml 70 | 71 | # Cursive Clojure plugin 72 | .idea/replstate.xml 73 | 74 | # Crashlytics plugin (for Android Studio and IntelliJ) 75 | com_crashlytics_export_strings.xml 76 | crashlytics.properties 77 | crashlytics-build.properties 78 | fabric.properties 79 | 80 | # Editor-based Rest Client 81 | .idea/httpRequests 82 | 83 | # Android studio 3.1+ serialized cache file 84 | .idea/caches/build_file_checksums.ser 85 | 86 | ### CLion+all Patch ### 87 | # Ignores the whole .idea folder and all .iml files 88 | # See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 89 | 90 | .idea/ 91 | 92 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 93 | 94 | *.iml 95 | modules.xml 96 | .idea/misc.xml 97 | *.ipr 98 | 99 | # Sonarlint plugin 100 | .idea/sonarlint 101 | 102 | ### CMake ### 103 | CMakeLists.txt.user 104 | CMakeCache.txt 105 | CMakeFiles 106 | CMakeScripts 107 | Testing 108 | Makefile 109 | cmake_install.cmake 110 | install_manifest.txt 111 | compile_commands.json 112 | CTestTestfile.cmake 113 | _deps 114 | 115 | ### CMake Patch ### 116 | # External projects 117 | *-prefix/ 118 | 119 | ### Linux ### 120 | *~ 121 | 122 | # temporary files which can be created if a process still has a handle open of a deleted file 123 | .fuse_hidden* 124 | 125 | # KDE directory preferences 126 | .directory 127 | 128 | # Linux trash folder which might appear on any partition or disk 129 | .Trash-* 130 | 131 | # .nfs files are created when an open file is removed but is still being accessed 132 | .nfs* 133 | 134 | ### macOS ### 135 | # General 136 | .DS_Store 137 | .AppleDouble 138 | .LSOverride 139 | 140 | # Icon must end with two \r 141 | Icon 142 | 143 | # Thumbnails 144 | ._* 145 | 146 | # Files that might appear in the root of a volume 147 | .DocumentRevisions-V100 148 | .fseventsd 149 | .Spotlight-V100 150 | .TemporaryItems 151 | .Trashes 152 | .VolumeIcon.icns 153 | .com.apple.timemachine.donotpresent 154 | 155 | # Directories potentially created on remote AFP share 156 | .AppleDB 157 | .AppleDesktop 158 | Network Trash Folder 159 | Temporary Items 160 | .apdisk 161 | 162 | ### VisualStudioCode ### 163 | .vscode/* 164 | !.vscode/settings.json 165 | !.vscode/tasks.json 166 | !.vscode/launch.json 167 | !.vscode/extensions.json 168 | 169 | ### VisualStudioCode Patch ### 170 | # Ignore all local history of files 171 | .history 172 | 173 | ### Windows ### 174 | # Windows thumbnail cache files 175 | Thumbs.db 176 | Thumbs.db:encryptable 177 | ehthumbs.db 178 | ehthumbs_vista.db 179 | 180 | # Dump file 181 | *.stackdump 182 | 183 | # Folder config file 184 | [Dd]esktop.ini 185 | 186 | # Recycle Bin used on file shares 187 | $RECYCLE.BIN/ 188 | 189 | # Windows Installer files 190 | *.cab 191 | *.msi 192 | *.msix 193 | *.msm 194 | *.msp 195 | 196 | # Windows shortcuts 197 | *.lnk 198 | 199 | ### Xcode ### 200 | # Xcode 201 | # 202 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 203 | 204 | ## User settings 205 | xcuserdata/ 206 | 207 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 208 | *.xcscmblueprint 209 | *.xccheckout 210 | 211 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 212 | build/ 213 | DerivedData/ 214 | *.moved-aside 215 | *.pbxuser 216 | !default.pbxuser 217 | *.mode1v3 218 | !default.mode1v3 219 | *.mode2v3 220 | !default.mode2v3 221 | *.perspectivev3 222 | !default.perspectivev3 223 | 224 | ## Xcode Patch 225 | *.xcodeproj/* 226 | !*.xcodeproj/project.pbxproj 227 | !*.xcodeproj/xcshareddata/ 228 | !*.xcworkspace/contents.xcworkspacedata 229 | /*.gcno 230 | 231 | ### Xcode Patch ### 232 | **/xcshareddata/WorkspaceSettings.xcsettings 233 | 234 | ### Gradle ### 235 | .gradle 236 | 237 | # Ignore Gradle GUI config 238 | gradle-app.setting 239 | 240 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 241 | !gradle-wrapper.jar 242 | 243 | # Cache of project 244 | .gradletasknamecache 245 | 246 | # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 247 | # gradle/wrapper/gradle-wrapper.properties 248 | 249 | ### Gradle Patch ### 250 | **/build/ 251 | 252 | ### VisualStudio ### 253 | ## Ignore Visual Studio temporary files, build results, and 254 | ## files generated by popular Visual Studio add-ons. 255 | ## 256 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 257 | 258 | # User-specific files 259 | *.rsuser 260 | *.suo 261 | *.user 262 | *.userosscache 263 | *.sln.docstates 264 | 265 | # User-specific files (MonoDevelop/Xamarin Studio) 266 | *.userprefs 267 | 268 | # Mono auto generated files 269 | mono_crash.* 270 | 271 | # Build results 272 | [Dd]ebug/ 273 | [Dd]ebugPublic/ 274 | [Rr]elease/ 275 | [Rr]eleases/ 276 | x64/ 277 | x86/ 278 | [Aa][Rr][Mm]/ 279 | [Aa][Rr][Mm]64/ 280 | bld/ 281 | [Bb]in/ 282 | [Oo]bj/ 283 | [Ll]og/ 284 | 285 | # Visual Studio 2015/2017 cache/options directory 286 | .vs/ 287 | # Uncomment if you have tasks that create the project's static files in wwwroot 288 | #wwwroot/ 289 | 290 | # Visual Studio 2017 auto generated files 291 | Generated\ Files/ 292 | 293 | # MSTest test Results 294 | [Tt]est[Rr]esult*/ 295 | [Bb]uild[Ll]og.* 296 | 297 | # NUnit 298 | *.VisualState.xml 299 | TestResult.xml 300 | nunit-*.xml 301 | 302 | # Build Results of an ATL Project 303 | [Dd]ebugPS/ 304 | [Rr]eleasePS/ 305 | dlldata.c 306 | 307 | # Benchmark Results 308 | BenchmarkDotNet.Artifacts/ 309 | 310 | # .NET Core 311 | project.lock.json 312 | project.fragment.lock.json 313 | artifacts/ 314 | 315 | # StyleCop 316 | StyleCopReport.xml 317 | 318 | # Files built by Visual Studio 319 | *_i.c 320 | *_p.c 321 | *_h.h 322 | *.ilk 323 | *.obj 324 | *.iobj 325 | *.pch 326 | *.pdb 327 | *.ipdb 328 | *.pgc 329 | *.pgd 330 | *.rsp 331 | *.sbr 332 | *.tlb 333 | *.tli 334 | *.tlh 335 | *.tmp 336 | *.tmp_proj 337 | *_wpftmp.csproj 338 | *.log 339 | *.vspscc 340 | *.vssscc 341 | .builds 342 | *.pidb 343 | *.svclog 344 | *.scc 345 | 346 | # Chutzpah Test files 347 | _Chutzpah* 348 | 349 | # Visual C++ cache files 350 | ipch/ 351 | *.aps 352 | *.ncb 353 | *.opendb 354 | *.opensdf 355 | *.sdf 356 | *.cachefile 357 | *.VC.db 358 | *.VC.VC.opendb 359 | 360 | # Visual Studio profiler 361 | *.psess 362 | *.vsp 363 | *.vspx 364 | *.sap 365 | 366 | # Visual Studio Trace Files 367 | *.e2e 368 | 369 | # TFS 2012 Local Workspace 370 | $tf/ 371 | 372 | # Guidance Automation Toolkit 373 | *.gpState 374 | 375 | # ReSharper is a .NET coding add-in 376 | _ReSharper*/ 377 | *.[Rr]e[Ss]harper 378 | *.DotSettings.user 379 | 380 | # JustCode is a .NET coding add-in 381 | .JustCode 382 | 383 | # TeamCity is a build add-in 384 | _TeamCity* 385 | 386 | # DotCover is a Code Coverage Tool 387 | *.dotCover 388 | 389 | # AxoCover is a Code Coverage Tool 390 | .axoCover/* 391 | !.axoCover/settings.json 392 | 393 | # Visual Studio code coverage results 394 | *.coverage 395 | *.coveragexml 396 | 397 | # NCrunch 398 | _NCrunch_* 399 | .*crunch*.local.xml 400 | nCrunchTemp_* 401 | 402 | # MightyMoose 403 | *.mm.* 404 | AutoTest.Net/ 405 | 406 | # Web workbench (sass) 407 | .sass-cache/ 408 | 409 | # Installshield output folder 410 | [Ee]xpress/ 411 | 412 | # DocProject is a documentation generator add-in 413 | DocProject/buildhelp/ 414 | DocProject/Help/*.HxT 415 | DocProject/Help/*.HxC 416 | DocProject/Help/*.hhc 417 | DocProject/Help/*.hhk 418 | DocProject/Help/*.hhp 419 | DocProject/Help/Html2 420 | DocProject/Help/html 421 | 422 | # Click-Once directory 423 | publish/ 424 | 425 | # Publish Web Output 426 | *.[Pp]ublish.xml 427 | *.azurePubxml 428 | # Note: Comment the next line if you want to checkin your web deploy settings, 429 | # but database connection strings (with potential passwords) will be unencrypted 430 | *.pubxml 431 | *.publishproj 432 | 433 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 434 | # checkin your Azure Web App publish settings, but sensitive information contained 435 | # in these scripts will be unencrypted 436 | PublishScripts/ 437 | 438 | # NuGet Packages 439 | *.nupkg 440 | # NuGet Symbol Packages 441 | *.snupkg 442 | # The packages folder can be ignored because of Package Restore 443 | **/[Pp]ackages/* 444 | # except build/, which is used as an MSBuild target. 445 | !**/[Pp]ackages/build/ 446 | # Uncomment if necessary however generally it will be regenerated when needed 447 | #!**/[Pp]ackages/repositories.config 448 | # NuGet v3's project.json files produces more ignorable files 449 | *.nuget.props 450 | *.nuget.targets 451 | 452 | # Microsoft Azure Build Output 453 | csx/ 454 | *.build.csdef 455 | 456 | # Microsoft Azure Emulator 457 | ecf/ 458 | rcf/ 459 | 460 | # Windows Store app package directories and files 461 | AppPackages/ 462 | BundleArtifacts/ 463 | Package.StoreAssociation.xml 464 | _pkginfo.txt 465 | *.appx 466 | *.appxbundle 467 | *.appxupload 468 | 469 | # Visual Studio cache files 470 | # files ending in .cache can be ignored 471 | *.[Cc]ache 472 | # but keep track of directories ending in .cache 473 | !?*.[Cc]ache/ 474 | 475 | # Others 476 | ClientBin/ 477 | ~$* 478 | *.dbmdl 479 | *.dbproj.schemaview 480 | *.jfm 481 | *.pfx 482 | *.publishsettings 483 | orleans.codegen.cs 484 | 485 | # Including strong name files can present a security risk 486 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 487 | #*.snk 488 | 489 | # Since there are multiple workflows, uncomment next line to ignore bower_components 490 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 491 | #bower_components/ 492 | 493 | # RIA/Silverlight projects 494 | Generated_Code/ 495 | 496 | # Backup & report files from converting an old project file 497 | # to a newer Visual Studio version. Backup files are not needed, 498 | # because we have git ;-) 499 | _UpgradeReport_Files/ 500 | Backup*/ 501 | UpgradeLog*.XML 502 | UpgradeLog*.htm 503 | ServiceFabricBackup/ 504 | *.rptproj.bak 505 | 506 | # SQL Server files 507 | *.mdf 508 | *.ldf 509 | *.ndf 510 | 511 | # Business Intelligence projects 512 | *.rdl.data 513 | *.bim.layout 514 | *.bim_*.settings 515 | *.rptproj.rsuser 516 | *- [Bb]ackup.rdl 517 | *- [Bb]ackup ([0-9]).rdl 518 | *- [Bb]ackup ([0-9][0-9]).rdl 519 | 520 | # Microsoft Fakes 521 | FakesAssemblies/ 522 | 523 | # GhostDoc plugin setting file 524 | *.GhostDoc.xml 525 | 526 | # Node.js Tools for Visual Studio 527 | .ntvs_analysis.dat 528 | node_modules/ 529 | 530 | # Visual Studio 6 build log 531 | *.plg 532 | 533 | # Visual Studio 6 workspace options file 534 | *.opt 535 | 536 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 537 | *.vbw 538 | 539 | # Visual Studio LightSwitch build output 540 | **/*.HTMLClient/GeneratedArtifacts 541 | **/*.DesktopClient/GeneratedArtifacts 542 | **/*.DesktopClient/ModelManifest.xml 543 | **/*.Server/GeneratedArtifacts 544 | **/*.Server/ModelManifest.xml 545 | _Pvt_Extensions 546 | 547 | # Paket dependency manager 548 | .paket/paket.exe 549 | paket-files/ 550 | 551 | # FAKE - F# Make 552 | .fake/ 553 | 554 | # CodeRush personal settings 555 | .cr/personal 556 | 557 | # Python Tools for Visual Studio (PTVS) 558 | __pycache__/ 559 | *.pyc 560 | 561 | # Cake - Uncomment if you are using it 562 | # tools/** 563 | # !tools/packages.config 564 | 565 | # Tabs Studio 566 | *.tss 567 | 568 | # Telerik's JustMock configuration file 569 | *.jmconfig 570 | 571 | # BizTalk build output 572 | *.btp.cs 573 | *.btm.cs 574 | *.odx.cs 575 | *.xsd.cs 576 | 577 | # OpenCover UI analysis results 578 | OpenCover/ 579 | 580 | # Azure Stream Analytics local run output 581 | ASALocalRun/ 582 | 583 | # MSBuild Binary and Structured Log 584 | *.binlog 585 | 586 | # NVidia Nsight GPU debugger configuration file 587 | *.nvuser 588 | 589 | # MFractors (Xamarin productivity tool) working folder 590 | .mfractor/ 591 | 592 | # Local History for Visual Studio 593 | .localhistory/ 594 | 595 | # BeatPulse healthcheck temp database 596 | healthchecksdb 597 | 598 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 599 | MigrationBackup/ 600 | 601 | # End of https://www.gitignore.io/api/xcode,linux,macos,cmake,bazel,gradle,windows,clion+all,visualstudio,visualstudiocode -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Note 3 | # Travis CI will update GitHub Pages 4 | # 5 | 6 | notifications: 7 | email: 8 | - luncliff@gmail.com 9 | 10 | os: linux 11 | dist: bionic 12 | 13 | addons: 14 | apt: 15 | update: true 16 | sources: 17 | - ubuntu-toolchain-r-test 18 | - sourceline: "deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" 19 | key_url: "https://apt.llvm.org/llvm-snapshot.gpg.key" 20 | packages: 21 | - tree 22 | - clang-9 23 | - g++-9 24 | 25 | language: python 26 | python: 27 | - "3.7" 28 | 29 | install: 30 | - pip install -r requirements.txt 31 | 32 | script: 33 | - mkdocs build 34 | 35 | deploy: 36 | - provider: pages 37 | github_token: ${MAINTAINER_GITHUB_TOKEN} 38 | local_dir: _site 39 | skip_cleanup: true 40 | keep_history: true 41 | on: 42 | branch: master 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2020 Chris Ohk, DongHa Park 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Modern C++ Next: Comprehensive Guide for C++20 2 | 3 | ## Purpose 4 | 5 | The intent of "Modern C++ Next" is to provide a comprehensive introduction to the relevant features regarding C++20 or earlier (if there's enough time). Readers can choose interesting content according to the following table of content to learn and quickly familiarize the new features you would like to learn. Readers should aware that all of these features are not required. It should be leart when you really need it. At the same time, instead of grammar-only, the book introduces the historical background as simple as possible of its technical requirements, which provides great help in understanding why these features comes out. 6 | 7 | We'll write this book in Korean and English and our goal of writing is July 2020. 8 | 9 | ## Targets 10 | 11 | This book assumes that readers are already familiar with modern C++ (i.e. C++11/14/17), at least they do not have any difficulty in reading modern C++ code. In other words, those who have long experience in modern C++ and people who desire to quickly understand the features of C++20 in a short period of time are well suited to read the book. 12 | 13 | ## Contents 14 | 15 | - [ ] Modules 16 | - [ ] Coroutines 17 | - [ ] Concepts 18 | - [ ] Ranges 19 | - [ ] Designated Initializer 20 | - [ ] Three-way Comparison 21 | - [ ] `consteval` 22 | - [ ] `std::format` 23 | - [ ] Calendar and time-zone additions to `` 24 | 25 | and so many more ... 26 | 27 | ## License 28 | 29 | 30 | 31 | All documents and source code files in this repo are licensed under the [MIT License](http://opensource.org/licenses/MIT): 32 | 33 | Copyright (c) 2019-2020 [Chris Ohk](http://www.github.com/utilForever), [DongHa Park](https://github.com/luncliff) 34 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | 2 | # Modern C++ Next 3 | 4 | ## Sections 5 | 6 | * C++ 20 [시작하기](./kor/getting_started.md) / Getting Started 7 | 8 | ### Core Features 9 | 10 | * Modules: [한국어](./kor/modules_p1.md) / English 11 | * Coroutines 12 | * Concepts 13 | 14 | ### Expression 15 | 16 | * Designated Initializer 17 | * Three-way Comparison 18 | * `consteval` 19 | 20 | ### Language Support Library 21 | 22 | * Ranges 23 | * `std::format` 24 | * Calendar and time-zone additions to `` 25 | 26 | ### Appendix 27 | 28 | * 설치 / Installation 29 | * [LLVM 프로젝트의 설치](./kor/appendix_install.md) 30 | * [Ubuntu 환경에서의 컴파일러 설치](./kor/appendix_install.md) 31 | * ... 32 | -------------------------------------------------------------------------------- /docs/kor/appendix_install.md: -------------------------------------------------------------------------------- 1 | 2 | ## LLVM 프로젝트(libc++, Clang ...) 3 | 4 | ### 설치방법 5 | 6 | You can remove the `clang` if you don't want to install it. 7 | Normally just `libcxx` and `libcxxabi` will be fine. 8 | 9 | ```bash hl_lines="8 19 23" 10 | #!/bin/bash 11 | branch=${1:-"master"} 12 | install_prefix=$(realpath ${2:-"/usr"}) 13 | provider="https://github.com/llvm-mirror" 14 | 15 | pushd /tmp 16 | # get the packages with specified version 17 | for repo in "llvm" "libcxx" "libcxxabi" "clang" 18 | do 19 | # download + unzip one by one 20 | uri="${provider}/${repo}/archive/${branch}.zip" 21 | wget -q -O "${repo}.zip" ${uri} 22 | unzip -u -q "${repo}.zip" 23 | mv "${repo}-${branch}" "${repo}" 24 | done 25 | 26 | mkdir -p llvm-build && pushd llvm-build 27 | cmake ../llvm \ 28 | -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;clang" \ 29 | -DCMAKE_INSTALL_PREFIX="${install_prefix}" 30 | 31 | # too many logs. make silent ... 32 | make -j4 install-clang 2>err-clang.txt 33 | make -j4 install-cxx 2>err-libcxx.txt 34 | make -j4 install-cxxabi 2>err-libcxxabi.txt 35 | popd # leave /tmp/llvm-build 36 | popd # leave /tmp 37 | ``` 38 | 39 | ## Ubuntu 환경에서의 컴파일러 설치 40 | 41 | > TBA 42 | -------------------------------------------------------------------------------- /docs/kor/getting_started.md: -------------------------------------------------------------------------------- 1 | 2 | # C++ 20 시작하기 3 | 4 | 이 페이지에서는 C++ 20을 사용하기 위해 필요한 것들에 대해 다룹니다. 5 | 6 | ### Minimal Executable Example 7 | 8 | 이 저장소의 **실행가능한 코드들은** 다음의 서비스들을 사용해서 용례를 보입니다. 9 | 10 | * https://wandbox.org/ 11 | * https://godbolt.org/ 12 | 13 | ### Platform 14 | 15 | 알려진 CI 서비스들에서 제공하는 환경들과 복잡한 절차 없이 설치 가능한 환경을 상정하였습니다. 16 | 17 | * Ubuntu Linux 18.04 x86_64 (4.4, 4.15) 18 | * Windows 10 x64 (10.0.18362) 19 | * ... 20 | 21 | > TODO: CI 서비스들의 MacOS 버전정보 확인 필요함 22 | 23 | ### Compiler 24 | 25 | 특별히 명시되지 않는한, 예제 코드들은 아래의 컴파일러들을 사용합니다. (2020년 1월 기준) 26 | 27 | * GCC 9.2.1 (20191102) 28 | * Clang 9.0.0 (20191211) 29 | * MSVC 19.24 x64 (v142, [Visual Studio 2019 16.4](https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes-history)) 30 | * AppleClang 11 ([XCode 11](https://developer.apple.com/documentation/xcode_release_notes/xcode_11_release_notes)) 31 | 32 | #### Standard Library 33 | 34 | * `libc++`/`libc++abi`의 버전은 컴파일러와 마찬가지로 [LLVM 의 배포 버전](http://releases.llvm.org/download.html)을 따릅니다. 35 | 36 | 37 | ### Build System 38 | 39 | 저자들이 사용한 빌드 관련 도구들의 버전은 다음과 같습니다. 40 | 41 | * GNU Make 4.1 42 | * CMake 3.12+ 43 | * `CXX_STANDARD`에 20을 설정 가능한 최소 버전 44 | * ... 45 | -------------------------------------------------------------------------------- /docs/kor/modules_p0.md: -------------------------------------------------------------------------------- 1 | # C++ Modules 2 | 3 | 아직 C++ Modules의 모든 내용을 시험해볼 수 있는 것은 아니지만, 대략적인 내용을 확인하는 것은 어렵지 않습니다. 4 | 5 | ### 준비 6 | 7 | * Clang 컴파일러 (LLVM 9.0+, AppleClang 11.0+) 8 | * [GNU Make](https://www.gnu.org/software/make/manual/make.html): http://wiki.kldp.org/KoreanDoc/html/GNU-Make/GNU-Make.html 9 | 10 | ## Overview 11 | 12 | ### Modules에서 해결하려는 문제는 무엇일까? (Why) 13 | 14 | #### 컴파일 속도 개선 15 | 16 | 컴파일 속도가 느려진 원인은 전처리 결과로 생성된 소스코드(Translation Unit)이 그만큼 커졌기 때문이다. 17 | 이러한 코드 증가는 전처리기(`#include`)에 의한 코드 복제가 널리 사용될수록 영향이 커진다. 18 | 19 | ### Modules의 접근법은 무엇일까? (What) 20 | 21 | #### 코드 복제의 대안(Alternative) 제시 22 | 23 | 전처리기를 사용해 소스코드를 복제했던 이유는 선언(Declaration)을 재사용하기 위함이었으므로, 24 | Modules에서는 소스코드 없이도 선언을 재사용할 수 있는 방법을 제공한다. 25 | 26 | ### Modules는 어떻게 사용할 수 있을까? (How) 27 | 28 | Modules의 목표(?)는 선언을 재사용할 수 있도록 하는 것이므로, 다음의 3가지를 지원한다. 29 | 30 | * 재사용할 수 있는 선언을 구분할 수 있어야 한다: `export` 31 | * 선언을 집단화 할 수 있어야 한다: `module` 32 | * 원하는 선언(혹은 그 집합)을 가져올 수 있어야 한다: `import` 33 | 34 | #### Module Unit 35 | 36 | * `module` 선언이 있으면 이후(Purview)의 선언들은 해당 module에 속한다. 37 | * `export module` 선언이 있으면 _Module Interface Unit_ 이 되며, 그 외에는 _Module Implementation Unit_ 이 된다. 38 | * 같은 module에서만 사용할 수 있는 unit을 _module partition_ 이라고 한다. 39 | 40 | #### Global Module 41 | 42 | * `module`선언이 없는 _Translation Unit_ 들은 Global Module Fragment에 속한다. 43 | * _Global Module_ 은 모든 Global Module Framgmentd의 집합이다. 44 | 45 | #### Reachability 46 | 47 | * 임의의 모듈을 `import`하면, 해당 모듈의 선언들과 그 선언들에 필요한 다른 모듈들의 선언을 사용할 수 있다(Reachable). 48 | 49 | ## References 50 | 51 | ### C++ Standard 52 | 53 | [N4835](https://github.com/cplusplus/draft/tree/master/papers)를 기반으로 작성되었습니다. [https://github.com/cplusplus/draft](https://github.com/cplusplus/draft) 에서 다른 문서를 확인하실 수 있습니다. 54 | 55 | * ... 56 | 57 | ### Web 58 | 59 | * https://stackoverflow.com/questions/33307657/how-do-i-use-c-modules-in-clang 60 | * https://vector-of-bool.github.io/2019/03/10/modules-1.html 61 | * https://vector-of-bool.github.io/2019/03/31/modules-2.html 62 | * https://vector-of-bool.github.io/2019/10/07/modules-3.html 63 | * https://quuxplusone.github.io/blog/2019/11/07/modular-hello-world/ 64 | 65 | ### Video 66 | 67 | * CppCon 2019: Gabriel Dos Reis ["Programming with C++ Modules: Guide for the Working"](https://www.youtube.com/watch?v=tjSuKOz5HK4) 68 | * ... 69 | 70 | -------------------------------------------------------------------------------- /docs/kor/modules_p1.md: -------------------------------------------------------------------------------- 1 | # C++ Modules 에서 해결하려는 문제 2 | 3 | 지금 설명하는 주제에 관심이 있는 분이라면 이미 알고 계시겠지만, 컴파일 언어인 C++에서 프로그램은 1개 이상의 소스코드 파일로 구성됩니다. 4 | 소스 코드란, 아래와 같이 C++ 문법에 맞춰 작성한 텍스트를 가리키는 것이구요. 5 | 6 | ```c++ 7 | /// @file examples/modules_p1_1.cpp 8 | #include 9 | 10 | int main(int argc, char* argv[]){ 11 | for(auto i = 0; i < argc; ++i) 12 | fputs(argv[i], stdout); 13 | return 0; 14 | } 15 | ``` 16 | 17 | ```bash 18 | clang -std=c++2a ./modules_p0_1.cpp 19 | ``` 20 | 21 | 위와 같이 컴파일러를 호출해서 프로그램을 만들 수 있습니다. 22 | 전통에 따라 a.out파일이 만들어질텐데요. 23 | 프로그램이란 (천공카드처럼) 일련의 비트이긴 하지만, 소스코드의 의미을 반영하여 Text와 Data로 그 영역이 구분되어 있습니다. 24 | 25 | ```console 26 | user@host:~/examples $ objdump -syms ./a.out 27 | 28 | ./a.out: file format Mach-O 64-bit x86-64 29 | 30 | SYMBOL TABLE: 31 | 0000000100002008 l O __DATA,__data __dyld_private 32 | 0000000100000000 g F __TEXT,__text __mh_execute_header 33 | 0000000100000f30 g F __TEXT,__text _main 34 | 0000000000000000 *UND* ___stdoutp 35 | 0000000000000000 *UND* _fputs 36 | 0000000000000000 *UND* dyld_stub_binder 37 | ``` 38 | 39 | 출력 내용을 보면 `a.out`만으로는 알 수 없는 부분도 있지만, 소스코드에 있었던 `main`, `fputs`, `stdout`이 모두 나타난 것을 볼 수 있습니다. (이름이 약간 다른 것 같지만 개의치 마세요!) 40 | 컴파일러가 프로그래머의 의도를 (아마도) 잘 해석했다는 것을 짐작할 수 있는 부분입니다. 41 | 42 | 방금 사용한 `-syms`옵션의 이름처럼, 프로그램은 비트로 만들어져있고, 비트 묶음에는 부호(symbol, 어떠한 뜻을 나타내기 위하여 정한 기호)가 부여됩니다. 부호에 담긴 의미로는 TEXT, DATA 등등이 있는 것이죠. 43 | 44 | 그리고 컴파일러가 그 부호를 만들기 위해 필요로 하는 것이 바로 선언(Declaration)입니다. 45 | C++ 코드를 구성하는 것 중 가장 많은 부분을 차지하는 부분이죠... 46 | 47 | ### 전처리 (Preprocessing) 48 | 49 | 그런데 소스코드마다 필요한 선언들을 작성하고, 이들의 정합(consistency)을 유지해주는 것은 상당히 번거롭기 때문에, 전처리기(Preprocessor)가 사용됩니다. 50 | `#include`와 같은 지시(directive)를 써서 파일의 내용을 복사-붙여넣기 한다거나, `#define`을 써서 특정 문자열을 치환하는 일을 합니다. 51 | 52 | 좀 전의 코드가 전처리기를 거치면 어떻게 되는지 바로 확인해보도록 하죠. (`-E` 옵션) 53 | 전처리기의 동작만 확인할 목적으로 파일을 만들기엔 번거로우니 Pipe를 써서(`|`) 표준 입력으로 소스코드를 제공해보겠습니다. (`-` 옵션) 54 | 좀 더 친절하게, 무슨 프로그래밍 언어인지도 알려주도록 하죠. (`-x c++` 옵션) 55 | 56 | 제 기억에 libc++에서 가장 간단한 헤더는 `<__nullptr>`였던 것 같습니다. 57 | 58 | ``` 59 | user@host:~/examples $ echo "#include <__nullptr>" | clang -x c++ -E - 60 | # 1 "" 61 | ... 62 | # 18 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__nullptr" 3 63 | 64 | namespace std { inline namespace __1 { 65 | 66 | struct __attribute__ ((__type_visibility__("default"))) nullptr_t 67 | { 68 | void* __lx; 69 | // ... 70 | }; 71 | 72 | inline __attribute__ ((__visibility__("hidden"))) __attribute__ ((internal_linkage)) nullptr_t __get_nullptr_t() {return nullptr_t(0);} 73 | 74 | } } 75 | # 2 "" 2 76 | ``` 77 | 78 | `std::nullptr_t`가 사실은 `struct`라는 것을 알게된 기쁨(?)은 제쳐두고, 전처리기가 코드를 잘 정리해서 하나의 소스파일로 만들어준다는 것을 알 수 있었습니다. 79 | C++ 에서는 위처럼 **전처리를 거친 소스파일을 Translation Unit이라 합니다**. (편의상 이후로는 TU라고 하겠습니다.) 80 | 즉, 이때부터 소스코드가 컴파일(Translation)이 되어 이진(binary) 형태로 바뀌는 것이죠. 81 | 82 | * 함께 보기: C++ Standard: 5. Lexical Conventions 83 | 84 | ### 전처리의 양면성 85 | 86 | #### 밝은 부분 87 | 88 | 전처리기를 사용해서 얻는 장점은 명확합니다. 89 | 90 | * 소스코드 재작성을 자동화: 선언을 모아놓은 파일(header)의 내용을 복사하도록 함으로써 다시 작성해줄 필요가 없음 91 | * 일률적임: header 파일은 일반적인 소스파일처럼 관리가 가능 92 | * 제어가 가능함: 소스파일을 변경하지 않으면서 TU를 변경할 수 있음(부분적인 활성화/비활성화 등) 93 | 94 | 헤더 파일을 사용하기 위해선 해당 파일을 찾기 위한 경로를 제공해야 하지만, `/usr/include`와 같이 묵시적으로 사용되는 경로라면 생략이 가능합니다. 컴파일러를 위한 복잡한 옵션이 필요하진 않은 것이죠. 95 | 무엇보다 소스파일 내에서서 읽을 수 있는 형태로 드러나기 때문에 프로그래머에게 주는 전달력 또한 상당하다는 점을 들 수 있습니다. 96 | 97 | 예컨대, 아래의 코드는 별다른 설명 없이도 그 내용을 짐작할 수 있습니다. 98 | 그 내용이란, 이 소스파일이 `openssl`이라는 라이브러리의 선언을 사용하며, 선언 중에 `SHA_CTX`, `SHA1_Init`등의 존재를 확인할 수 있다는 의미입니다. 99 | 100 | ```c++ 101 | #include // C++17 byte 102 | #include // C++11 array 103 | 104 | #include 105 | 106 | using namespace std; 107 | 108 | int digest_sha1(FILE* fin, 109 | array& digest){ 110 | SHA_CTX ctx{}; 111 | SHA1_Init(&ctx); 112 | 113 | auto& buffer = digest; // alias for readability 114 | while(auto count = fread(buffer.data(), buffer.size(), fin)) 115 | SHA1_Update(&ctx, buffer.data(), count); 116 | 117 | return SHA1_Final(digest.data(), &ctx); 118 | } 119 | ``` 120 | 121 | #### 어두운 부분 122 | 123 | 하지만 모든 프로그램이 위와 같이 단순하지는 않습니다. 어려움이 발생하는 근본적인 원인으로 2가지를 들 수 있는데, 124 | 첫째는 대부분의 프로젝트는 수많은 파일을 사용해 상당한 수의 TU를 생성한다는 것입니다. 125 | 126 | ... 127 | 결과적으로 소스코드의 양이 늘어나기 때문에 전체 컴파일 시간(즉, 빌드 시간)은 길어지게 될 것입니다. 128 | 129 | 두번째는 이 TU들의 컴파일 시점이 다를 수 있다는 것입니다. 130 | 다음과 같은 상황이 발생한다면 어떨까요? 131 | 132 | 1. 라이브러리를 개발할 때 의도한 헤더들의 include 순서는 A-B-C 였는데, 133 | 이를 사용하는 코드에서는 B-A-C 순서로 include 하도록 헤더를 수정하였다. 134 | 2. A 헤더에서 `#ifdef` 조건을 사용하고 있었는데, 135 | 새로 B 헤더가 그 앞에 include 되면서 조건이 반전되었다 (false 였다면 true로 변함. 혹은 그 반대) 136 | 137 | 위 두 상황이 시사하는 점은, 선언을 모아놓은 헤더 파일은 **변경될 수 있으며(mutable)**, 이것이 전처리기와 같이 **헤더파일에서 제어할 수 없는 요인에 의해 발생할 수 있다**는 것입니다. 138 | 139 | 전처리기의 장점을 되짚어보면 C++ 프로젝트의 규모가 커지고 의존성이 복잡해질 수록 이같은 문제로 인한 위험이 더 커진다는 것을 예상할 수 있습니다. 140 | 물론 오늘날 많은 C++ 라이브러리들은 이 문제를 위한 최소한의 방어법을 적용하고 있습니다. 141 | 142 | 매크로를 `constexpr` 혹은 `if constexpr`로 대체하면서 전처리기 의존을 낮추고, 사용하게 되더라도 매크로 조건이 충돌하거나 의도한 범위를 넘어서 영향을 주지않도록(`#undef`) 설계하며, 미리 정해진 순서로 부분 헤더파일을 include하는 헤더파일을 제공하기도 합니다. 143 | 하지만 전처리기에 의존하는 이상 이런 문제들은 계속 발생할 수 밖에 없기 때문에 복잡성은 계속 증가하게 됩니다. 144 | -------------------------------------------------------------------------------- /docs/kor/modules_p2.md: -------------------------------------------------------------------------------- 1 | # C++ Modules의 접근법 2 | 3 | `#include`를 사용해왔던 이유를 분명히하자면, 전방 선언 때문입니다. 즉, 하나의 선언을 위해선 다른 선언이 필요하고, 4 | 이를 위해 필요한 선언을 재작성하는 일은 전처리기를 통한 코드 복제로 대신하고 있었던 것이니까요. 5 | 6 | Modules의 접근법은 이렇습니다. **하나의 TU를 미리 컴파일하여, 이로부터 선언(Declaration)을 얻는다**. 7 | 이 방법이 가져오는 효과는 2가지 입니다. 8 | 9 | 1. 소스 파일을 노출하지 않기 때문에 변경이 불가능하다 10 | 2. 컴파일을 거치기 때문에 **컴파일 시점의 전처리 결과를 반영한다** 11 | 12 | TU는 전처리기를 거친 것이라고 서두에서 설명드렸던 것을 기억하시나요? 13 | 결국 전처리 과정에서 (주요 선언을 포함한) 소스코드가 변경될 수 있다는 것, 변경이 발생하는 것은 미래 시점이기에 제어할 수 없다는 것이 현재까지의 컴파일 과정에서 문제가 끊이지 않는 원인이라는 것입니다. 14 | 15 | -------------------------------------------------------------------------------- /docs/kor/modules_p3.md: -------------------------------------------------------------------------------- 1 | # C++ Modules의 사용법 - 1 2 | 3 | 사용법을 다루면서 용어도 같이 짚고 넘어가야 할 것 같습니다. 4 | 5 | ## Module Unit 6 | 7 | ### Module Interface Unit 8 | 9 | 모듈을 만들고 사용하는 것은 먼저 모듈이 노출하는(`export`) 선언들이 모여있는 하나의 TU를 작성하여 컴파일하는 것으로 시작합니다. 10 | 이를 _Module Interface Unit_ 이라고 합니다. 11 | MIU의 작성방법은 굉장히 간단한데, 그저 `export module m1;`를 선언하면, 그 이후의 내용은 전부 `m1`에 귀속됩니다. 이렇게 **암묵적으로** 선언이 귀속되는 범위를 모듈의 _Purview_ 라고 합니다. 12 | 13 | 예를 들어, 아래 코드의 경우, `endpoint_t`와 `lookup`은 `m1`의 범위(Purview)에 있는 것이죠. 14 | 따라서 이 선언들을 사용하려면 `m1`을 `import` 해야만 합니다. 15 | 16 | ```c++ 17 | /// @file examples/modules_p1_2.cpp 18 | /// @see https://en.cppreference.com/w/cpp/preprocessor/replace 19 | #if not defined(__cpp_modules) 20 | #warning "'__cpp_modules' not defined" 21 | #endif 22 | #include 23 | export module m1; // all following declarations will be in `m1` 24 | 25 | export struct endpoint_t { 26 | uint32_t _u32[4]; 27 | }; 28 | 29 | export uint16_t lookup(endpoint_t* base, uint16_t capacity, // 30 | const char* hostname, // 31 | const char* servname) noexcept; 32 | ``` 33 | 34 | 모듈의 다른 소스코드를 컴파일하고, 최종적으로 라이브러리 혹은 실행파일을 만들기 위해선 위와 같은 MIU를 먼저 컴파일(precompile) 해야 합니다. 35 | 36 | Clang의 경우, 아래와 같이 수행할 수 있습니다. 37 | 38 | ```console 39 | user@host:~/examples $ clang -x c++-module -std=c++2a -fmodules-ts --precompile -o m1.ifc ./modules_p1_2.cpp 40 | ./modules_p1_2.cpp:4:2: warning: "'__cpp_modules' not 41 | defined" [-W#warnings] 42 | #warning "'__cpp_modules' not defined" 43 | ^ 44 | 1 warning generated. 45 | ``` 46 | 47 | Makefile로 작성한다면 이런 형태가 되겠지요. 48 | 49 | ```makefile 50 | CXXFLAGS = -std=c++2a -fmodules-ts 51 | 52 | m1.ifc: modules_p1_2.cpp 53 | clang $(CXXFLAGS) -x c++-module \ 54 | --precompile -o m1.ifc $? 55 | ``` 56 | 57 | `.ifc` 이라는 확장자는 예약된 것은 아닙니다. 당장은 미리 컴파일된 파일을 위한 임의의 확장자가 있다고 생각하시면 되겠습니다. 58 | 아마 이 파일의 규격화(즉, 컴파일러 종속적이지 않은 ifc 파일)는 C++ 20 이후 다소 시간이 지난 후에야 이루어질 수 있을 것입니다. 59 | 60 | > 61 | > todo: 62 | > * 컴파일러 별 확장자 목록 63 | > 64 | 65 | 현재로써는 이 파일 안에 어떤 선언들이 들어있는지 확인하는 방법이 없습니다. 하지만 실제로 사용해보면 적법한(valid) 내용이 있는지 확인하는 것은 가능합니다. 66 | 67 | 1. 구현 코드(module)를 작성해본다 68 | 2. 사용 코드(import)를 작성해본다 69 | 70 | ### Module Implementation Unit 71 | 72 | `export` 선언은 MIU에서만 가능하기 때문에, `module m1`의 구현파일들에서는 따로 `export` 키워드를 사용할 일은 없습니다. 73 | 단지 `m1`의 범위안에서 구현을 제공하기만 하면 됩니다. 74 | 범위를 바꾸는 것은 아래 코드처럼 `module m1;`를 선언하는 것으로 충분합니다. 75 | 76 | ```c++ 77 | /// @file examples/module_p1_3.cpp 78 | #include 79 | module m1; // `endpoint_t` becomes visible 80 | // since it's purview of `m1` 81 | 82 | uint16_t lookup(endpoint_t* base, uint16_t capacity, // 83 | const char* hostname, // 84 | const char* servname) noexcept { 85 | return 0; 86 | } 87 | ``` 88 | 89 | 이 TU에는 `endpoint_t`에 대한 선언이 없지만, `m1`의 범위에 있기 때문에 컴파일이 가능합니다. 이를 Reachable 하다고 표현합니다. 90 | 이는 선언(Declaration)에 대한 것이므로, Linking 과정에서 Symbol에 대한 접근을 제어하는 `-fvisibility`옵션과는 다르다는 점을 숙지할 필요가 있습니다. 91 | 92 | 모듈 구현 유닛을 위한 컴파일 명령은 일반적인 C++ 소스코드와 유사합니다. 93 | 다만, 새로 2개의 옵션을 지정해줄 필요가 있습니다. 94 | 95 | * `-fprebuilt-module-path`: .ifc 파일을 찾기 위한 폴더 지정 (선택적) 96 | * `-fmodule-file`: 현재 구현중인 모듈의 .ifc 파일 이름 (필수) 97 | 98 | ```makefile 99 | CXXFLAGS = -std=c++2a -fmodules-ts 100 | # ... 101 | m1_impl_1.o: modules_p1_3.cpp 102 | clang $(CXXFLAGS) \ 103 | -fprebuilt-module-path=/usr/local/include \ 104 | -fprebuilt-module-path=. \ 105 | -fmodule-file=m1.ifc -o m1_impl_1.o -c $? 106 | ``` 107 | 108 | 명령을 보면 `-fprebuilt-module-path`는 헤더를 찾을 수 있도록 `-I`옵션을 제공했던 것과 유사합니다. 109 | 컴파일 방법을 알았으니, `mi_impl_1.o`파일에서 symbol을 확인해볼 수 있겠군요. 110 | 111 | ```console 112 | ~/examples $ make m1_impl_1.o 113 | clang -std=c++2a -fmodules-ts \ 114 | -fprebuilt-module-path=/usr/local/include \ 115 | -fprebuilt-module-path=. \ 116 | -fmodule-file=m1.ifc -o m1_impl_1.o -c modules_p1_3.cpp 117 | ~/examples $ luncliff$ nm --demangle ./m1_impl_1.o 118 | 0000000000000000 T lookup(endpoint_t*, unsigned short, char const*, char const*) 119 | ``` 120 | 121 | > 122 | > * Q. `-fmodule-file`을 생략하고 컴파일 해보세요! (컴파일 옵션) 123 | > * Q. 소스 코드에서 `module m1;`을 생략한 뒤에 컴파일 오류를 확인하세요! (purview 이해하기) 124 | > * Q. 소스 코드에서 `module m1;`의 위치를 `lookup`함수의 정의보다 아래쪽에 배치하고 컴파일 오류를 확인하세요! (purview 이해하기) 125 | > 126 | 127 | ## Module Import 128 | 129 | 앞선 예제로 확인하셨겠지만, 모듈을 사용하기 시작한다고 해서 헤더파일(즉, 전처리기에 의한 `#include`)를 사용할 수 없게 되는 것은 아닙니다. 130 | 다만 컴파일된 모듈 인터페이스가 있다면, `import` 하는 것이 가능하다는 것이죠. 131 | 132 | ```c++ 133 | /// @file examples/modules_p1_5.cpp 134 | #include 135 | #include 136 | import m1; 137 | 138 | std::array endpoints{}; 139 | 140 | int main(int, char*[]) { 141 | auto count = lookup(endpoints.data(), endpoints.size(), // 142 | "releases.llvm.org", "https"); 143 | 144 | std::cout << count << std::endl; 145 | for (auto i = 0u; i < count; ++i) { 146 | endpoints[i]; 147 | } 148 | return count > 0 ? EXIT_SUCCESS : EXIT_FAILURE; 149 | } 150 | ``` 151 | 152 | [헤더파일들이 지원하기만 한다면, 헤더파일을 `import`하는 것이 가능합니다](https://youtu.be/tjSuKOz5HK4?t=2286). 153 | `#include`가 코드의 복제인데 반해, `import`는 헤더파일 안에 있는 코드를 한번 처리하여, 그 중간결과물을 다른 TU의 import에서 재사용합니다. 154 | 결과적으로 처리 시간이 좀 더 줄어들게 되겠죠. (안타깝게도 아직은 지원되지 않습니다.) 155 | 156 | ```c++ 157 | import ; 158 | import ; 159 | import m1; 160 | // ... 161 | ``` 162 | 163 | 앞서 만들어놓은 `m1`의 구현 object와 함께 빌드하는 것은 아래처럼 할 수 있습니다. (편의상 `-fprebuilt-module-path`를 생략하였습니다.) 164 | 165 | ```makefile 166 | LDFLAGS = -lc++ 167 | CXXFLAGS = -std=c++2a -fmodules-ts 168 | # ... 169 | m1_usage: m1_impl_1.o modules_p1_5.cpp 170 | clang $(CXXFLAGS) $(LDFLAGS) \ 171 | -fmodule-file=m1.ifc $? 172 | ``` 173 | 174 | ```console 175 | user@host:~/examples $ make m1_usage 176 | clang -std=c++2a -fmodules-ts -lc++ \ 177 | -fmodule-file=m1.ifc m1_impl_1.o modules_p1_5.cpp 178 | user@host:~/examples $ nm --demangle ./a.out 179 | 0000000100000f6c s GCC_except_table6 180 | U __Unwind_Resume 181 | 0000000100000bf0 T lookup(endpoint_t*, unsigned short, char const*, char const*) 182 | ... 183 | 0000000100000c20 T _main 184 | ... 185 | ``` 186 | 187 | > TBA 188 | -------------------------------------------------------------------------------- /docs/kor/modules_p4.md: -------------------------------------------------------------------------------- 1 | # C++ Modules의 사용법 - 2 2 | 3 | > TBA 4 | 5 | ## Global Module 6 | 7 | 기존 코드와의 호환성 8 | 9 | ### Global Module Fragment 10 | 11 | Purview 개념을 더 이해할 수 있기 위한 내용 12 | 13 | #### Examples, Bad 14 | 15 | * 실패 Case 16 | * ... 17 | 18 | ## Linkage of Module 19 | 20 | 모듈내 선언들의 링킹 제약조건 21 | 22 | #### Examples, Bad 23 | 24 | * 실패 Case 25 | * ... 26 | 27 | 28 | ## Module Unit 29 | 30 | 아직 실험할 수 없지만 Standard 에는 존재하는 부분 31 | 32 | ### Module Partition 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | Language: Cpp 3 | Standard: Cpp11 4 | 5 | UseTab: Never 6 | IndentWidth: 4 7 | ColumnLimit: 80 8 | PointerAlignment: Left 9 | 10 | AlignTrailingComments: true 11 | AllowShortFunctionsOnASingleLine: false 12 | AllowShortIfStatementsOnASingleLine: false 13 | AllowShortLoopsOnASingleLine: false 14 | AlwaysBreakTemplateDeclarations: true 15 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/utilForever/modern-cpp-next/5f0cd71613f7b27462796aeeeb69c2ed9fb7b139/examples/.gitignore -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | LDFLAGS = -lc++ 2 | CXXFLAGS = -std=c++2a -fmodules-ts 3 | 4 | m1.ifc: modules_p1_2.cpp 5 | clang $(CXXFLAGS) -x c++-module \ 6 | --precompile -o m1.ifc $? 7 | 8 | m1_impl_1.o: m1.ifc modules_p1_3.cpp 9 | clang $(CXXFLAGS) \ 10 | -fprebuilt-module-path=/usr/local/include \ 11 | -fprebuilt-module-path=. \ 12 | -fmodule-file=m1.ifc -o m1_impl_1.o -c modules_p1_3.cpp 13 | 14 | m1_usage: m1_impl_1.o modules_p1_5.cpp 15 | clang $(CXXFLAGS) $(LDFLAGS) \ 16 | -fmodule-file=m1.ifc $? 17 | 18 | 19 | -------------------------------------------------------------------------------- /examples/ReadMe.md: -------------------------------------------------------------------------------- 1 | ### References 2 | 3 | * https://stackoverflow.com/questions/33307657/how-do-i-use-c-modules-in-clang 4 | * https://vector-of-bool.github.io/2019/03/10/modules-1.html 5 | * https://vector-of-bool.github.io/2019/03/31/modules-2.html 6 | * https://vector-of-bool.github.io/2019/10/07/modules-3.html 7 | * https://quuxplusone.github.io/blog/2019/11/07/modular-hello-world/ 8 | 9 | 10 | ## Note 11 | 12 | ### Clang 13 | 14 | * Version: 9.0.0+ 15 | 16 | #### module partitions are not yet supported 17 | 18 | Given 19 | 20 | ```cpp 21 | // module_part_1.cpp 22 | module; 23 | #include 24 | 25 | // change to next's purview 26 | module next:impl; 27 | ``` 28 | 29 | When 30 | 31 | ```makefile 32 | CFLAGS = -std=c++2a -fmodules-ts 33 | LDFLAGS = -lstdc++ 34 | 35 | next_part_1: module_part_1.cpp 36 | clang-9 -o module_part_1.o $(CFLAGS) $(LDFLAGS) \ 37 | -c $? 38 | ``` 39 | 40 | Then 41 | 42 | ```console 43 | user@host:~/examples$ make next_part_1 44 | clang-9 -o module_part_1.o -std=c++2a -fmodules-ts -lstdc++ \ 45 | -c module_part_1.cpp 46 | clang: warning: -Z-reserved-lib-stdc++: 'linker' input unused [-Wunused-command-line-argument] 47 | module_part_1.cpp:6:12: error: sorry, module partitions are not yet supported 48 | module next:impl; 49 | ^~~~~ 50 | module_part_1.cpp:6:1: error: definition of module 'next' is not available; use -fmodule-file= to specify path to precompiled module interface 51 | module next:impl; 52 | ^ 53 | 2 errors generated. 54 | Makefile:9: recipe for target 'next_part_1' failed 55 | make: *** [next_part_1] Error 1 56 | ``` 57 | 58 | #### definition of module 'next' is not available 59 | 60 | Given 61 | 62 | ```cpp 63 | // module_part_1.cpp 64 | module; // implement in global module fragment 65 | #include 66 | 67 | #include 68 | #include 69 | 70 | auto make_system_error(uint32_t ec) noexcept -> std::system_error { 71 | const auto code = static_cast(ec); 72 | const auto msg = ::gai_strerror(ec); 73 | return {code, std::system_category(), msg}; 74 | } 75 | 76 | uint32_t lookup(const addrinfo& hint, // 77 | const char* name, const char* serv) noexcept { 78 | addrinfo* list = nullptr; 79 | if (auto ec = ::getaddrinfo(name, serv, &hint, &list)) 80 | return ec; 81 | ::freeaddrinfo(list); 82 | for (addrinfo* it = list; it != nullptr; it = it->ai_next) { 83 | // ... 84 | } 85 | return 0; 86 | } 87 | 88 | module next; // change to next's purview 89 | 90 | // nothing 91 | ``` 92 | 93 | When 94 | 95 | ```makefile 96 | CFLAGS = -std=c++2a -fmodules-ts 97 | LDFLAGS = -lstdc++ 98 | 99 | next_impl_1: module_impl_1.cpp 100 | clang-9 -o next_impl.o $(CFLAGS) $(LDFLAGS) \ 101 | -c $? 102 | ``` 103 | 104 | Then 105 | 106 | ```console 107 | user@host:~/examples$ make next_impl_1 108 | clang-9 -o next_impl.o -std=c++2a -fmodules-ts -lstdc++ \ 109 | -c module_impl_1.cpp 110 | clang: warning: -Z-reserved-lib-stdc++: 'linker' input unused [-Wunused-command-line-argument] 111 | module_impl_1.cpp:44:1: error: definition of module 'next' is not available; use -fmodule-file= to specify path to precompiled module interface 112 | module next; 113 | ^ 114 | 1 error generated. 115 | Makefile:13: recipe for target 'next_impl_1' failed 116 | make: *** [next_impl_1] Error 1 117 | ``` 118 | 119 | #### successful 120 | 121 | Given 122 | 123 | ```cpp 124 | // module_ifc.cpp 125 | 126 | /// @see https://en.cppreference.com/w/cpp/preprocessor/replace 127 | #if not defined(__cpp_modules) 128 | #warning "'__cpp_modules' not defined" 129 | #endif 130 | 131 | export module next; 132 | 133 | #include 134 | 135 | /** 136 | * @brief IP v6 address. 128 bit 137 | */ 138 | export union address_t final { 139 | uint8_t _u8[16]; 140 | uint16_t _u16[8]; 141 | uint32_t _u32[4]; 142 | }; 143 | 144 | /** 145 | * @brief IP v6 address + port : 28 byte 146 | * Values are stored in Host Byte order. 147 | * 148 | * @see https://tools.ietf.org/html/rfc5952 149 | */ 150 | export struct endpoint_t final { 151 | uint16_t family; // AF_INET6. 152 | uint16_t port; // Transport level port number. 153 | uint32_t flowinfo; // IPv6 flow information. 154 | address_t addr; // IPv6 address. 155 | uint32_t scope_id; // Set of interfaces for a scope. 156 | }; 157 | 158 | export uint32_t lookup(endpoint_t* base, uint16_t count, // 159 | const char* hostname, // 160 | const char* servname) noexcept; 161 | 162 | ``` 163 | 164 | ```cpp 165 | // module_impl_2.cpp 166 | module; // implement in global module fragment 167 | 168 | #include 169 | #include 170 | #include 171 | #include 172 | 173 | uint32_t lookup(const addrinfo& hint, // 174 | const char* name, const char* serv) noexcept { 175 | addrinfo* list = nullptr; 176 | if (auto ec = ::getaddrinfo(name, serv, &hint, &list)) { 177 | ::gai_strerror(ec); 178 | return ec; 179 | } 180 | ::freeaddrinfo(list); 181 | for (addrinfo* it = list; it != nullptr; it = it->ai_next) { 182 | // ... 183 | } 184 | return 0; 185 | } 186 | 187 | // change to next's purview 188 | module next; 189 | 190 | uint32_t lookup(endpoint_t* base, uint16_t count, // 191 | const char* hostname, const char* servname) noexcept { 192 | addrinfo hint{}; 193 | return lookup(hint, hostname, servname); 194 | } 195 | 196 | ``` 197 | 198 | 199 | When 200 | 201 | ```makefile 202 | CFLAGS = -std=c++2a -fmodules-ts 203 | LDFLAGS = -lstdc++ 204 | 205 | next.pcm: 206 | clang-9 -o $@ $(LDFLAGS) $(CFLAGS) \ 207 | --precompile -x c++-module module_ifc.cpp 208 | 209 | next_impl_2: module_impl_2.cpp 210 | make next.pcm 211 | clang-9 $(CFLAGS) $(LDFLAGS) \ 212 | -fmodule-file=next.pcm \ 213 | -o next_impl_2.o -c $? 214 | nm ./next_impl_2.o 215 | 216 | clang-9 $(CFLAGS) $(LDFLAGS) \ 217 | -o main.o -c main.cpp \ 218 | -fprebuilt-module-path=. \ 219 | -fmodule-file=next.pcm 220 | clang-9 $(CFLAGS) $(LDFLAGS) \ 221 | -o main main.o next_impl_2.o 222 | nm --demangle ./main | grep endpoint_t 223 | ``` 224 | 225 | Then 226 | 227 | ```console 228 | user@host:~/examples$ make next_impl_2 229 | make next.pcm 230 | make[1]: Entering directory '/mnt/c/Users/luncl/source/modern-cpp-next/examples' 231 | clang-9 -lstdc++ -std=c++2a -fmodules-ts \ 232 | -o next.pcm \ 233 | --precompile -x c++-module module_ifc.cpp 234 | clang: warning: -Z-reserved-lib-stdc++: 'linker' input unused [-Wunused-command-line-argument] 235 | module_ifc.cpp:4:2: warning: __cpp_modules not defined" [-W#warnings] 236 | #warning __cpp_modules not defined" 237 | ^ 238 | 1 warning generated. 239 | make[1]: Leaving directory '/mnt/c/Users/luncl/source/modern-cpp-next/examples' 240 | clang-9 -std=c++2a -fmodules-ts -lstdc++ \ 241 | -fmodule-file=next.pcm \ 242 | -o next_impl_2.o -c module_impl_2.cpp 243 | clang: warning: -Z-reserved-lib-stdc++: 'linker' input unused [-Wunused-command-line-argument] 244 | nm ./next_impl_2.o 245 | 0000000000000000 r GCC_except_table0 246 | 00000000000000b0 T _Z6lookupP10endpoint_ttPKcS2_ 247 | 0000000000000000 T _Z6lookupRK8addrinfoPKcS3_ 248 | U _ZSt9terminatev 249 | 0000000000000000 W __clang_call_terminate 250 | U __cxa_begin_catch 251 | U __gxx_personality_v0 252 | U freeaddrinfo 253 | U gai_strerror 254 | U getaddrinfo 255 | U memset 256 | clang-9 -std=c++2a -fmodules-ts -lstdc++ \ 257 | -o main.o -c main.cpp \ 258 | -fprebuilt-module-path=. \ 259 | -fmodule-file=next.pcm 260 | clang: warning: -Z-reserved-lib-stdc++: 'linker' input unused [-Wunused-command-line-argument] 261 | clang-9 -std=c++2a -fmodules-ts -lstdc++ \ 262 | -o main main.o next_impl_2.o 263 | nm --demangle ./main | grep endpoint_t 264 | 0000000000400b10 T lookup(endpoint_t*, unsigned short, char const*, char const*) 265 | ``` -------------------------------------------------------------------------------- /examples/modules_p1_1.cpp: -------------------------------------------------------------------------------- 1 | /// @file examples/modules_p1_1.cpp 2 | #include 3 | 4 | int main(int argc, char* argv[]) { 5 | for (auto i = 0; i < argc; ++i) 6 | fputs(argv[i], stdout); 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /examples/modules_p1_2.cpp: -------------------------------------------------------------------------------- 1 | /// @file examples/modules_p1_2.cpp 2 | /// @see https://en.cppreference.com/w/cpp/preprocessor/replace 3 | #if not defined(__cpp_modules) 4 | #warning "'__cpp_modules' not defined" 5 | #endif 6 | #include 7 | export module m1; // all following declarations will be in `m1` 8 | 9 | export struct endpoint_t { 10 | uint32_t _u32[4]; 11 | }; 12 | 13 | export uint16_t lookup(endpoint_t* base, uint16_t capacity, // 14 | const char* hostname, // 15 | const char* servname) noexcept; 16 | -------------------------------------------------------------------------------- /examples/modules_p1_3.cpp: -------------------------------------------------------------------------------- 1 | /// @file examples/module_p1_3.cpp 2 | #include 3 | module m1; // `endpoint_t` becomes visible 4 | // since it's purview of `m1` 5 | 6 | uint16_t lookup(endpoint_t* base, uint16_t capacity, // 7 | const char* hostname, // 8 | const char* servname) noexcept { 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /examples/modules_p1_5.cpp: -------------------------------------------------------------------------------- 1 | /// @file examples/modules_p1_5.cpp 2 | #include 3 | #include 4 | import m1; 5 | 6 | std::array endpoints{}; 7 | 8 | int main(int, char*[]) { 9 | auto count = lookup(endpoints.data(), endpoints.size(), // 10 | "releases.llvm.org", "https"); 11 | 12 | std::cout << count << std::endl; 13 | for (auto i = 0u; i < count; ++i) { 14 | endpoints[i]; 15 | } 16 | return count > 0 ? EXIT_SUCCESS : EXIT_FAILURE; 17 | } 18 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Author: github.com/luncliff (luncliff@gmail.com) 3 | # References: 4 | # https://www.mkdocs.org/ 5 | # 6 | # Note: 7 | # Any suggestion for this file will be welcomed :) 8 | # 9 | site_name: "Modern C++ Next" 10 | site_description: "Comprehensive Guide for C++20" 11 | site_url: https://luncliff.github.io/modern-cpp-next 12 | site_author: Park DongHa 13 | site_dir: _site 14 | 15 | repo_name: luncliff/modern-cpp-next 16 | repo_url: http://github.com/luncliff/modern-cpp-next 17 | 18 | copyright: "MIT" 19 | 20 | theme: 21 | name: readthedocs 22 | highlightjs: true 23 | hljs_languages: 24 | - yaml 25 | - c++ 26 | include_sidebar: false 27 | 28 | # https://python-markdown.github.io/extensions/ 29 | markdown_extensions: 30 | - toc 31 | # - codehilite: 32 | # linenums: true 33 | # guess_lang: false 34 | 35 | nav: 36 | - Home: index.md 37 | - Getting Started: kor/getting_started.md 38 | - Modules: 39 | - Overview: kor/modules_p0.md 40 | - Part 1: kor/modules_p1.md 41 | - Part 2: kor/modules_p2.md 42 | - Part 3: kor/modules_p3.md 43 | - Part 4: kor/modules_p4.md 44 | # - Concepts: 45 | # - Overview: kor/concepts_p0.md 46 | # - Appendix: 47 | # - Install: kor/appendix_install.md 48 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # https://www.mkdocs.org/ 3 | # https://github.com/matusnovak/doxybook 4 | # 5 | doxybook 6 | 7 | mkdocs 8 | -------------------------------------------------------------------------------- /scripts/build-vs2017-cmake-clang.bat: -------------------------------------------------------------------------------- 1 | REM # 2 | REM # Author : github.com/luncliff (luncliff@gmail.com) 3 | REM # 4 | 5 | REM The batch script emulates the 'Visual Studio Native Command Prompt' 6 | REM If the script fails, check the location of 'vcvarsall.bat' and invoke it 7 | 8 | REM VC++ Tools from Chocolatey package 9 | REM choco install visualstudio2017-workload-vctools; 10 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" 11 | if exist %vcvarsall_path% ( 12 | call %vcvarsall_path% x86_amd64 13 | ) 14 | 15 | REM Visual Studio Installer 16 | REM Enterprise/Professional/Community 17 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" 18 | if exist %vcvarsall_path% ( 19 | call %vcvarsall_path% x86_amd64 20 | ) 21 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Auxiliary\Build\vcvarsall.bat" 22 | if exist %vcvarsall_path% ( 23 | call %vcvarsall_path% x86_amd64 24 | ) 25 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" 26 | if exist %vcvarsall_path% ( 27 | call %vcvarsall_path% x86_amd64 28 | ) 29 | 30 | REM Install path of the Chocolatey LLVM package 31 | path "C:/Program Files/LLVM/bin/";%PATH% 32 | clang-cl --version 33 | 34 | REM We can specify with -DCMAKE_CXX_COMPILER=clang-cl 35 | REM But for this script we will use CXX variable 36 | set CXX=clang-cl 37 | 38 | cmake . -G "Ninja" -DBUILD_SHARED_LIBS="%SHARED%" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%" 39 | cmake --build . 40 | cmake --build . --target install 41 | -------------------------------------------------------------------------------- /scripts/build-vs2019-cmake-clang.bat: -------------------------------------------------------------------------------- 1 | REM # 2 | REM # Author : github.com/luncliff (luncliff@gmail.com) 3 | REM # 4 | 5 | REM The batch script emulates the 'Visual Studio Native Command Prompt' 6 | REM If the script fails, check the location of 'vcvarsall.bat' and invoke it 7 | 8 | REM Visual Studio Installer 9 | REM Enterprise/Professional/Community 10 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" 11 | if exist %vcvarsall_path% ( 12 | call %vcvarsall_path% x86_amd64 13 | ) 14 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvarsall.bat" 15 | if exist %vcvarsall_path% ( 16 | call %vcvarsall_path% x86_amd64 17 | ) 18 | set vcvarsall_path="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" 19 | if exist %vcvarsall_path% ( 20 | call %vcvarsall_path% x86_amd64 21 | ) 22 | 23 | REM Install path of the Chocolatey LLVM package 24 | path "C:/Program Files/LLVM/bin/";%PATH% 25 | clang-cl --version 26 | 27 | REM We can specify with -DCMAKE_CXX_COMPILER=clang-cl 28 | REM But for this script we will use CXX variable 29 | set CXX=clang-cl 30 | 31 | cmake . -G "Ninja" -DBUILD_SHARED_LIBS="%SHARED%" -DCMAKE_BUILD_TYPE="%BUILD_TYPE%" 32 | cmake --build . 33 | cmake --build . --target install 34 | -------------------------------------------------------------------------------- /scripts/install-cmake-3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author : github.com/luncliff (luncliff@gmail.com) 4 | # Example 5 | # sudo bash install-cmake-3.sh 3.16.1 6 | # 7 | version=${1:-"3.16.2"} 8 | 9 | echo "----------------------------------------------------------------------" 10 | echo " " 11 | echo " Install Script: CMake " 12 | echo " - Version: ${version} " 13 | echo " - Source: https://github.com/Kitware/CMake/releases " 14 | echo " " 15 | echo "----------------------------------------------------------------------" 16 | 17 | # render packaged folder's name. for example ... 18 | # cmake-3.16.1-Linux-x86_64 19 | dirname="cmake-${version}-$(uname)-$(uname -m)" 20 | source="https://github.com/Kitware/CMake/releases/download" 21 | 22 | # download & extract in /tmp to keep working directory clean 23 | uri="${source}/v${version}/${dirname}.tar.gz" 24 | wget -O /tmp/cmake3.tar.gz ${uri} 25 | 26 | pushd /tmp 27 | tar -x -f cmake3.tar.gz 28 | rsync -ah /tmp/${dirname}/bin /usr 29 | rsync -ah /tmp/${dirname}/share /usr 30 | popd # leave /tmp 31 | 32 | cmake --version 33 | -------------------------------------------------------------------------------- /scripts/install-libcxx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author : github.com/luncliff (luncliff@gmail.com) 4 | # 5 | branch=${1:-"release_90"} 6 | install_prefix=$(realpath ${2:-"/usr"}) 7 | 8 | echo "----------------------------------------------------------------------" 9 | echo " " 10 | echo " Build/Install libcxx & libcxxabi " 11 | echo " - http://libcxx.llvm.org/docs/BuildingLibcxx.html " 12 | echo " " 13 | echo " - Branch : ${branch} " 14 | echo " - Path : ${install_prefix}/{include, lib} " 15 | echo " " 16 | echo "----------------------------------------------------------------------" 17 | 18 | provider="https://github.com/llvm-mirror" 19 | 20 | pushd /tmp 21 | # get the packages with specified version 22 | for repo in "llvm" "libcxx" "libcxxabi" 23 | do 24 | uri="${provider}/${repo}/archive/${branch}.zip" 25 | wget -q -O "${repo}.zip" ${uri} & 26 | done 27 | # wait for background downloads 28 | for pid in $(jobs -p); do 29 | wait $pid 30 | done 31 | 32 | for repo in "llvm" "libcxx" "libcxxabi" 33 | do 34 | unzip -u -q "${repo}.zip" 35 | mv "${repo}-${branch}" "${repo}" 36 | done 37 | 38 | mkdir -p llvm-build && pushd llvm-build 39 | cmake ../llvm \ 40 | -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ 41 | -DCMAKE_INSTALL_PREFIX="${install_prefix}" 42 | 43 | # too many logs. make silent ... 44 | make -j4 cxx 2>err-libcxx.txt 45 | make install-cxx 46 | make -j4 cxxabi 2>err-libcxxabi.txt 47 | make install-cxxabi 48 | 49 | popd # leave /tmp/llvm-build 50 | popd # leave /tmp 51 | -------------------------------------------------------------------------------- /scripts/install-llvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author : github.com/luncliff (luncliff@gmail.com) 4 | # 5 | branch=${1:-"master"} 6 | install_prefix=$(realpath ${2:-"/usr"}) 7 | 8 | echo "----------------------------------------------------------------------" 9 | echo " " 10 | echo " Build/Install LLVM project modules " 11 | echo " - Branch : ${branch} " 12 | echo " - Path : ${install_prefix}/{include, lib} " 13 | echo " " 14 | echo "----------------------------------------------------------------------" 15 | 16 | provider="https://github.com/llvm-mirror" 17 | 18 | # get the packages with specified version 19 | for repo in "llvm" "libcxx" "libcxxabi" "clang" 20 | do 21 | uri="${provider}/${repo}/archive/${branch}.zip" 22 | wget -q -O "/tmp/${repo}.zip" ${uri} & 23 | done 24 | # wait for background downloads 25 | for pid in $(jobs -p); do 26 | wait $pid 27 | done 28 | 29 | pushd /tmp 30 | for repo in "llvm" "libcxx" "libcxxabi" "clang" 31 | do 32 | unzip -u -q "${repo}.zip" 33 | mv "${repo}-${branch}" "${repo}" 34 | done 35 | 36 | mkdir -p llvm-build && pushd llvm-build 37 | cmake ../llvm \ 38 | -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;clang" \ 39 | -DCMAKE_INSTALL_PREFIX="${install_prefix}" 40 | 41 | # too many logs. make silent ... 42 | make -j4 install-cxx 2>err-libcxx.txt 43 | make -j4 install-cxxabi 2>err-libcxxabi.txt 44 | make -j4 clang 2>err-clang.txt 45 | make clang 46 | 47 | popd # leave /tmp/llvm-build 48 | popd # leave /tmp 49 | -------------------------------------------------------------------------------- /scripts/setup-compilers-ubuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author : github.com/luncliff (luncliff@gmail.com) 4 | # References: 5 | # https://apt.llvm.org/ 6 | # 7 | apt --version 8 | if [ $? -gt 0 ] 9 | then 10 | echo "The script requires APT" 11 | exit 1 12 | fi 13 | 14 | verion_name=$(. /etc/os-release;echo $VERSION) 15 | distribution=$(. /etc/os-release;echo $UBUNTU_CODENAME) 16 | 17 | echo "----------------------------------------------------------------------" 18 | echo " " 19 | echo " Install C++ Compilers: ${verion_name} " 20 | echo " - Path : /usr/bin " 21 | echo " - Compiler : g++-8, g++-9, clang-8, clang-9 " 22 | echo " " 23 | echo "----------------------------------------------------------------------" 24 | 25 | # display release info. this will helpful for checking CI environment 26 | cat /etc/os-release 27 | 28 | apt update -qq 29 | apt install -y -qq \ 30 | build-essential software-properties-common 31 | apt-add-repository -y ppa:ubuntu-toolchain-r/test 32 | 33 | # http://apt.llvm.org/ 34 | # use clang for 'stable, development branch' 35 | wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - 36 | apt-add-repository "deb http://apt.llvm.org/${distribution}/ llvm-toolchain-${distribution}-8 main" 37 | apt-add-repository "deb http://apt.llvm.org/${distribution}/ llvm-toolchain-${distribution}-9 main" 38 | 39 | apt update -qq 40 | apt install -y -q \ 41 | g++-8 g++-9 clang-8 clang-9 \ 42 | libc++abi-8-dev 43 | 44 | pushd /usr/bin 45 | ln -s --force gcc-9 gcc 46 | ln -s --force g++-9 g++ 47 | ln -s --force clang-9 clang 48 | popd # leave /usr/bin 49 | -------------------------------------------------------------------------------- /scripts/setup-llvm-ubuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Author : github.com/luncliff (luncliff@gmail.com) 4 | # References: 5 | # https://apt.llvm.org/ 6 | # 7 | wget https://apt.llvm.org/llvm.sh 8 | bash ./llvm.sh 9 9 | --------------------------------------------------------------------------------