如何在 Mac OS X Big Sur 下将 c++20 标准的模块<format>与 g++ 13.2.0 和 Gnu Make 3.81 一起使用

How to use the module <format> of the c++20 standard with g++ 13.2.0 and Gnu Make 3.81 under Mac OS X Big Sur

提问人:pocahontius 提问时间:10/20/2023 最后编辑:pocahontius 更新时间:10/25/2023 访问量:90

问:

5天后...没有人能给我一个提示,这有什么问题吗?我还没有找到这个问题的解决方案!

---vvv---

我刚开始阅读有关 C++20 标准的信息,并想尝试模块。我在 Mac OS X Big Sur 下通过 Homebrew 安装了 g++ 13.2.0 和 GNU Make 3.8.1。在 gcc 网站上指出,模块支持尚未完成,必须:

1.) 使用 -std=c++20 和 -fmodules-ts 标志, 2.) 首先构建标准库头单元 3.) 使用不带后缀的标头时,请使用 -x C++-system-header 标志。

所以我创建了这两个测试文件(main.cpp 和 makefile):

main.c:

import <cstdint>;
import <format>;
import <iostream>;
import <ostream>;
import <sstream>;
import <string>;

int main()
{
    // test module: cstdint
    uint64_t val { UINT64_C(42) };
    
    // test module: format
    // std::string fstr = std::format("The number {} is great!", 42);

    // test module: iostream
    std::cout << "Hello World!";
    
    // test module: ostream
    std::cout << std::endl;
    
    // test module: sstream
    std::stringstream ss; ss << "C++20";

    // test module: string
    std::string str = "This is a string stream";

    return 0;
}

makefile:

#!/usr/bin/make -f

SHELL = /bin/sh

.SUFFIXES:
.SUFFIXES: .cpp .o

objects = main.o

mtest : stdlib $(objects)
    g++ -std=c++20 -fmodules-ts -o mtest $(objects)

stdlib :
    g++ -std=c++20 -fmodules-ts -x c++-system-header cstdint
    g++ -std=c++20 -fmodules-ts -x c++-system-header format
    g++ -std=c++20 -fmodules-ts -x c++-system-header iostream
    g++ -std=c++20 -fmodules-ts -x c++-system-header ostream
    g++ -std=c++20 -fmodules-ts -x c++-system-header sstream
    g++ -std=c++20 -fmodules-ts -x c++-system-header string

main.o : main.cpp
    g++ -std=c++20 -fmodules-ts -c main.cpp

.PHONY : clean
clean :
    -rm -rf gcm.cache
    -rm mtest $(objects)

当“test module: format”下的行被注释掉时,一切正常。但是:如果我尝试使用 std::format 并激活该行,则会出现链接器错误。

错误:

g++ -std=c++20 -fmodules-ts -x c++-system-header cstdint
g++ -std=c++20 -fmodules-ts -x c++-system-header format
g++ -std=c++20 -fmodules-ts -x c++-system-header iostream
g++ -std=c++20 -fmodules-ts -x c++-system-header ostream
g++ -std=c++20 -fmodules-ts -x c++-system-header sstream
g++ -std=c++20 -fmodules-ts -x c++-system-header string
g++ -std=c++20 -fmodules-ts -c main.cpp
g++ -std=c++20 -fmodules-ts -o mtest main.o
Undefined symbols for architecture x86_64:
  "__ZNSt8__detail31__from_chars_alnum_to_val_tableILb0EE5valueE", referenced from:
      __ZNSt8__detail25__from_chars_alnum_to_valILb0EEEhh in main.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [mtest] Error 1

我在很多网站上搜索过,但没有找到合适的解决方案。我在 C++ 编程和 makefile 方面没有太多专业知识,所以很难弄清楚那里发生了什么。有没有人解决这个问题?

我尝试了列出的代码示例,这些示例以相同的方式导入、编译和链接所有模块。我希望std::format可以正常工作,因为所有其他模块都可以完美运行。当我使用 std::format 时,我收到链接器错误。

PS:我还测试了__cpp_lib_format宏的值 >= 201907,如 isocpp.org 网站上的 SD-FeatureTest 中所述。我敢肯定,我有一个最新版本。

PPS:我刚刚添加了一个用户定义的模块。这也很好用!

问候,感谢您的帮助! 波卡洪提乌斯

C++ 模块 格式 C++20 链接器错误

评论

0赞 Lothar 10/27/2023
可悲的是,XCode 仍然不支持 std::format。这总是屁股很痛。花了数年时间才包含 std::filesystem。苹果在这方面很慢。而且我不想想象需要多少年才能支持模块。我知道现在的年轻人非常沉迷于使用最新功能,但作为一名专业开发人员,我告诉你要坚持使用至少十年前的东西。也就是说,您可以将 std::format 替换为开源 fmt::format,这就是我在代码中所做的。
0赞 pocahontius 10/28/2023
感谢您的回答,但我没有使用 Xcode。我通过终端和自制软件安装了 G++ 13.2.0 和 Make 4.4.1(不是上面提到的 3.81)。正如我所写的,模块工作正常,唯一给出链接器错误的是<格式>。我查找了 g++ 的支持页面,它指出 13.2.0 支持模块和格式,所以我想,我在编译时可能出错了?

答: 暂无答案