We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Should hide the symbols from the third party
I am integrating KenLM in torchaudio and realized that KenLM uses double-conversion like torchtext does.

In torchaudio we are hiding the symbols of third party with `-fhidden` flag with compiling, but it turns out that torchtext does not do this. (and according to the conversation I had with @malfet about a year ago, PyTorch also hides the symbol of their own code, in addition to third party.)

Torchtext may want to do this in case client code imports the same package compiled differently.

## References:
- https://stackoverflow.com/a/22254251
- https://labjack.com/news/simple-cpp-symbol-visibility-demo

## Double conversion

```
nm torchtext/_torchtext.so| grep double_c | grep 'T __' | head -10
0000000000175a48 T __ZN17double_conversion13StrtodTrimmedENS_6VectorIKcEEi
000000000017175c T __ZN17double_conversion16PowersOfTenCache32GetCachedPowerForDecimalExponentEiPNS_5DiyFpEPi
00000000001716fc T __ZN17double_conversion16PowersOfTenCache36GetCachedPowerForBinaryExponentRangeEiiPNS_5DiyFpEPi
00000000001715bc T __ZN17double_conversion6Bignum11PlusCompareERKS0_S2_S2_
000000000016f7cc T __ZN17double_conversion6Bignum12AssignBignumERKS0_
000000000016f788 T __ZN17double_conversion6Bignum12AssignUInt16Et
000000000016f7a0 T __ZN17double_conversion6Bignum12AssignUInt64Ey
0000000000171188 T __ZN17double_conversion6Bignum13SubtractTimesERKS0_i
00000000001702e8 T __ZN17double_conversion6Bignum14SubtractBignumERKS0_
000000000016ff70 T __ZN17double_conversion6Bignum15AssignHexStringENS_6VectorIKcEE
```

## Sentencepiece

```
$ nm torchtext/_torchtext.so| grep sentencep | grep 'T __' | head -10
0000000000128718 T __ZN13sentencepiece10ModelProto12InternalSwapEPS0_
00000000001277fc T __ZN13sentencepiece10ModelProto14_InternalParseEPKcPN6google8protobuf8internal12ParseContextE
000000000012765c T __ZN13sentencepiece10ModelProto16default_instanceEv
0000000000128334 T __ZN13sentencepiece10ModelProto21CheckTypeAndMergeFromERKN6google8protobuf11MessageLiteE
00000000001276a0 T __ZN13sentencepiece10ModelProto5ClearEv
0000000000128620 T __ZN13sentencepiece10ModelProto8CopyFromERKS0_
0000000000127650 T __ZN13sentencepiece10ModelProto9ArenaDtorEPv
0000000000128338 T __ZN13sentencepiece10ModelProto9MergeFromERKS0_
0000000000127168 T __ZN13sentencepiece10ModelProto9_Internal12trainer_specEPKS0_
0000000000127178 T __ZN13sentencepiece10ModelProto9_Internal14self_test_dataEPKS0_
```



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `build_tools/setup_helpers/extension.py`
Content:
```
1 import os
2 import platform
3 import subprocess
4 from pathlib import Path
5 
6 from torch.utils.cpp_extension import (
7     CppExtension,
8     BuildExtension as TorchBuildExtension
9 )
10 
11 __all__ = [
12     'get_ext_modules',
13     'BuildExtension',
14 ]
15 
16 _ROOT_DIR = Path(__file__).parent.parent.parent.resolve()
17 _CSRC_DIR = _ROOT_DIR / 'torchtext' / 'csrc'
18 _TP_BASE_DIR = _ROOT_DIR / 'third_party'
19 _TP_INSTALL_DIR = _TP_BASE_DIR / 'build'
20 
21 
22 def _get_eca(debug):
23     eca = []
24     if platform.system() == "Windows":
25         eca += ['/MT']
26     if debug:
27         eca += ["-O0", "-g"]
28     else:
29         if platform.system() == "Windows":
30             eca += ['-O2']
31         else:
32             eca += ["-O3"]
33     return eca
34 
35 
36 def _get_ela(debug):
37     ela = []
38     if debug:
39         if platform.system() == "Windows":
40             ela += ["/DEBUG:FULL"]
41         else:
42             ela += ["-O0", "-g"]
43     else:
44         if platform.system() != "Windows":
45             ela += ["-O3"]
46     return ela
47 
48 
49 def _get_srcs():
50     return [str(p) for p in _CSRC_DIR.glob('**/*.cpp')]
51 
52 
53 def _get_include_dirs():
54     return [
55         str(_CSRC_DIR),
56         str(_TP_INSTALL_DIR / 'include'),
57     ]
58 
59 
60 def _get_library_dirs():
61     return [
62         str(_TP_INSTALL_DIR / 'lib'),
63         str(_TP_INSTALL_DIR / 'lib64')
64     ]
65 
66 
67 def _get_libraries():
68     # NOTE: The order of the library listed bellow matters.
69     #
70     # For example, the symbol `sentencepiece::unigram::Model` is
71     # defined in sentencepiece but UNDEFINED in sentencepiece_train.
72     # GCC only remembers the last encountered symbol.
73     # Therefore placing 'sentencepiece_train' after 'sentencepiece' cause runtime error.
74     #
75     # $ nm third_party/build/lib/libsentencepiece_train.a | grep _ZTIN13sentencepiece7unigram5ModelE
76     #                  U _ZTIN13sentencepiece7unigram5ModelE
77     # $ nm third_party/build/lib/libsentencepiece.a       | grep _ZTIN13sentencepiece7unigram5ModelE
78     # 0000000000000000 V _ZTIN13sentencepiece7unigram5ModelE
79     return [
80         'sentencepiece_train',
81         'sentencepiece',
82         're2',
83         'double-conversion'
84     ]
85 
86 
87 def _get_cxx11_abi():
88     try:
89         import torch
90         value = int(torch._C._GLIBCXX_USE_CXX11_ABI)
91     except ImportError:
92         value = 0
93     return '-D_GLIBCXX_USE_CXX11_ABI=' + str(value)
94 
95 
96 def _build_third_party(debug):
97     build_dir = _TP_BASE_DIR / 'build'
98     build_dir.mkdir(exist_ok=True)
99     build_env = os.environ.copy()
100     config = 'Debug' if debug else 'Release'
101     if platform.system() == 'Windows':
102         extra_args = [
103             '-GNinja',
104         ]
105         build_env.setdefault('CC', 'cl')
106         build_env.setdefault('CXX', 'cl')
107     else:
108         extra_args = ['-DCMAKE_CXX_FLAGS=-fPIC ' + _get_cxx11_abi()]
109     subprocess.run(
110         args=[
111             'cmake',
112             '-DBUILD_SHARED_LIBS=OFF',
113             '-DRE2_BUILD_TESTING=OFF',
114             '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',
115             f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',
116             f'-DCMAKE_BUILD_TYPE={config}',
117         ] + extra_args + ['..'],
118         cwd=str(build_dir),
119         check=True,
120         env=build_env,
121     )
122     print('*** Command list Thirdparty ***')
123     with open(build_dir / 'compile_commands.json', 'r') as fileobj:
124         print(fileobj.read())
125     print('running cmake --build', flush=True)
126     subprocess.run(
127         args=['cmake', '--build', '.', '--target', 'install', '--config', config],
128         cwd=str(build_dir),
129         check=True,
130         env=build_env,
131     )
132 
133 
134 def _build_sentence_piece(debug):
135     build_dir = _TP_BASE_DIR / 'sentencepiece' / 'build'
136     build_dir.mkdir(exist_ok=True)
137     build_env = os.environ.copy()
138     config = 'Debug' if debug else 'Release'
139     if platform.system() == 'Windows':
140         extra_args = ['-GNinja']
141         build_env.setdefault('CC', 'cl')
142         build_env.setdefault('CXX', 'cl')
143     else:
144         extra_args = []
145     subprocess.run(
146         args=['cmake', '-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',
147               '-DCMAKE_CXX_FLAGS=' + _get_cxx11_abi(),
148               f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'],
149         cwd=str(build_dir),
150         check=True,
151         env=build_env,
152     )
153     subprocess.run(
154         args=['cmake', '--build', '.', '--target', 'install', '--config', config],
155         cwd=str(build_dir),
156         check=True,
157         env=build_env,
158     )
159 
160 
161 def _configure_third_party(debug):
162     _build_third_party(debug)
163     _build_sentence_piece(debug)
164 
165 
166 _EXT_NAME = 'torchtext._torchtext'
167 
168 
169 def get_ext_modules(debug=False):
170     return [
171         CppExtension(
172             _EXT_NAME,
173             _get_srcs(),
174             libraries=_get_libraries(),
175             include_dirs=_get_include_dirs(),
176             library_dirs=_get_library_dirs(),
177             extra_compile_args=_get_eca(debug),
178             extra_link_args=_get_ela(debug),
179         ),
180     ]
181 
182 
183 class BuildExtension(TorchBuildExtension):
184     def build_extension(self, ext):
185         if ext.name == _EXT_NAME:
186             _configure_third_party(self.debug)
187         super().build_extension(ext)
188
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py
--- a/build_tools/setup_helpers/extension.py
+++ b/build_tools/setup_helpers/extension.py
@@ -29,7 +29,7 @@
         if platform.system() == "Windows":
             eca += ['-O2']
         else:
-            eca += ["-O3"]
+            eca += ["-O3", "-fvisibility=hidden"]
     return eca
 
 
@@ -114,6 +114,8 @@
             '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',
             f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',
             f'-DCMAKE_BUILD_TYPE={config}',
+            '-DCMAKE_CXX_VISIBILITY_PRESET=hidden',
+            '-DCMAKE_POLICY_DEFAULT_CMP0063=NEW',
         ] + extra_args + ['..'],
         cwd=str(build_dir),
         check=True,
@@ -144,8 +146,11 @@
         extra_args = []
     subprocess.run(
         args=['cmake', '-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',
+              '-DCMAKE_CXX_VISIBILITY_PRESET=hidden',
               '-DCMAKE_CXX_FLAGS=' + _get_cxx11_abi(),
+              '-DCMAKE_POLICY_DEFAULT_CMP0063=NEW',
               f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'],
+
         cwd=str(build_dir),
         check=True,
         env=build_env,

{"golden_diff": "diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py\n--- a/build_tools/setup_helpers/extension.py\n+++ b/build_tools/setup_helpers/extension.py\n@@ -29,7 +29,7 @@\n         if platform.system() == \"Windows\":\n             eca += ['-O2']\n         else:\n-            eca += [\"-O3\"]\n+            eca += [\"-O3\", \"-fvisibility=hidden\"]\n     return eca\n \n \n@@ -114,6 +114,8 @@\n             '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',\n             f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',\n             f'-DCMAKE_BUILD_TYPE={config}',\n+            '-DCMAKE_CXX_VISIBILITY_PRESET=hidden',\n+            '-DCMAKE_POLICY_DEFAULT_CMP0063=NEW',\n         ] + extra_args + ['..'],\n         cwd=str(build_dir),\n         check=True,\n@@ -144,8 +146,11 @@\n         extra_args = []\n     subprocess.run(\n         args=['cmake', '-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',\n+              '-DCMAKE_CXX_VISIBILITY_PRESET=hidden',\n               '-DCMAKE_CXX_FLAGS=' + _get_cxx11_abi(),\n+              '-DCMAKE_POLICY_DEFAULT_CMP0063=NEW',\n               f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'],\n+\n         cwd=str(build_dir),\n         check=True,\n         env=build_env,\n", "issue": "Should hide the symbols from the third party\nI am integrating KenLM in torchaudio and realized that KenLM uses double-conversion like torchtext does.\r\n\r\nIn torchaudio we are hiding the symbols of third party with `-fhidden` flag with compiling, but it turns out that torchtext does not do this. (and according to the conversation I had with @malfet about a year ago, PyTorch also hides the symbol of their own code, in addition to third party.)\r\n\r\nTorchtext may want to do this in case client code imports the same package compiled differently.\r\n\r\n## References:\r\n- https://stackoverflow.com/a/22254251\r\n- https://labjack.com/news/simple-cpp-symbol-visibility-demo\r\n\r\n## Double conversion\r\n\r\n```\r\nnm torchtext/_torchtext.so| grep double_c | grep 'T __' | head -10\r\n0000000000175a48 T __ZN17double_conversion13StrtodTrimmedENS_6VectorIKcEEi\r\n000000000017175c T __ZN17double_conversion16PowersOfTenCache32GetCachedPowerForDecimalExponentEiPNS_5DiyFpEPi\r\n00000000001716fc T __ZN17double_conversion16PowersOfTenCache36GetCachedPowerForBinaryExponentRangeEiiPNS_5DiyFpEPi\r\n00000000001715bc T __ZN17double_conversion6Bignum11PlusCompareERKS0_S2_S2_\r\n000000000016f7cc T __ZN17double_conversion6Bignum12AssignBignumERKS0_\r\n000000000016f788 T __ZN17double_conversion6Bignum12AssignUInt16Et\r\n000000000016f7a0 T __ZN17double_conversion6Bignum12AssignUInt64Ey\r\n0000000000171188 T __ZN17double_conversion6Bignum13SubtractTimesERKS0_i\r\n00000000001702e8 T __ZN17double_conversion6Bignum14SubtractBignumERKS0_\r\n000000000016ff70 T __ZN17double_conversion6Bignum15AssignHexStringENS_6VectorIKcEE\r\n```\r\n\r\n## Sentencepiece\r\n\r\n```\r\n$ nm torchtext/_torchtext.so| grep sentencep | grep 'T __' | head -10\r\n0000000000128718 T __ZN13sentencepiece10ModelProto12InternalSwapEPS0_\r\n00000000001277fc T __ZN13sentencepiece10ModelProto14_InternalParseEPKcPN6google8protobuf8internal12ParseContextE\r\n000000000012765c T __ZN13sentencepiece10ModelProto16default_instanceEv\r\n0000000000128334 T __ZN13sentencepiece10ModelProto21CheckTypeAndMergeFromERKN6google8protobuf11MessageLiteE\r\n00000000001276a0 T __ZN13sentencepiece10ModelProto5ClearEv\r\n0000000000128620 T __ZN13sentencepiece10ModelProto8CopyFromERKS0_\r\n0000000000127650 T __ZN13sentencepiece10ModelProto9ArenaDtorEPv\r\n0000000000128338 T __ZN13sentencepiece10ModelProto9MergeFromERKS0_\r\n0000000000127168 T __ZN13sentencepiece10ModelProto9_Internal12trainer_specEPKS0_\r\n0000000000127178 T __ZN13sentencepiece10ModelProto9_Internal14self_test_dataEPKS0_\r\n```\r\n\r\n\n", "before_files": [{"content": "import os\nimport platform\nimport subprocess\nfrom pathlib import Path\n\nfrom torch.utils.cpp_extension import (\n    CppExtension,\n    BuildExtension as TorchBuildExtension\n)\n\n__all__ = [\n    'get_ext_modules',\n    'BuildExtension',\n]\n\n_ROOT_DIR = Path(__file__).parent.parent.parent.resolve()\n_CSRC_DIR = _ROOT_DIR / 'torchtext' / 'csrc'\n_TP_BASE_DIR = _ROOT_DIR / 'third_party'\n_TP_INSTALL_DIR = _TP_BASE_DIR / 'build'\n\n\ndef _get_eca(debug):\n    eca = []\n    if platform.system() == \"Windows\":\n        eca += ['/MT']\n    if debug:\n        eca += [\"-O0\", \"-g\"]\n    else:\n        if platform.system() == \"Windows\":\n            eca += ['-O2']\n        else:\n            eca += [\"-O3\"]\n    return eca\n\n\ndef _get_ela(debug):\n    ela = []\n    if debug:\n        if platform.system() == \"Windows\":\n            ela += [\"/DEBUG:FULL\"]\n        else:\n            ela += [\"-O0\", \"-g\"]\n    else:\n        if platform.system() != \"Windows\":\n            ela += [\"-O3\"]\n    return ela\n\n\ndef _get_srcs():\n    return [str(p) for p in _CSRC_DIR.glob('**/*.cpp')]\n\n\ndef _get_include_dirs():\n    return [\n        str(_CSRC_DIR),\n        str(_TP_INSTALL_DIR / 'include'),\n    ]\n\n\ndef _get_library_dirs():\n    return [\n        str(_TP_INSTALL_DIR / 'lib'),\n        str(_TP_INSTALL_DIR / 'lib64')\n    ]\n\n\ndef _get_libraries():\n    # NOTE: The order of the library listed bellow matters.\n    #\n    # For example, the symbol `sentencepiece::unigram::Model` is\n    # defined in sentencepiece but UNDEFINED in sentencepiece_train.\n    # GCC only remembers the last encountered symbol.\n    # Therefore placing 'sentencepiece_train' after 'sentencepiece' cause runtime error.\n    #\n    # $ nm third_party/build/lib/libsentencepiece_train.a | grep _ZTIN13sentencepiece7unigram5ModelE\n    #                  U _ZTIN13sentencepiece7unigram5ModelE\n    # $ nm third_party/build/lib/libsentencepiece.a       | grep _ZTIN13sentencepiece7unigram5ModelE\n    # 0000000000000000 V _ZTIN13sentencepiece7unigram5ModelE\n    return [\n        'sentencepiece_train',\n        'sentencepiece',\n        're2',\n        'double-conversion'\n    ]\n\n\ndef _get_cxx11_abi():\n    try:\n        import torch\n        value = int(torch._C._GLIBCXX_USE_CXX11_ABI)\n    except ImportError:\n        value = 0\n    return '-D_GLIBCXX_USE_CXX11_ABI=' + str(value)\n\n\ndef _build_third_party(debug):\n    build_dir = _TP_BASE_DIR / 'build'\n    build_dir.mkdir(exist_ok=True)\n    build_env = os.environ.copy()\n    config = 'Debug' if debug else 'Release'\n    if platform.system() == 'Windows':\n        extra_args = [\n            '-GNinja',\n        ]\n        build_env.setdefault('CC', 'cl')\n        build_env.setdefault('CXX', 'cl')\n    else:\n        extra_args = ['-DCMAKE_CXX_FLAGS=-fPIC ' + _get_cxx11_abi()]\n    subprocess.run(\n        args=[\n            'cmake',\n            '-DBUILD_SHARED_LIBS=OFF',\n            '-DRE2_BUILD_TESTING=OFF',\n            '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',\n            f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',\n            f'-DCMAKE_BUILD_TYPE={config}',\n        ] + extra_args + ['..'],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n    print('*** Command list Thirdparty ***')\n    with open(build_dir / 'compile_commands.json', 'r') as fileobj:\n        print(fileobj.read())\n    print('running cmake --build', flush=True)\n    subprocess.run(\n        args=['cmake', '--build', '.', '--target', 'install', '--config', config],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n\n\ndef _build_sentence_piece(debug):\n    build_dir = _TP_BASE_DIR / 'sentencepiece' / 'build'\n    build_dir.mkdir(exist_ok=True)\n    build_env = os.environ.copy()\n    config = 'Debug' if debug else 'Release'\n    if platform.system() == 'Windows':\n        extra_args = ['-GNinja']\n        build_env.setdefault('CC', 'cl')\n        build_env.setdefault('CXX', 'cl')\n    else:\n        extra_args = []\n    subprocess.run(\n        args=['cmake', '-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',\n              '-DCMAKE_CXX_FLAGS=' + _get_cxx11_abi(),\n              f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n    subprocess.run(\n        args=['cmake', '--build', '.', '--target', 'install', '--config', config],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n\n\ndef _configure_third_party(debug):\n    _build_third_party(debug)\n    _build_sentence_piece(debug)\n\n\n_EXT_NAME = 'torchtext._torchtext'\n\n\ndef get_ext_modules(debug=False):\n    return [\n        CppExtension(\n            _EXT_NAME,\n            _get_srcs(),\n            libraries=_get_libraries(),\n            include_dirs=_get_include_dirs(),\n            library_dirs=_get_library_dirs(),\n            extra_compile_args=_get_eca(debug),\n            extra_link_args=_get_ela(debug),\n        ),\n    ]\n\n\nclass BuildExtension(TorchBuildExtension):\n    def build_extension(self, ext):\n        if ext.name == _EXT_NAME:\n            _configure_third_party(self.debug)\n        super().build_extension(ext)\n", "path": "build_tools/setup_helpers/extension.py"}], "after_files": [{"content": "import os\nimport platform\nimport subprocess\nfrom pathlib import Path\n\nfrom torch.utils.cpp_extension import (\n    CppExtension,\n    BuildExtension as TorchBuildExtension\n)\n\n__all__ = [\n    'get_ext_modules',\n    'BuildExtension',\n]\n\n_ROOT_DIR = Path(__file__).parent.parent.parent.resolve()\n_CSRC_DIR = _ROOT_DIR / 'torchtext' / 'csrc'\n_TP_BASE_DIR = _ROOT_DIR / 'third_party'\n_TP_INSTALL_DIR = _TP_BASE_DIR / 'build'\n\n\ndef _get_eca(debug):\n    eca = []\n    if platform.system() == \"Windows\":\n        eca += ['/MT']\n    if debug:\n        eca += [\"-O0\", \"-g\"]\n    else:\n        if platform.system() == \"Windows\":\n            eca += ['-O2']\n        else:\n            eca += [\"-O3\", \"-fvisibility=hidden\"]\n    return eca\n\n\ndef _get_ela(debug):\n    ela = []\n    if debug:\n        if platform.system() == \"Windows\":\n            ela += [\"/DEBUG:FULL\"]\n        else:\n            ela += [\"-O0\", \"-g\"]\n    else:\n        if platform.system() != \"Windows\":\n            ela += [\"-O3\"]\n    return ela\n\n\ndef _get_srcs():\n    return [str(p) for p in _CSRC_DIR.glob('**/*.cpp')]\n\n\ndef _get_include_dirs():\n    return [\n        str(_CSRC_DIR),\n        str(_TP_INSTALL_DIR / 'include'),\n    ]\n\n\ndef _get_library_dirs():\n    return [\n        str(_TP_INSTALL_DIR / 'lib'),\n        str(_TP_INSTALL_DIR / 'lib64')\n    ]\n\n\ndef _get_libraries():\n    # NOTE: The order of the library listed bellow matters.\n    #\n    # For example, the symbol `sentencepiece::unigram::Model` is\n    # defined in sentencepiece but UNDEFINED in sentencepiece_train.\n    # GCC only remembers the last encountered symbol.\n    # Therefore placing 'sentencepiece_train' after 'sentencepiece' cause runtime error.\n    #\n    # $ nm third_party/build/lib/libsentencepiece_train.a | grep _ZTIN13sentencepiece7unigram5ModelE\n    #                  U _ZTIN13sentencepiece7unigram5ModelE\n    # $ nm third_party/build/lib/libsentencepiece.a       | grep _ZTIN13sentencepiece7unigram5ModelE\n    # 0000000000000000 V _ZTIN13sentencepiece7unigram5ModelE\n    return [\n        'sentencepiece_train',\n        'sentencepiece',\n        're2',\n        'double-conversion'\n    ]\n\n\ndef _get_cxx11_abi():\n    try:\n        import torch\n        value = int(torch._C._GLIBCXX_USE_CXX11_ABI)\n    except ImportError:\n        value = 0\n    return '-D_GLIBCXX_USE_CXX11_ABI=' + str(value)\n\n\ndef _build_third_party(debug):\n    build_dir = _TP_BASE_DIR / 'build'\n    build_dir.mkdir(exist_ok=True)\n    build_env = os.environ.copy()\n    config = 'Debug' if debug else 'Release'\n    if platform.system() == 'Windows':\n        extra_args = [\n            '-GNinja',\n        ]\n        build_env.setdefault('CC', 'cl')\n        build_env.setdefault('CXX', 'cl')\n    else:\n        extra_args = ['-DCMAKE_CXX_FLAGS=-fPIC ' + _get_cxx11_abi()]\n    subprocess.run(\n        args=[\n            'cmake',\n            '-DBUILD_SHARED_LIBS=OFF',\n            '-DRE2_BUILD_TESTING=OFF',\n            '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',\n            f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',\n            f'-DCMAKE_BUILD_TYPE={config}',\n            '-DCMAKE_CXX_VISIBILITY_PRESET=hidden',\n            '-DCMAKE_POLICY_DEFAULT_CMP0063=NEW',\n        ] + extra_args + ['..'],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n    print('*** Command list Thirdparty ***')\n    with open(build_dir / 'compile_commands.json', 'r') as fileobj:\n        print(fileobj.read())\n    print('running cmake --build', flush=True)\n    subprocess.run(\n        args=['cmake', '--build', '.', '--target', 'install', '--config', config],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n\n\ndef _build_sentence_piece(debug):\n    build_dir = _TP_BASE_DIR / 'sentencepiece' / 'build'\n    build_dir.mkdir(exist_ok=True)\n    build_env = os.environ.copy()\n    config = 'Debug' if debug else 'Release'\n    if platform.system() == 'Windows':\n        extra_args = ['-GNinja']\n        build_env.setdefault('CC', 'cl')\n        build_env.setdefault('CXX', 'cl')\n    else:\n        extra_args = []\n    subprocess.run(\n        args=['cmake', '-DSPM_ENABLE_SHARED=OFF', f'-DCMAKE_INSTALL_PREFIX={_TP_INSTALL_DIR}',\n              '-DCMAKE_CXX_VISIBILITY_PRESET=hidden',\n              '-DCMAKE_CXX_FLAGS=' + _get_cxx11_abi(),\n              '-DCMAKE_POLICY_DEFAULT_CMP0063=NEW',\n              f'-DCMAKE_BUILD_TYPE={config}'] + extra_args + ['..'],\n\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n    subprocess.run(\n        args=['cmake', '--build', '.', '--target', 'install', '--config', config],\n        cwd=str(build_dir),\n        check=True,\n        env=build_env,\n    )\n\n\ndef _configure_third_party(debug):\n    _build_third_party(debug)\n    _build_sentence_piece(debug)\n\n\n_EXT_NAME = 'torchtext._torchtext'\n\n\ndef get_ext_modules(debug=False):\n    return [\n        CppExtension(\n            _EXT_NAME,\n            _get_srcs(),\n            libraries=_get_libraries(),\n            include_dirs=_get_include_dirs(),\n            library_dirs=_get_library_dirs(),\n            extra_compile_args=_get_eca(debug),\n            extra_link_args=_get_ela(debug),\n        ),\n    ]\n\n\nclass BuildExtension(TorchBuildExtension):\n    def build_extension(self, ext):\n        if ext.name == _EXT_NAME:\n            _configure_third_party(self.debug)\n        super().build_extension(ext)\n", "path": "build_tools/setup_helpers/extension.py"}]}