Skip to content

Commit 9ef1042

Browse files
committed
ompi_setup_fc.m4: use -Wl,-ld_classic if supported
Per #12427, on MacOS, add -Wl,-ld_classic to the Fortran wrapper compiler if that flag is needed. Specifically, Open MPI has used -Wl,-commons,use_dylibs for decades to support common symbols (e.g., MPI_BOTTOM) in the Fortran bindings. There is a window of Xcode versions where this switch was effectively disabled; it effectively required the additional -Wl,-ld_classic switch to force the use of the "old" Apple linker (that still supported -Wl,-commons,use_dylibs). Update the configury to test whether we need -Wl,-ld_classic or not. Signed-off-by: Jeff Squyres <[email protected]>
1 parent 8b7e577 commit 9ef1042

File tree

1 file changed

+162
-14
lines changed

1 file changed

+162
-14
lines changed

config/ompi_setup_fc.m4

Lines changed: 162 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,168 @@ AC_DEFUN_ONCE([_OMPI_SETUP_FC_COMPILER],[
5050

5151
#############################################################################
5252

53+
dnl On macOS with Xcode, test whether -Wl,-commons,use_dylibs works
54+
dnl by itself or whether it also needs -Wl,-ld_classic.
55+
dnl
56+
dnl * It seems to always work (by itself) when building static
57+
dnl libraries.
58+
dnl * It seems to fail (by itself) when building shared libraries for
59+
dnl certain versions of Xcode. In these failure scenarios, we add
60+
dnl -Wl,-ld_classic to make it work.
61+
dnl
62+
dnl Note: the -ld_classic flag works with both static and shared
63+
dnl libraries, so it is safe to always do this test -- even if
64+
dnl we are only building static libraries.
65+
dnl
66+
dnl The history is that for a long time (decades),
67+
dnl -Wl,-commons,use_dylibs worked by itself. But then Apple decided
68+
dnl to remove support for it, and cause link-time errors with MPI
69+
dnl Fortran sentinel values (e.g., MPI_BOTTOM) because they are
70+
dnl implemented with Fortran common blocks. Later, Xcode v16
71+
dnl (re)added support for -Wl,commons,use_dylibs again. Hence, there
72+
dnl is a window of a few versions of Xcode that need the additional
73+
dnl -Wl,ld_classic flag to link/work properly.
74+
dnl
75+
dnl We have to use a slightly complex test code that will actually
76+
dnl fail if the version of Xcode being used requires -Wl,-ld_classic
77+
dnl with -Wl,-commons,use_dylibs.
78+
dnl
79+
dnl 1. Build a shared library (with C source code) with a public
80+
dnl symbol that can be used as a Fortran common block symbol.
81+
dnl 2. Compile a Fortran program that calls a function in the shared
82+
dnl library, and link it against the shared library.
83+
dnl
84+
dnl Note: This is a linker test; we are checking to see if this all
85+
dnl compiles and links properly. The logic in the C / Fortran code
86+
dnl below specifically does not test for correctness because we do not
87+
dnl actually run the code.
88+
AC_DEFUN([_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS],[
89+
OPAL_VAR_SCOPE_PUSH([xcode_flags])
90+
91+
# This variable is used by the invoking macro to display the
92+
# results via AC RESULT (just to keep the symmetry of
93+
# MSG_CHECKING / RESULT in the same upper-level macro).
94+
OMPI_FORTRAN_WRAPPER_FLAGS=
95+
96+
xcode_flags="-Wl,-commons,use_dylibs"
97+
_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND(
98+
[$xcode_flags],
99+
[OMPI_FORTRAN_WRAPPER_FLAGS=$xcode_flags], [])
100+
AS_IF([test -z "$OMPI_FORTRAN_WRAPPER_FLAGS"],
101+
[xcode_flags="-Wl,-commons,use_dylibs -Wl,-ld_classic"
102+
_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND(
103+
[$xcode_flags],
104+
[OMPI_FORTRAN_WRAPPER_FLAGS=$xcode_flags], [])])
105+
AS_IF([test -z "$OMPI_FORTRAN_WRAPPER_FLAGS"],
106+
[OMPI_FORTRAN_WRAPPER_FLAGS="none"])
107+
108+
OPAL_VAR_SCOPE_POP
109+
])
110+
111+
dnl Companion to _OMPI SETUP_FC_XCODE_COMMONS_LDFLAGS;
112+
dnl see that macro for an explanation of this macro.
113+
dnl
114+
dnl $1: LDFLAGS to test
115+
dnl $2: action to perform upon success
116+
dnl $3: action to perform upon failure
117+
AC_DEFUN([_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND],[
118+
OPAL_VAR_SCOPE_PUSH([xcode_happy xcode_dir LDFLAGS_save_xcode LIBS_save_xcode])
119+
120+
xcode_dir=conftest.$$
121+
rm -rf $xcode_dir
122+
mkdir -p $xcode_dir
123+
cd $xcode_dir
124+
125+
LIBS_save_xcode=$LIBS
126+
LDFLAGS_save_xcode=$LDFLAGS
127+
LDFLAGS="$LDFLAGS -L. $1"
128+
129+
# Note: we use COMPILE_IFELSE and LANG_SOURCE below, which assume
130+
# that confdefs.h exists. This is being invoked extremely early
131+
# in the configure sequence, so we haven't AC DEFINE'ed anything
132+
# yet, and therefore confdefs.h won't be automatically created
133+
# yet. So we'll make an empty confdefs.h to avoid some error
134+
# messages (it'll be removed with the whole tempdir, later).
135+
touch confdefs.h
136+
137+
# Step 1: make a C library with some public symbols
138+
xcode_happy=0
139+
AC_LANG_PUSH([C])
140+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
141+
/* Must end the symbol in _ (remember: we are specifically targeting
142+
the MacOS compilation environment, so it is ok to target a specific
143+
Fortran symbol convention), otherwise the Fortran linker will not
144+
find it, and will just create a new Fortran symbol for it */
145+
int ompi_mpi_bottom_ = 42;
146+
147+
void ompi_init_f(int *bogus);
148+
149+
/* Empty / useless function that still ensures that this compilation
150+
unit will not be optimized out */
151+
void ompi_init_f(int *bogus)
152+
{
153+
*bogus = ompi_mpi_bottom_;
154+
}
155+
]])],
156+
[ # If the above compiled successfully, Then use
157+
# conftest.OBJEXT to make the library. Note that
158+
# conftest.OBJEXT will automatically be deleted upon exit of
159+
# COMPILE_IFELSE.
160+
OPAL_LOG_COMMAND([$CC -dynamiclib -Wl,-undefined -Wl,dynamic_lookup $LDFLAGS conftest.$OBJEXT -o libconftest.dylib],
161+
[xcode_happy=1])])
162+
AC_LANG_POP
163+
164+
# Now compile and link a Fortran program against this shared
165+
# library.
166+
AC_LANG_PUSH([Fortran])
167+
AS_IF([test $xcode_happy -eq 1],
168+
[LIBS="$LIBS -lconftest"
169+
AC_LINK_IFELSE([AC_LANG_SOURCE([
170+
program test
171+
integer :: mpi_bottom
172+
common/ompi_mpi_bottom/mpi_bottom
173+
174+
interface
175+
subroutine ompi_init(bogus) BIND(C, name="ompi_init_f")
176+
implicit none
177+
integer bogus
178+
end subroutine ompi_init
179+
end interface
180+
181+
integer bogus
182+
call ompi_init(bogus)
183+
end program
184+
])],
185+
186+
[],
187+
[xcode_happy=0])])
188+
AC_LANG_POP
189+
190+
# Exit the temp dir
191+
cd ..
192+
rm -rf $xcode_dir
193+
194+
# LIBS was set specifically for the artificial conditions of this
195+
# test, so reset it
196+
LIBS=$LIBS_save_xcode
197+
198+
AS_IF([test $xcode_happy -eq 1],
199+
[$2],
200+
[ # If we failed the test, reset LDFLAGS back to its
201+
# original value (if we passed the test, we'll leave
202+
# LDFLAGS modified with the new flags so that we use them
203+
# to build Open MPI).
204+
LDFLAGS=$LDFLAGS_xcode_save
205+
$3])
206+
207+
OPAL_VAR_SCOPE_POP
208+
])
209+
210+
#############################################################################
211+
53212
# General Fortran compiler setup
54213
AC_DEFUN([OMPI_SETUP_FC],[
55-
OPAL_VAR_SCOPE_PUSH([ompi_fc_happy LDFLAGS_save fc_version])
214+
OPAL_VAR_SCOPE_PUSH([ompi_fc_happy LDFLAGS_save fc_version OMPI_FORTRAN_WRAPPER_FLAGS])
56215

57216
# Force the intro banner to be displayed first
58217
AC_REQUIRE([_OMPI_SETUP_FC_BANNER])
@@ -226,23 +385,12 @@ I = 3]])],
226385
])
227386
])
228387

229-
# Per #1982, on OS X, we may need some esoteric linker flags in the
388+
# Per Trac #1982, on OS X, we may need some esoteric linker flags in the
230389
# Fortran wrapper compiler.
231390
AC_MSG_CHECKING([to see if mpifort compiler needs additional linker flags])
232391
case "$host" in
233392
*apple-darwin*)
234-
# Test whether -Wl,-commons,use_dylibs works; if it does, use it.
235-
LDFLAGS_save=$LDFLAGS
236-
LDFLAGS="$LDFLAGS -Wl,-commons,use_dylibs"
237-
AC_LANG_PUSH([Fortran])
238-
AC_LINK_IFELSE([AC_LANG_SOURCE([[program test
239-
integer :: i
240-
end program]])],
241-
[OMPI_FORTRAN_WRAPPER_FLAGS="-Wl,-commons,use_dylibs"
242-
OPAL_WRAPPER_FLAGS_ADD([FCFLAGS], [$OMPI_FORTRAN_WRAPPER_FLAGS])],
243-
[OMPI_FORTRAN_WRAPPER_FLAGS=none])
244-
AC_LANG_POP([Fortran])
245-
LDFLAGS=$LDFLAGS_save
393+
_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS
246394
AC_MSG_RESULT([$OMPI_FORTRAN_WRAPPER_FLAGS])
247395
;;
248396
*)

0 commit comments

Comments
 (0)