2024年5月16日 星期四

c++20 moudles support by g++

這是一個我很想用的特性, 沒有 header files 還能編譯, 真的厲害, 不知道怎麼辦到的, c++ 的魔法越來越多了。

主要以 chatgpt 為主, 再搭配 google 找資料, 終於知道怎麼編譯 module。
descent@deb64:cpp_module$ g++ --version
g++ (Debian 13.2.0-12) 13.2.0
main.cpp
 1 import functions;
 2 
 3 #include <iostream>
 4 #include <cstdio>
 5 
 6 int main() {
 7 #if 0
 8     int x = 10;
 9     int y = 5;
10 
11     std::cout << "x + y = " << add(x, y) << std::endl;
12     std::cout << "x - y = " << subtract(x, y) << std::endl;
13     std::cout << "x + y = " << add(10.5, 1.2) << std::endl;
14     //std::cout << "x * y = " << multiply(x, y) << std::endl;
15 #endif
16     Point p1 = createPoint(3, 4);
17     Point p2 = {1, 2};
18 
19     std::cout << "p1.x = " << p1.x << ", p1.y = " << p1.y << std::endl;
20     std::cout << "p2.x = " << p2.x << ", p2.y = " << p2.y << std::endl;
21     Line line{1,2};
22     line.print();
23     printMessage();
24     print_msg();
25     return 0;
26 }
math_functions.cpp
 1 export module functions;
 2 
 3 import <iostream>;
 4 
 5 export int int_add(int a, int b) {
 6     return a + b;
 7 }
 8 
 9 #if 0
10 export int subtract(int a, int b) {
11     return a - b;
12 }
13 
14 export int multiply(int a, int b) {
15     return a * b;
16 }
17 #endif
18 
19 export template<typename T>
20 T add(T a, T b) {
21     return a + b;
22 }
23 
24 export template<typename T>
25 T subtract(T a, T b) {
26     return a - b;
27 }
28 
29 // export module math_functions;
30 
31 export struct Point 
32 {
33     int x;
34     int y;
35 };
36 
37 export Point createPoint(int x, int y) 
38 {
39     return {x, y};
40 }
41 
42 export 
43 class Line
44 {
45   public:
46     Line(int x, int y):x_(x), y_(y)
47     {
48     }
49     void print()
50     {
51       printf("x_: %d, y_: %d\n", x_, y_);
52       std::cout << "x_: " << x_ << std::endl;
53     }
54   private:
55     int x_;
56     int y_;
57 };
58 
59 
60 
61 export void printMessage() 
62 {
63   std::cout << "Hello again from math_functions.cpp by iostream" << std::endl;
64 }
65 
66 export void print_msg() 
67 {
68   std::printf("Hello again from math_functions.cpp by printf!\n");
69 }
list 1 編譯指令
g++ -std=c++23 -fmodules-ts main.cpp math_functions.cpp -o math_program -x c++-system-header iostream -x c++-system-header cstdio

編譯之後會產生 gcm.cache 目錄。另外也有可能第一次編譯有錯, 再一次編譯就正常的情形, 所以有時候我搞不清楚是我寫錯還是編譯的問題。

測試了:
  1. class
  2. function
  3. template function
  4. 使用標準程式庫
這樣大概就可以來用 module 了, 不過這樣就不能從 header files 知道有哪些 function, class, class member function 可用, 一定得寫文件了吧! 原本的 include 還是可以用。

c++20_module
 1 g++ -std=c++23 -fmodules-ts main.cpp math_functions.cpp -o math_program -x c++-system-header iostream -x c++-system-header cstdio
 2 In module imported at main.cpp:1:1:
 3 functions: error: failed to read compiled module: No such file or directory
 4 functions: note: compiled module file is ‘gcm.cache/functions.gcm’
 5 functions: note: imports must be built before being imported
 6 functions: fatal error: returning to the gate for a mechanical issue
 7 compilation terminated.
 8 In module imported at math_functions.cpp:3:1:
 9 /usr/include/c++/13/iostream: error: failed to read compiled module: No such file or directory
10 /usr/include/c++/13/iostream: note: compiled module file is ‘gcm.cache/./usr/include/c++/13/iostream.gcm’
11 /usr/include/c++/13/iostream: note: imports must be built before being imported
12 /usr/include/c++/13/iostream: fatal error: returning to the gate for a mechanical issue
13 compilation terminated.
14 make: *** [makefile:2: math_program] Error 1
15 descent@debian-vm:cpp20_module$ make clean
16 rm math_program
17 rm: cannot remove 'math_program': No such file or directory
18 make: *** [makefile:4: clean] Error 1
19 descent@debian-vm:cpp20_module$ ls
20 gcm.cache  main.cpp  makefile  math_functions.cpp
21 descent@debian-vm:cpp20_module$ rm -rf gcm.cache/
22 descent@debian-vm:cpp20_module$ make
23 g++ -std=c++23 -fmodules-ts main.cpp math_functions.cpp -o math_program -x c++-system-header iostream -x c++-system-header cstdio
24 In module imported at main.cpp:1:1:
25 functions: error: failed to read compiled module: No such file or directory
26 functions: note: compiled module file is ‘gcm.cache/functions.gcm’
27 functions: note: imports must be built before being imported
28 functions: fatal error: returning to the gate for a mechanical issue
29 compilation terminated.
30 In module imported at math_functions.cpp:3:1:
31 /usr/include/c++/13/iostream: error: failed to read compiled module: No such file or directory
32 /usr/include/c++/13/iostream: note: compiled module file is ‘gcm.cache/./usr/include/c++/13/iostream.gcm’
33 /usr/include/c++/13/iostream: note: imports must be built before being imported
34 /usr/include/c++/13/iostream: fatal error: returning to the gate for a mechanical issue
35 compilation terminated.
36 make: *** [makefile:2: math_program] Error 1
37 descent@debian-vm:cpp20_module$ make
38 g++ -std=c++23 -fmodules-ts main.cpp math_functions.cpp -o math_program -x c++-system-header iostream -x c++-system-header cstdio
39 In module imported at main.cpp:1:1:
40 functions: error: failed to read compiled module: No such file or directory
41 functions: note: compiled module file is ‘gcm.cache/functions.gcm’
42 functions: note: imports must be built before being imported
43 functions: fatal error: returning to the gate for a mechanical issue
44 compilation terminated.
45 make: *** [makefile:2: math_program] Error 1
46 descent@debian-vm:cpp20_module$ make
47 g++ -std=c++23 -fmodules-ts main.cpp math_functions.cpp -o math_program -x c++-system-header iostream -x c++-system-header cstdio
48 In module imported at main.cpp:1:1:
49 functions: error: import ‘/usr/include/c++/13/iostream’ has CRC mismatch
50 main.cpp: In substitution of ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>]’:
51 main.cpp:19:18:   required from here
52 functions: error: failed to read compiled module cluster 15: Bad file data
53 functions: note: compiled module file is ‘gcm.cache/functions.gcm’
54 main.cpp:19:18: fatal error: failed to load pendings for ‘std::operator<<’
55    19 |     std::cout << "p1.x = " << p1.x << ", p1.y = " << p1.y << std::endl;
56       |                  ^~~~~~~~~
57 compilation terminated.
58 make: *** [makefile:2: math_program] Error 1
59 descent@debian-vm:cpp20_module$ make
60 g++ -std=c++23 -fmodules-ts main.cpp math_functions.cpp -o math_program -x c++-system-header iostream -x c++-system-header cstdio
61 descent@debian-vm:cpp20_module$ ls
62 gcm.cache  main.cpp  makefile  math_functions.cpp  math_program
63 descent@debian-vm:cpp20_module$ ./math_program 
ref:
C++20 Modules - 讓編譯加速吧 | C++ · 傳統與革新的空間

1 則留言:

  1. 上面提到 compile error 的問題。
    我參考 [c++ - How to use c++20 modules with GCC? - Stack Overflow](https://stackoverflow.com/a/76892451) 修改如下:

    ```
    g++ -std=c++23 -fmodules-ts -x c++-system-header iostream -x c++-system-header cstdio
    g++ -std=c++23 -fmodules-ts math_functions.cpp main.cpp -o math_program
    ```

    好像就可以了。

    回覆刪除

使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。

我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。