Skip to content

Commit 59b9e78

Browse files
authored
Merge pull request #12663 from jsquyres/pr/v4.1.x/macos-fortran-ld-classic
v4.1.x: ompi_setup_fc.m4: use -Wl,-ld_classic if supported
2 parents 2f4ef91 + b15ff39 commit 59b9e78

File tree

1 file changed

+177
-14
lines changed

1 file changed

+177
-14
lines changed

config/ompi_setup_fc.m4

Lines changed: 177 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,183 @@ 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 Backstory
57+
dnl
58+
dnl The history is that for a long time (decades),
59+
dnl -Wl,-commons,use_dylibs worked by itself.
60+
dnl
61+
dnl XCode 15 introduced a a new linker (either "the new linker" or
62+
dnl "ld_prime", according to
63+
dnl https://developer.apple.com/forums/thread/715385). The new linker
64+
dnl originally did not support "-commons use_dylibs", but Apple recently
65+
dnl added support for that feature to the new linker in the XCode 16
66+
dnl beta. "-ld_classic" forces using the old linker (which doesn't support
67+
dnl some other features that customers might like, but Open MPI doesn't
68+
dnl use for its Fortran bindings, like mergable libraries).
69+
dnl
70+
dnl Sidenode: Open MPI needs this "-commons use_dylibs" functionality
71+
dnl because Fortran sentinel values (e.g., MPI_BOTTOM) are implemented
72+
dnl with Fortran common blocks.
73+
dnl
74+
dnl So there's three cases:
75+
dnl
76+
dnl 1. Customer's default linker is the classic linker, which always
77+
dnl supported "-commons use_dylibs".
78+
dnl 2. Customer's default linker is the new linker, but not new enough
79+
dnl to support "-commons use_dylibs", so we need to force using the old
80+
dnl linker via "-ld_classic".
81+
dnl 3. Customer's default linker is the new linker, new enough to support
82+
dnl "-commons use_dylibs", so we do not want to force using the old
83+
dnl linker.
84+
dnl
85+
dnl We have to use a slightly complex test code that will actually
86+
dnl fail if the version of Xcode being used requires "-ld_classic"
87+
dnl with "-commons,use_dylibs".
88+
dnl
89+
dnl 1. Build a shared library (with C source code) with a public
90+
dnl symbol that can be used as a Fortran common block symbol.
91+
dnl 2. Compile a Fortran program that calls a function in the shared
92+
dnl library, and link it against the shared library.
93+
dnl
94+
dnl Note: This is a linker test; we are checking to see if this all
95+
dnl compiles and links properly. The logic in the C / Fortran code
96+
dnl below specifically does not test for correctness because we do not
97+
dnl actually run the code.
98+
AC_DEFUN([_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS],[
99+
OPAL_VAR_SCOPE_PUSH([xcode_flags])
100+
101+
# This variable is used by the invoking macro to display the
102+
# results via AC RESULT (just to keep the symmetry of
103+
# MSG_CHECKING / RESULT in the same upper-level macro).
104+
OMPI_FORTRAN_WRAPPER_FLAGS=
105+
106+
xcode_flags="-Wl,-commons,use_dylibs"
107+
_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND(
108+
[$xcode_flags],
109+
[OMPI_FORTRAN_WRAPPER_FLAGS=$xcode_flags], [])
110+
AS_IF([test -z "$OMPI_FORTRAN_WRAPPER_FLAGS"],
111+
[xcode_flags="-Wl,-commons,use_dylibs -Wl,-ld_classic"
112+
_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND(
113+
[$xcode_flags],
114+
[OMPI_FORTRAN_WRAPPER_FLAGS=$xcode_flags], [])])
115+
AS_IF([test -z "$OMPI_FORTRAN_WRAPPER_FLAGS"],
116+
[OMPI_FORTRAN_WRAPPER_FLAGS="none"])
117+
118+
OPAL_VAR_SCOPE_POP
119+
])
120+
121+
dnl Companion to _OMPI SETUP_FC_XCODE_COMMONS_LDFLAGS;
122+
dnl see that macro for an explanation of this macro.
123+
dnl
124+
dnl $1: LDFLAGS to test
125+
dnl $2: action to perform upon success
126+
dnl $3: action to perform upon failure
127+
AC_DEFUN([_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND],[
128+
OPAL_VAR_SCOPE_PUSH([xcode_happy xcode_dir LDFLAGS_save_xcode LIBS_save_xcode])
129+
130+
xcode_dir=conftest.$$
131+
rm -rf $xcode_dir
132+
mkdir -p $xcode_dir
133+
cd $xcode_dir
134+
135+
LIBS_save_xcode=$LIBS
136+
LDFLAGS_save_xcode=$LDFLAGS
137+
LDFLAGS="$LDFLAGS -L. $1"
138+
139+
# Note: we use COMPILE_IFELSE and LANG_SOURCE below, which assume
140+
# that confdefs.h exists. This is being invoked extremely early
141+
# in the configure sequence, so we haven't AC DEFINE'ed anything
142+
# yet, and therefore confdefs.h won't be automatically created
143+
# yet. So we'll make an empty confdefs.h to avoid some error
144+
# messages (it'll be removed with the whole tempdir, later).
145+
touch confdefs.h
146+
147+
# Step 1: make a C library with some public symbols
148+
xcode_happy=0
149+
AC_LANG_PUSH([C])
150+
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
151+
/* Must end the symbol in _ (remember: we are specifically targeting
152+
the MacOS compilation environment, so it is ok to target a specific
153+
Fortran symbol convention), otherwise the Fortran linker will not
154+
find it, and will just create a new Fortran symbol for it */
155+
int ompi_mpi_bottom_ = 42;
156+
157+
void ompi_init_f(int *bogus);
158+
159+
/* Empty / useless function that still ensures that this compilation
160+
unit will not be optimized out */
161+
void ompi_init_f(int *bogus)
162+
{
163+
*bogus = ompi_mpi_bottom_;
164+
}
165+
]])],
166+
[ # If the above compiled successfully, Then use
167+
# conftest.OBJEXT to make the library. Note that
168+
# conftest.OBJEXT will automatically be deleted upon exit of
169+
# COMPILE_IFELSE.
170+
#
171+
# NOTE: this is pretty gross -- we're manually making a
172+
# shared library. But the libtool binary doesn't exist yet,
173+
# so this is the best that we can do.
174+
OPAL_LOG_COMMAND([$CC -dynamiclib -Wl,-undefined -Wl,dynamic_lookup $LDFLAGS conftest.$OBJEXT -o libconftest.dylib],
175+
[xcode_happy=1])])
176+
AC_LANG_POP
177+
178+
# Now compile and link a Fortran program against this shared
179+
# library.
180+
AC_LANG_PUSH([Fortran])
181+
AS_IF([test $xcode_happy -eq 1],
182+
[LIBS="$LIBS -lconftest"
183+
AC_LINK_IFELSE([AC_LANG_SOURCE([
184+
program test
185+
integer :: mpi_bottom
186+
common/ompi_mpi_bottom/mpi_bottom
187+
188+
interface
189+
subroutine ompi_init(bogus) BIND(C, name="ompi_init_f")
190+
implicit none
191+
integer bogus
192+
end subroutine ompi_init
193+
end interface
194+
195+
integer bogus
196+
call ompi_init(bogus)
197+
end program
198+
])],
199+
200+
[],
201+
[xcode_happy=0])])
202+
AC_LANG_POP
203+
204+
# Exit the temp dir
205+
cd ..
206+
rm -rf $xcode_dir
207+
208+
# LIBS was set specifically for the artificial conditions of this
209+
# test, so reset it
210+
LIBS=$LIBS_save_xcode
211+
212+
AS_IF([test $xcode_happy -eq 1],
213+
[ # Restore LDFLAFGS + the new flags (i.e., get rid of the
214+
# "-L." we added for this test)
215+
LDFLAGS="$LDFLAGS_xcode_save $1"
216+
$2],
217+
[ # If we failed the test, reset LDFLAGS back to its
218+
# original value.
219+
LDFLAGS=$LDFLAGS_xcode_save
220+
$3])
221+
222+
OPAL_VAR_SCOPE_POP
223+
])
224+
225+
#############################################################################
226+
53227
# General Fortran compiler setup
54228
AC_DEFUN([OMPI_SETUP_FC],[
55-
OPAL_VAR_SCOPE_PUSH([ompi_fc_happy LDFLAGS_save fc_version])
229+
OPAL_VAR_SCOPE_PUSH([ompi_fc_happy LDFLAGS_save fc_version OMPI_FORTRAN_WRAPPER_FLAGS])
56230

57231
# Force the intro banner to be displayed first
58232
AC_REQUIRE([_OMPI_SETUP_FC_BANNER])
@@ -226,23 +400,12 @@ I = 3]])],
226400
])
227401
])
228402

229-
# Per #1982, on OS X, we may need some esoteric linker flags in the
403+
# Per Trac #1982, on OS X, we may need some esoteric linker flags in the
230404
# Fortran wrapper compiler.
231405
AC_MSG_CHECKING([to see if mpifort compiler needs additional linker flags])
232406
case "$host" in
233407
*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
408+
_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS
246409
AC_MSG_RESULT([$OMPI_FORTRAN_WRAPPER_FLAGS])
247410
;;
248411
*)

0 commit comments

Comments
 (0)