如何在ubuntu 20.04 / 22.04中预编译<bits/stdc++.h>头文件?

问题描述 投票:0回答:5

有没有办法像我们在 Windows 操作系统中一样在 ubuntu 20.04 中预编译

<bits/stdc++.h>
头文件,以便我可以在 Sublime 文本编辑器中更快地执行程序?

我使用 FastOlympicCoding 扩展来快速执行,但我怀念使用输入输出文件的旧方法。我到处搜索,但没有找到任何“外行”方法来做到这一点。

c++ ubuntu precompiled-headers
5个回答
4
投票

创建预编译头的示例:

mkdir -p pch/bits &&
g++ -O3 -std=c++20 -pedantic-errors -o pch/bits/stdc++.h.gch \
   /usr/include/c++/11/x86_64-redhat-linux/bits/stdc++.h

检查你得到了什么:

$ file pch/bits/stdc++.h.gch
pch/bits/stdc++.h.gch: GCC precompiled header (version 014) for C++

$ ls -l pch/bits/stdc++.h.gch
-rw-r--r-- 1 ted users 118741428  8 mar 23.27 pch/bits/stdc++.h.gch

使用它的程序:

#include <bits/stdc++.h>

int main() {
    std::vector<int> foo{1, 2, 3};
    for(auto v : foo) std::cout << v << '\n';
}

示例编译(将

-Ipch
放在
-I
指令的第一个):

$ strace -f g++ -Ipch -O3 -std=c++20 -pedantic-errors -o program program.cpp 2>&1 | grep 'stdc++.h'
[pid 13964] read(3, "#include <bits/stdc++.h>\n\nint ma"..., 122) = 122
[pid 13964] newfstatat(AT_FDCWD, "pch/bits/stdc++.h.gch", {st_mode=S_IFREG|0644, st_size=118741428, ...}, 0) = 0
[pid 13964] openat(AT_FDCWD, "pch/bits/stdc++.h.gch", O_RDONLY|O_NOCTTY) = 4

2
投票

不应该

#include <bits/stdc++.h>
从源代码中,至少有两个原因:

  • 它不方便携带,所以需要丑陋的

    #ifdef
    s来守护。

  • 与 GCC 不同,Clang 从不使用 PCH 来表示

    #include

您应该使用

-include
标志包含 PCH。这是 GCC 和 Clang 都接受的唯一选项。

  1. 使用

    g++ -xc++-header /path/to/bits/stdc++.h -o stdc++.h.gch
    预编译头文件。

  2. 将其包含在

    -include
    中:
    g++ foo.cpp -include stdc++.h

请注意,

-include
会自动将
.gch
附加到文件名;当前目录不必包含
stdc++.h

如果没有

.gch
文件,
-include
会回退到包含常规非 PCH 标头(如果存在)。如果两者都存在于包含路径中,则 PCH 优先。


1
投票

根据泰德的回答,我实际上会做这样的事情(未经测试):

my_pch.h:

#include <bits/stdc++.h>          // might need to specify the full path here

然后:

g++ -O3 -std=c++20 -pedantic-errors -o pch/bits/my_pch.h.gch my_pch.h

最后,你的程序将如下所示:

#include "my_pch.h"

int main() {
    // ...
}

这意味着您不需要将

#include <bits/stdc++.h>
直接放入源文件中,因为这有点顽皮。这也意味着您可以根据需要将其他包含文件添加到
my_pch.h

我也认为,在包含

#include <string>
之后添加
my_pch.h
不会花费你任何费用,而且这样做可能是明智的。如果您要将代码移至生产环境,则可以使用
my_pch.h
空重新编译它。


编辑:要考虑的另一件事(我也无法测试)就是将您实际使用的东西(

string
vector
,等等)包含在
my_pch.h
中。无论如何,在构建预编译头时,这可能会引入
bits/stdc++.h
。使其成为一个全面的列表,这样您就无需不断添加内容。然后你就有了可移植的代码,人们就不会再为此责备你了。


0
投票

因此,在获得@TedLyngmo的回答的帮助并做了更多研究后,我决定自己用更清晰的步骤来回答这个问题。

PS这个答案对于那些在 Linux 操作系统(Ubuntu)上使用 sublime 及其自定义构建文件的人来说更相关。

  1. 您需要找到stdc++.h头文件所在的位置,因此打开终端并使用以下命令:

    find /usr/include -name 'stdc++.h'

    输出:

    /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h

  2. 转到上述位置并打开终端,现在我们准备预编译bits/stdc++.h头文件。

  3. 使用以下命令:

    sudo g++ -std=c++17 stdc++.h

  4. 您将观察到stdc++.h.gch文件现已创建,这意味着预编译已完成。

PS: 你需要使用sudo,因为当g++制作stdc++.h.gch文件时我们需要root权限。

注意: 由于我在自定义构建文件中使用 c++17 版本,因此我提到了 c++17,您可以使用您正在使用的任何版本。

它对我来说非常有效,所以我希望它也能帮助你!


0
投票

首先找到

bits/stdc++.h
头文件的路径。

在 g++ 的非常正常的 apt 安装中,它应该位于以下位置:

/usr/include/x86_64-linux-gnu/c++/<version>/

就我而言,我安装了版本 11。运行下面的简单命令:

cd /usr/include/x86_64-linux-gnu/c++/11/bits/
sudo rm ./stdc++.h.gch # required if you previously tried compiling
sudo g++ ./stdc++.h

就是这样!没什么太复杂的。就我而言,已生成

stdc++.h.gch
文件,大小约为 93 mb。即使没有任何额外的标志或代码更改,它也会在您下次使用 g++ 时自动包含。在我的例子中,编译时间得到了很大程度的改善。

长期记住的事情:

  • 跑步时请留意
    sudo apt update
  • 如果您更新了g++版本,则应再次按照上述步骤操作。
  • 如果您在编译常规代码期间经常使用某些标志,则在预编译时也可能必须使用相同的标志
    stdc++.h
© www.soinside.com 2019 - 2024. All rights reserved.