We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
RPath compiler wrapper breaking precompiled header builds
This issue was found when building OpenCV-4.0.1-foss-2018b-Python-3.6.6.eb with EB 4.1.1. The build has multiple errors `undefined reference to main`. This is caused by the rpath wrappers adding `-Wl,-rpath=...` options to the g++ call, which turns otherwise compile-only commands to generate precompiled headers (`-x c++-header`) into commands that link. 

See [easybuild-OpenCV-4.0.1-20200623.143513.mcEaZ.log.gz](https://github.com/easybuilders/easybuild-framework/files/4819395/easybuild-OpenCV-4.0.1-20200623.143513.mcEaZ.log.gz) for the full logs. But it can also be shown using only the generated rpath wrapper to compile a simple file:

```
paulm@tcn180 14:43 ~$ m list
Currently Loaded Modulefiles:
 1) surfsara   2) 2019   3) EasyBuild/4.1.1   4) compilerwrappers   5) eb/4.1.1(default)   6) GCCcore/8.2.0   7) zlib/1.2.11-GCCcore-8.2.0   8) binutils/2.31.1-GCCcore-8.2.0   9) GCC/8.2.0-2.31.1  

paulm@tcn180:~$ cat t.cc
#include <cstdio>

# Straight g++ call, no wrappers, succeeds
paulm@tcn180 14:45 ~$ /sw/arch/RedHatEnterpriseServer7/EB_production/2019/software/GCCcore/8.2.0/bin/g++ -x c++-header t.cc
paulm@tcn180 14:45 ~$ 

# Wrapped call, fails
paulm@tcn180 14:45 ~$ /scratch-shared/paulm/eb-3OiLzK/tmpvR7vdm/rpath_wrappers/gxx_wrapper/g++ -x c++-header t.cc 
/lib/../lib64/crt1.o(.text+0x20): error: undefined reference to 'main'
collect2: error: ld returned 1 exit status

# Straight g++ call with -Wl,-rpath addition, no wrappers, fails
paulm@tcn180 14:46 ~$ /sw/arch/RedHatEnterpriseServer7/EB_production/2019/software/GCCcore/8.2.0/bin/g++ -x c++-header -Wl,-rpath=/tmp/doh t.cc
/lib/../lib64/crt1.o(.text+0x20): error: undefined reference to 'main'
collect2: error: ld returned 1 exit status
```

We (me and @casparvl) suggest that the rpath wrappers check for the `-x c++-header` (and similar) options to make sure an otherwise correct call of g++ is not turned into one that fails. Note that there is a bit of a mist as to the expected behaviour of GCC with various options, as the docs aren't entirely clear:

* For example, calling `g++ t.cc` fails if `t.cc` does not contain a main function as it does linking of the generated object code. But calling `g++ -x c++-header t.cc` apparently turns on compile-only mode and succeeds (but the [gcc docs](https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html) only say: "To create a precompiled header file, simply compile it as you would any other file, if necessary using the -x option to make the driver treat it as a C or C++ header file")
* Adding `-Wl,-rpath=...` makes GCC link (although the docs do not specify this), unless `-c` is used, in which case linking is never done.
* The [examples in the GCC docs of using precompiled headers](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_headers.html) do not use `-c` when using `-x c++-header`. But upstream package could be more explicit by using `-c -x c++-header`, which would still work when the RPATH wrappers would add `-Wl,-rpath=...`, but it can't really be expected of those packages to handle that case of downstream building.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `easybuild/scripts/rpath_args.py`
Content:
```
1 #!/usr/bin/env python
2 ##
3 # Copyright 2016-2020 Ghent University
4 #
5 # This file is part of EasyBuild,
6 # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
7 # with support of Ghent University (http://ugent.be/hpc),
8 # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
9 # Flemish Research Foundation (FWO) (http://www.fwo.be/en)
10 # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
11 #
12 # https://github.com/easybuilders/easybuild
13 #
14 # EasyBuild is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation v2.
17 #
18 # EasyBuild is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
25 ##
26 """
27 Utility script used by RPATH wrapper script;
28 output is statements that define the following environment variables
29 * $CMD_ARGS: new list of command line arguments to pass
30 * $RPATH_ARGS: command line option to specify list of paths to RPATH
31 
32 author: Kenneth Hoste (HPC-UGent)
33 """
34 import os
35 import re
36 import sys
37 
38 
39 cmd = sys.argv[1]
40 rpath_filter = sys.argv[2]
41 rpath_include = sys.argv[3]
42 args = sys.argv[4:]
43 
44 # wheter or not to use -Wl to pass options to the linker
45 if cmd in ['ld', 'ld.gold', 'ld.bfd']:
46     flag_prefix = ''
47 else:
48     flag_prefix = '-Wl,'
49 
50 rpath_filter = rpath_filter.split(',')
51 if rpath_filter:
52     rpath_filter = re.compile('^%s$' % '|'.join(rpath_filter))
53 else:
54     rpath_filter = None
55 
56 if rpath_include:
57     rpath_include = rpath_include.split(',')
58 else:
59     rpath_include = []
60 
61 version_mode = False
62 cmd_args, cmd_args_rpath = [], []
63 
64 # process list of original command line arguments
65 idx = 0
66 while idx < len(args):
67 
68     arg = args[idx]
69 
70     # if command is run in 'version check' mode, make sure we don't include *any* -rpath arguments
71     if arg in ['-v', '-V', '--version', '-dumpversion']:
72         version_mode = True
73         cmd_args.append(arg)
74 
75     # FIXME: also consider $LIBRARY_PATH?
76     # FIXME: support to hard inject additional library paths?
77     # FIXME: support to specify list of path prefixes that should not be RPATH'ed into account?
78     # FIXME skip paths in /tmp, build dir, etc.?
79 
80     # handle -L flags, inject corresponding -rpath flag
81     elif arg.startswith('-L'):
82         # take into account that argument to -L may be separated with one or more spaces...
83         if arg == '-L':
84             # actual library path is next argument when arg='-L'
85             idx += 1
86             lib_path = args[idx]
87         else:
88             lib_path = arg[2:]
89 
90         if os.path.isabs(lib_path) and (rpath_filter is None or not rpath_filter.match(lib_path)):
91             # inject -rpath flag in front for every -L with an absolute path,
92             # also retain the -L flag (without reordering!)
93             cmd_args_rpath.append(flag_prefix + '-rpath=%s' % lib_path)
94             cmd_args.append('-L%s' % lib_path)
95         else:
96             # don't RPATH in relative paths;
97             # it doesn't make much sense, and it can also break the build because it may result in reordering lib paths
98             cmd_args.append('-L%s' % lib_path)
99 
100     # replace --enable-new-dtags with --disable-new-dtags if it's used;
101     # --enable-new-dtags would result in copying rpath to runpath,
102     # meaning that $LD_LIBRARY_PATH is taken into account again;
103     # --enable-new-dtags is not removed but replaced to prevent issues when linker flag is forwarded from the compiler
104     # to the linker with an extra prefixed flag (either -Xlinker or -Wl,).
105     # In that case, the compiler would erroneously pass the next random argument to the linker.
106     elif arg == flag_prefix + '--enable-new-dtags':
107         cmd_args.append(flag_prefix + '--disable-new-dtags')
108     else:
109         cmd_args.append(arg)
110 
111     idx += 1
112 
113 # add -rpath flags in front
114 cmd_args = cmd_args_rpath + cmd_args
115 
116 cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include]
117 
118 if not version_mode:
119     cmd_args = cmd_args_rpath + [
120         # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags
121         flag_prefix + '--disable-new-dtags',
122     ] + cmd_args
123 
124 # wrap all arguments into single quotes to avoid further bash expansion
125 cmd_args = ["'%s'" % a.replace("'", "''") for a in cmd_args]
126 
127 # output: statement to define $CMD_ARGS and $RPATH_ARGS
128 print("CMD_ARGS=(%s)" % ' '.join(cmd_args))
129
```
--- 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/easybuild/scripts/rpath_args.py b/easybuild/scripts/rpath_args.py
--- a/easybuild/scripts/rpath_args.py
+++ b/easybuild/scripts/rpath_args.py
@@ -41,7 +41,7 @@
 rpath_include = sys.argv[3]
 args = sys.argv[4:]
 
-# wheter or not to use -Wl to pass options to the linker
+# determine whether or not to use -Wl to pass options to the linker based on name of command
 if cmd in ['ld', 'ld.gold', 'ld.bfd']:
     flag_prefix = ''
 else:
@@ -58,7 +58,7 @@
 else:
     rpath_include = []
 
-version_mode = False
+add_rpath_args = True
 cmd_args, cmd_args_rpath = [], []
 
 # process list of original command line arguments
@@ -69,7 +69,16 @@
 
     # if command is run in 'version check' mode, make sure we don't include *any* -rpath arguments
     if arg in ['-v', '-V', '--version', '-dumpversion']:
-        version_mode = True
+        add_rpath_args = False
+        cmd_args.append(arg)
+
+    # compiler options like "-x c++header" imply no linking is done (similar to -c),
+    # so then we must not inject -Wl,-rpath option since they *enable* linking;
+    # see https://github.com/easybuilders/easybuild-framework/issues/3371
+    elif arg == '-x':
+        idx_next = idx + 1
+        if idx_next < len(args) and args[idx_next] in ['c-header', 'c++-header']:
+            add_rpath_args = False
         cmd_args.append(arg)
 
     # FIXME: also consider $LIBRARY_PATH?
@@ -110,16 +119,15 @@
 
     idx += 1
 
-# add -rpath flags in front
-cmd_args = cmd_args_rpath + cmd_args
+if add_rpath_args:
+    # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags
+    cmd_args_rpath.insert(0, flag_prefix + '--disable-new-dtags')
 
-cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include]
+    # add -rpath options for paths listed in rpath_include
+    cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include] + cmd_args_rpath
 
-if not version_mode:
-    cmd_args = cmd_args_rpath + [
-        # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags
-        flag_prefix + '--disable-new-dtags',
-    ] + cmd_args
+    # add -rpath flags in front
+    cmd_args = cmd_args_rpath + cmd_args
 
 # wrap all arguments into single quotes to avoid further bash expansion
 cmd_args = ["'%s'" % a.replace("'", "''") for a in cmd_args]

{"golden_diff": "diff --git a/easybuild/scripts/rpath_args.py b/easybuild/scripts/rpath_args.py\n--- a/easybuild/scripts/rpath_args.py\n+++ b/easybuild/scripts/rpath_args.py\n@@ -41,7 +41,7 @@\n rpath_include = sys.argv[3]\n args = sys.argv[4:]\n \n-# wheter or not to use -Wl to pass options to the linker\n+# determine whether or not to use -Wl to pass options to the linker based on name of command\n if cmd in ['ld', 'ld.gold', 'ld.bfd']:\n     flag_prefix = ''\n else:\n@@ -58,7 +58,7 @@\n else:\n     rpath_include = []\n \n-version_mode = False\n+add_rpath_args = True\n cmd_args, cmd_args_rpath = [], []\n \n # process list of original command line arguments\n@@ -69,7 +69,16 @@\n \n     # if command is run in 'version check' mode, make sure we don't include *any* -rpath arguments\n     if arg in ['-v', '-V', '--version', '-dumpversion']:\n-        version_mode = True\n+        add_rpath_args = False\n+        cmd_args.append(arg)\n+\n+    # compiler options like \"-x c++header\" imply no linking is done (similar to -c),\n+    # so then we must not inject -Wl,-rpath option since they *enable* linking;\n+    # see https://github.com/easybuilders/easybuild-framework/issues/3371\n+    elif arg == '-x':\n+        idx_next = idx + 1\n+        if idx_next < len(args) and args[idx_next] in ['c-header', 'c++-header']:\n+            add_rpath_args = False\n         cmd_args.append(arg)\n \n     # FIXME: also consider $LIBRARY_PATH?\n@@ -110,16 +119,15 @@\n \n     idx += 1\n \n-# add -rpath flags in front\n-cmd_args = cmd_args_rpath + cmd_args\n+if add_rpath_args:\n+    # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags\n+    cmd_args_rpath.insert(0, flag_prefix + '--disable-new-dtags')\n \n-cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include]\n+    # add -rpath options for paths listed in rpath_include\n+    cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include] + cmd_args_rpath\n \n-if not version_mode:\n-    cmd_args = cmd_args_rpath + [\n-        # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags\n-        flag_prefix + '--disable-new-dtags',\n-    ] + cmd_args\n+    # add -rpath flags in front\n+    cmd_args = cmd_args_rpath + cmd_args\n \n # wrap all arguments into single quotes to avoid further bash expansion\n cmd_args = [\"'%s'\" % a.replace(\"'\", \"''\") for a in cmd_args]\n", "issue": "RPath compiler wrapper breaking precompiled header builds\nThis issue was found when building OpenCV-4.0.1-foss-2018b-Python-3.6.6.eb with EB 4.1.1. The build has multiple errors `undefined reference to main`. This is caused by the rpath wrappers adding `-Wl,-rpath=...` options to the g++ call, which turns otherwise compile-only commands to generate precompiled headers (`-x c++-header`) into commands that link. \r\n\r\nSee [easybuild-OpenCV-4.0.1-20200623.143513.mcEaZ.log.gz](https://github.com/easybuilders/easybuild-framework/files/4819395/easybuild-OpenCV-4.0.1-20200623.143513.mcEaZ.log.gz) for the full logs. But it can also be shown using only the generated rpath wrapper to compile a simple file:\r\n\r\n```\r\npaulm@tcn180 14:43 ~$ m list\r\nCurrently Loaded Modulefiles:\r\n 1) surfsara   2) 2019   3) EasyBuild/4.1.1   4) compilerwrappers   5) eb/4.1.1(default)   6) GCCcore/8.2.0   7) zlib/1.2.11-GCCcore-8.2.0   8) binutils/2.31.1-GCCcore-8.2.0   9) GCC/8.2.0-2.31.1  \r\n\r\npaulm@tcn180:~$ cat t.cc\r\n#include <cstdio>\r\n\r\n# Straight g++ call, no wrappers, succeeds\r\npaulm@tcn180 14:45 ~$ /sw/arch/RedHatEnterpriseServer7/EB_production/2019/software/GCCcore/8.2.0/bin/g++ -x c++-header t.cc\r\npaulm@tcn180 14:45 ~$ \r\n\r\n# Wrapped call, fails\r\npaulm@tcn180 14:45 ~$ /scratch-shared/paulm/eb-3OiLzK/tmpvR7vdm/rpath_wrappers/gxx_wrapper/g++ -x c++-header t.cc \r\n/lib/../lib64/crt1.o(.text+0x20): error: undefined reference to 'main'\r\ncollect2: error: ld returned 1 exit status\r\n\r\n# Straight g++ call with -Wl,-rpath addition, no wrappers, fails\r\npaulm@tcn180 14:46 ~$ /sw/arch/RedHatEnterpriseServer7/EB_production/2019/software/GCCcore/8.2.0/bin/g++ -x c++-header -Wl,-rpath=/tmp/doh t.cc\r\n/lib/../lib64/crt1.o(.text+0x20): error: undefined reference to 'main'\r\ncollect2: error: ld returned 1 exit status\r\n```\r\n\r\nWe (me and @casparvl) suggest that the rpath wrappers check for the `-x c++-header` (and similar) options to make sure an otherwise correct call of g++ is not turned into one that fails. Note that there is a bit of a mist as to the expected behaviour of GCC with various options, as the docs aren't entirely clear:\r\n\r\n* For example, calling `g++ t.cc` fails if `t.cc` does not contain a main function as it does linking of the generated object code. But calling `g++ -x c++-header t.cc` apparently turns on compile-only mode and succeeds (but the [gcc docs](https://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html) only say: \"To create a precompiled header file, simply compile it as you would any other file, if necessary using the -x option to make the driver treat it as a C or C++ header file\")\r\n* Adding `-Wl,-rpath=...` makes GCC link (although the docs do not specify this), unless `-c` is used, in which case linking is never done.\r\n* The [examples in the GCC docs of using precompiled headers](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_headers.html) do not use `-c` when using `-x c++-header`. But upstream package could be more explicit by using `-c -x c++-header`, which would still work when the RPATH wrappers would add `-Wl,-rpath=...`, but it can't really be expected of those packages to handle that case of downstream building.\n", "before_files": [{"content": "#!/usr/bin/env python\n##\n# Copyright 2016-2020 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nUtility script used by RPATH wrapper script;\noutput is statements that define the following environment variables\n* $CMD_ARGS: new list of command line arguments to pass\n* $RPATH_ARGS: command line option to specify list of paths to RPATH\n\nauthor: Kenneth Hoste (HPC-UGent)\n\"\"\"\nimport os\nimport re\nimport sys\n\n\ncmd = sys.argv[1]\nrpath_filter = sys.argv[2]\nrpath_include = sys.argv[3]\nargs = sys.argv[4:]\n\n# wheter or not to use -Wl to pass options to the linker\nif cmd in ['ld', 'ld.gold', 'ld.bfd']:\n    flag_prefix = ''\nelse:\n    flag_prefix = '-Wl,'\n\nrpath_filter = rpath_filter.split(',')\nif rpath_filter:\n    rpath_filter = re.compile('^%s$' % '|'.join(rpath_filter))\nelse:\n    rpath_filter = None\n\nif rpath_include:\n    rpath_include = rpath_include.split(',')\nelse:\n    rpath_include = []\n\nversion_mode = False\ncmd_args, cmd_args_rpath = [], []\n\n# process list of original command line arguments\nidx = 0\nwhile idx < len(args):\n\n    arg = args[idx]\n\n    # if command is run in 'version check' mode, make sure we don't include *any* -rpath arguments\n    if arg in ['-v', '-V', '--version', '-dumpversion']:\n        version_mode = True\n        cmd_args.append(arg)\n\n    # FIXME: also consider $LIBRARY_PATH?\n    # FIXME: support to hard inject additional library paths?\n    # FIXME: support to specify list of path prefixes that should not be RPATH'ed into account?\n    # FIXME skip paths in /tmp, build dir, etc.?\n\n    # handle -L flags, inject corresponding -rpath flag\n    elif arg.startswith('-L'):\n        # take into account that argument to -L may be separated with one or more spaces...\n        if arg == '-L':\n            # actual library path is next argument when arg='-L'\n            idx += 1\n            lib_path = args[idx]\n        else:\n            lib_path = arg[2:]\n\n        if os.path.isabs(lib_path) and (rpath_filter is None or not rpath_filter.match(lib_path)):\n            # inject -rpath flag in front for every -L with an absolute path,\n            # also retain the -L flag (without reordering!)\n            cmd_args_rpath.append(flag_prefix + '-rpath=%s' % lib_path)\n            cmd_args.append('-L%s' % lib_path)\n        else:\n            # don't RPATH in relative paths;\n            # it doesn't make much sense, and it can also break the build because it may result in reordering lib paths\n            cmd_args.append('-L%s' % lib_path)\n\n    # replace --enable-new-dtags with --disable-new-dtags if it's used;\n    # --enable-new-dtags would result in copying rpath to runpath,\n    # meaning that $LD_LIBRARY_PATH is taken into account again;\n    # --enable-new-dtags is not removed but replaced to prevent issues when linker flag is forwarded from the compiler\n    # to the linker with an extra prefixed flag (either -Xlinker or -Wl,).\n    # In that case, the compiler would erroneously pass the next random argument to the linker.\n    elif arg == flag_prefix + '--enable-new-dtags':\n        cmd_args.append(flag_prefix + '--disable-new-dtags')\n    else:\n        cmd_args.append(arg)\n\n    idx += 1\n\n# add -rpath flags in front\ncmd_args = cmd_args_rpath + cmd_args\n\ncmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include]\n\nif not version_mode:\n    cmd_args = cmd_args_rpath + [\n        # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags\n        flag_prefix + '--disable-new-dtags',\n    ] + cmd_args\n\n# wrap all arguments into single quotes to avoid further bash expansion\ncmd_args = [\"'%s'\" % a.replace(\"'\", \"''\") for a in cmd_args]\n\n# output: statement to define $CMD_ARGS and $RPATH_ARGS\nprint(\"CMD_ARGS=(%s)\" % ' '.join(cmd_args))\n", "path": "easybuild/scripts/rpath_args.py"}], "after_files": [{"content": "#!/usr/bin/env python\n##\n# Copyright 2016-2020 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nUtility script used by RPATH wrapper script;\noutput is statements that define the following environment variables\n* $CMD_ARGS: new list of command line arguments to pass\n* $RPATH_ARGS: command line option to specify list of paths to RPATH\n\nauthor: Kenneth Hoste (HPC-UGent)\n\"\"\"\nimport os\nimport re\nimport sys\n\n\ncmd = sys.argv[1]\nrpath_filter = sys.argv[2]\nrpath_include = sys.argv[3]\nargs = sys.argv[4:]\n\n# determine whether or not to use -Wl to pass options to the linker based on name of command\nif cmd in ['ld', 'ld.gold', 'ld.bfd']:\n    flag_prefix = ''\nelse:\n    flag_prefix = '-Wl,'\n\nrpath_filter = rpath_filter.split(',')\nif rpath_filter:\n    rpath_filter = re.compile('^%s$' % '|'.join(rpath_filter))\nelse:\n    rpath_filter = None\n\nif rpath_include:\n    rpath_include = rpath_include.split(',')\nelse:\n    rpath_include = []\n\nadd_rpath_args = True\ncmd_args, cmd_args_rpath = [], []\n\n# process list of original command line arguments\nidx = 0\nwhile idx < len(args):\n\n    arg = args[idx]\n\n    # if command is run in 'version check' mode, make sure we don't include *any* -rpath arguments\n    if arg in ['-v', '-V', '--version', '-dumpversion']:\n        add_rpath_args = False\n        cmd_args.append(arg)\n\n    # compiler options like \"-x c++header\" imply no linking is done (similar to -c),\n    # so then we must not inject -Wl,-rpath option since they *enable* linking;\n    # see https://github.com/easybuilders/easybuild-framework/issues/3371\n    elif arg == '-x':\n        idx_next = idx + 1\n        if idx_next < len(args) and args[idx_next] in ['c-header', 'c++-header']:\n            add_rpath_args = False\n        cmd_args.append(arg)\n\n    # FIXME: also consider $LIBRARY_PATH?\n    # FIXME: support to hard inject additional library paths?\n    # FIXME: support to specify list of path prefixes that should not be RPATH'ed into account?\n    # FIXME skip paths in /tmp, build dir, etc.?\n\n    # handle -L flags, inject corresponding -rpath flag\n    elif arg.startswith('-L'):\n        # take into account that argument to -L may be separated with one or more spaces...\n        if arg == '-L':\n            # actual library path is next argument when arg='-L'\n            idx += 1\n            lib_path = args[idx]\n        else:\n            lib_path = arg[2:]\n\n        if os.path.isabs(lib_path) and (rpath_filter is None or not rpath_filter.match(lib_path)):\n            # inject -rpath flag in front for every -L with an absolute path,\n            # also retain the -L flag (without reordering!)\n            cmd_args_rpath.append(flag_prefix + '-rpath=%s' % lib_path)\n            cmd_args.append('-L%s' % lib_path)\n        else:\n            # don't RPATH in relative paths;\n            # it doesn't make much sense, and it can also break the build because it may result in reordering lib paths\n            cmd_args.append('-L%s' % lib_path)\n\n    # replace --enable-new-dtags with --disable-new-dtags if it's used;\n    # --enable-new-dtags would result in copying rpath to runpath,\n    # meaning that $LD_LIBRARY_PATH is taken into account again;\n    # --enable-new-dtags is not removed but replaced to prevent issues when linker flag is forwarded from the compiler\n    # to the linker with an extra prefixed flag (either -Xlinker or -Wl,).\n    # In that case, the compiler would erroneously pass the next random argument to the linker.\n    elif arg == flag_prefix + '--enable-new-dtags':\n        cmd_args.append(flag_prefix + '--disable-new-dtags')\n    else:\n        cmd_args.append(arg)\n\n    idx += 1\n\nif add_rpath_args:\n    # try to make sure that RUNPATH is not used by always injecting --disable-new-dtags\n    cmd_args_rpath.insert(0, flag_prefix + '--disable-new-dtags')\n\n    # add -rpath options for paths listed in rpath_include\n    cmd_args_rpath = [flag_prefix + '-rpath=%s' % inc for inc in rpath_include] + cmd_args_rpath\n\n    # add -rpath flags in front\n    cmd_args = cmd_args_rpath + cmd_args\n\n# wrap all arguments into single quotes to avoid further bash expansion\ncmd_args = [\"'%s'\" % a.replace(\"'\", \"''\") for a in cmd_args]\n\n# output: statement to define $CMD_ARGS and $RPATH_ARGS\nprint(\"CMD_ARGS=(%s)\" % ' '.join(cmd_args))\n", "path": "easybuild/scripts/rpath_args.py"}]}