@@ -50,9 +50,163 @@ 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 shared
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 symbols. 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 common
80+ dnl 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+ AC_DEFUN([_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS],[
84+ OPAL_VAR_SCOPE_PUSH([xcode_flags])
85+
86+ # This variable is used by the invoking macro to display the
87+ # results via AC RESULT (just to keep the symmetry of
88+ # MSG_CHECKING / RESULT in the same upper-level macro).
89+ OMPI_FORTRAN_WRAPPER_FLAGS=
90+
91+ xcode_flags= " -Wl,-commons,use_dylibs"
92+ _OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND(
93+ [$xcode_flags ],
94+ [OMPI_FORTRAN_WRAPPER_FLAGS= $xcode_flags ], [])
95+ AS_IF([test -z " $OMPI_FORTRAN_WRAPPER_FLAGS " ],
96+ [xcode_flags= " -Wl,-commons,use_dylibs -Wl,-ld_classic"
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+ [OMPI_FORTRAN_WRAPPER_FLAGS= " none" ])
102+
103+ OPAL_VAR_SCOPE_POP
104+ ])
105+
106+ dnl Companion to _OMPI SETUP_FC_XCODE_COMMONS_LDFLAGS;
107+ dnl see that macro for an explanation of this macro.
108+ dnl
109+ dnl $1 : LDFLAGS to test
110+ dnl $2 : action to perform upon success
111+ dnl $3 : action to perform upon failure
112+ AC_DEFUN([_OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS_BACKEND],[
113+ OPAL_VAR_SCOPE_PUSH([xcode_happy xcode_dir LDFLAGS_save_xcode LIBS_save_xcode])
114+
115+ xcode_dir= conftest.$$
116+ rm -r f $xcode_dir
117+ mkdir -p $xcode_dir
118+ cd $xcode_dir
119+
120+ LIBS_save_xcode= $LIBS
121+ LDFLAGS_save_xcode= $LDFLAGS
122+ LDFLAGS= " $LDFLAGS -L. $1 "
123+
124+ # Note: we use COMPILE_IFELSE and LANG_SOURCE below, which assume
125+ # that confdefs.h exists. This is being invoked extremely early
126+ # in the configure sequence, so we haven't AC DEFINE'ed anything
127+ # yet, and therefore confdefs.h won't be automatically created
128+ # yet. So we'll make an empty confdefs.h to avoid some error
129+ # messages (it'll be removed with the whole tempdir, later).
130+ touch confdefs.h
131+
132+ # Step 1: make a C library with some public symbols
133+ xcode_happy= 0
134+ AC_LANG_PUSH([C])
135+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
136+ /* Must end the symbol in _ (remember: we are targeting the MacOS
137+ compilation environment, otherwise the Fortran linker will not find
138+ it, and will just create a new Fortran symbol for it * /
139+ int ompi_mpi_bottom_ = 42;
140+
141+ void ompi_init_f(int * bogus);
142+
143+ /* Empty / useless function that ensures that this compilation
144+ unit will not be optimized out * /
145+ void ompi_init_f(int * bogus)
146+ {
147+ /* Have a non-optimizable function body
148+ (but is otherwise worthless) * /
149+ * bogus = ompi_mpi_bottom_;
150+ }
151+ ]])],
152+ [ # If the above compiled successfully, Then use
153+ # conftest.OBJEXT to make the library. Note that
154+ # conftest.OBJEXT will automatically be deleted upon exit of
155+ # COMPILE_IFELSE.
156+ OPAL_LOG_COMMAND([$CC -d ynamiclib -Wl,-undefined -Wl,dynamic_lookup $LDFLAGS conftest.$OBJEXT -o libconftest.dylib],
157+ [xcode_happy= 1])])
158+ AC_LANG_POP
159+
160+ # Now compile and link a Fortran program against this shared
161+ # library
162+ AC_LANG_PUSH([Fortran])
163+ AS_IF([test $xcode_happy -eq 1],
164+ [LIBS= " $LIBS -lconftest"
165+ AC_LINK_IFELSE([AC_LANG_SOURCE([
166+ program test
167+ integer :: mpi_bottom
168+ common/ompi_mpi_bottom/mpi_bottom
169+
170+ interface
171+ subroutine ompi_init(bogus) BIND(C, name=" ompi_init_f" )
172+ implicit none
173+ integer bogus
174+ end subroutine ompi_init
175+ end interface
176+
177+ integer bogus
178+ call ompi_init(bogus)
179+ end program
180+ ])],
181+
182+ [],
183+ [xcode_happy= 0])])
184+ AC_LANG_POP
185+
186+ # Exit the temp dir
187+ cd ..
188+ rm -r f $xcode_dir
189+
190+ # LIBS was set specifically for the artificial conditions of this
191+ # test, so reset it
192+ LIBS= $LIBS_save_xcode
193+
194+ AS_IF([test $xcode_happy -eq 1],
195+ [$2 ],
196+ [ # If we failed the test, reset LDFLAGS (if we passed the
197+ # test, leave LDFLAGS modified with the new flags so that
198+ # we use them to build Open MPI).
199+ LDFLAGS= $LDFLAGS_xcode_save
200+ $3 ])
201+
202+ OPAL_VAR_SCOPE_POP
203+ ])
204+
205+ # ############################################################################
206+
53207# General Fortran compiler setup
54208AC_DEFUN([OMPI_SETUP_FC],[
55- OPAL_VAR_SCOPE_PUSH([ompi_fc_happy LDFLAGS_save fc_version])
209+ OPAL_VAR_SCOPE_PUSH([ompi_fc_happy LDFLAGS_save fc_version OMPI_FORTRAN_WRAPPER_FLAGS ])
56210
57211 # Force the intro banner to be displayed first
58212 AC_REQUIRE([_OMPI_SETUP_FC_BANNER])
@@ -226,23 +380,12 @@ I = 3]])],
226380 ])
227381 ])
228382
229- # Per #1982, on OS X, we may need some esoteric linker flags in the
383+ # Per Trac #1982, on OS X, we may need some esoteric linker flags in the
230384 # Fortran wrapper compiler.
231385 AC_MSG_CHECKING([to see if mpifort compiler needs additional linker flags])
232386 case " $host " in
233387 * 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
388+ _OMPI_SETUP_FC_XCODE_COMMONS_LDFLAGS
246389 AC_MSG_RESULT([$OMPI_FORTRAN_WRAPPER_FLAGS ])
247390 ;;
248391 * )
0 commit comments