Opened 8 years ago

Closed 2 years ago

#37732 closed defect (fixed)

cmake-1.0: provide option to disable CMAKE_OSX_ARCHITECTURES

Reported by: mojca (Mojca Miklavec) Owned by: larryv (Lawrence Velázquez)
Priority: High Milestone:
Component: ports Version:
Keywords: Cc: tenomoto (Takeshi Enomoto), ryandesign (Ryan Schmidt), jmroot (Joshua Root), seanfarley (Sean Farley), cssdev, cooljeanius (Eric Gallager), jeremyhu (Jeremy Huddleston Sequoia), michaelld (Michael Dickens)
Port:

Description

gfortran-mp-4.X fails when the compiler flag -arch xxx is set. On the other hand g95 simply ignores the flag (it has no influence).

> gfortran-mp-4.5 -arch x86_64 a.f 
f951: error: unrecognized command line option "-arch"

This seems in contradiction to the information on http://www.microscopy.cen.dtu.dk/computing/fortran/index.html though which provides a counter example:

gfortran -arch x86_64 -arch i386 -arch ppc hello.f -o hello

so I'm still confused a bit.

It seems that one can use -m32 with both to get 32-bit i386 binaries, but I cannot try it out without recompiling gcc with +universal and I don't know yet how to make universal binaries with that approach.

If I try to use cmake Portgroup (but I didn't yet test without it), it automatically adds -arch x86_64 to FFLAGS and the compilation fails.

See also #37034 and #37688.

After writing the description I have also found this ticket #20361 and r54236 which made me believe that the wrong behaviour might have been fixed earlier and introduced again later (but I didn't try to understand the tcl code).

Attachments (1)

plplot.Portfile (12.6 KB) - added by mojca (Mojca Miklavec) 6 years ago.
plplot with CMake PortGroup

Download all attachments as: .zip

Change History (35)

comment:1 Changed 8 years ago by seanfarley (Sean Farley)

The page you linked to, ​http://www.microscopy.cen.dtu.dk/computing/fortran/index.html, actually points out that gfortran from the R project hosted at AT&T is the one that supports the -arch flag. All GNU gcc compilers do not support the -arch flag. Be careful with gfortran from R because it is based on gfortran-4.2 but that version of fortran is horribly riddled with bugs.

comment:2 Changed 8 years ago by ryandesign (Ryan Schmidt)

Resolution: invalid
Status: newclosed

Correct: none of the compilers in FSF GCC, including gfortran, support -arch flags; -arch flags are an Apple extension. If you would like FSF GCC to adopt this Apple extension you'll have to talk to the developers of FSF GCC about that.

The cmake 1.0 portgroup makes no mention of FFLAGS, or any other *FLAGS variables. MacPorts base should be smart enough to not add -arch flags if the compiler does not support it; we maintain a list in MacPorts base of which compilers do and do not support -arch flags. If this is not working correctly please provide a reproduction recipe.

comment:3 Changed 8 years ago by jmroot (Joshua Root)

  • You can't build universal binaries in a single command with -m32/-m64.
  • Sounds like your problem is either with cmake for passing -arch to compilers that don't support it, or possibly with the cmake portgroup if cmake isn't meant to be able to figure that stuff out on its own.

comment:4 in reply to:  3 Changed 8 years ago by seanfarley (Sean Farley)

Replying to jmr@…:

  • You can't build universal binaries in a single command with -m32/-m64.
  • Sounds like your problem is either with cmake for passing -arch to compilers that don't support it, or possibly with the cmake portgroup if cmake isn't meant to be able to figure that stuff out on its own.

I think it's the port group's fault (or rather, for not striping them out). As long as CMAKE_OSX_ARCHITECTURES, it "should just work".

comment:5 Changed 8 years ago by jmroot (Joshua Root)

Cc: sean@… added

I don't understand, should the portgroup be setting CMAKE_OSX_ARCHITECTURES for FSF compilers or not? Or do you mean it should be "stripping them out" of something else? As Ryan said, configure.fflags and friends don't contain -arch ever.

comment:6 Changed 8 years ago by jmroot (Joshua Root)

Cc: css@… added

comment:7 in reply to:  5 Changed 8 years ago by seanfarley (Sean Farley)

Replying to jmr@…:

I don't understand, should the portgroup be setting CMAKE_OSX_ARCHITECTURES for FSF compilers or not? Or do you mean it should be "stripping them out" of something else? As Ryan said, configure.fflags and friends don't contain -arch ever.

Ah, you're right, I remember now. This issue comes up for me when a port uses one of the FSF compilers *only for fortran*. When the configure.compiler is checked and, let's say, "clang" is returned, then all flags get the "-arch" switch which will then break any fortran compile.

comment:8 in reply to:  2 ; Changed 8 years ago by mojca (Mojca Miklavec)

Replying to ryandesign@…:

Correct: none of the compilers in FSF GCC, including gfortran, support -arch flags; -arch flags are an Apple extension. If you would like FSF GCC to adopt this Apple extension you'll have to talk to the developers of FSF GCC about that.

No, no. I'm not requesting from any compiler to support that flag.

The cmake 1.0 portgroup makes no mention of FFLAGS, or any other *FLAGS variables. MacPorts base should be smart enough to not add -arch flags if the compiler does not support it; we maintain a list in MacPorts base of which compilers do and do not support -arch flags.

I checked the cmake portgroup and it doesn't seem to have anything to do with FFLAGS either. So it must be MacPorts base.

If this is not working correctly please provide a reproduction recipe.

No, it's not working. I can provide two examples (for a minimal example I would need to create a hello world project). For the first one see browser:trunk/dports/science/plplot/Portfile@99965

# Adhoc fix
# cmake passes -arch to Fortran compiler
# g95 ignores -arch but gfortran fails with it
...
# Fortran notes:
# * In build/language_tests/Fortran, FC and LDFLAGS are used.
# * CMAKE_Fortran_COMPILER is used later in build.
# * To avoid -arch ${build_arch} to be passed configure.ld_archflags is unset.
...
variant gcc47 conflicts g95 gcc43 gcc44 gcc45 gcc46 universal description {Add support for fortran using gfortran-mp-4.7} {
    depends_lib-append      port:gcc47
    configure.fc            ${prefix}/bin/gfortran-mp-4.7
    configure.ld_archflags  ""
    configure.args-delete   -DENABLE_f77=OFF \
                            -DENABLE_f95=OFF
    configure.args-append   -DCMAKE_Fortran_COMPILER=\"${configure.fc}\" \
                            -DCMAKE_Fortran_FLAGS=\"${configure.fflags}\"
}
variant g95 conflicts gcc43 gcc44 gcc45 gcc46 gcc47 universal description {Add support for fortran using g95} {
    depends_lib-append      port:g95
    configure.fc            ${prefix}/bin/g95
    configure.ld_archflags  ""
    configure.args-delete   -DENABLE_f77=OFF \
                            -DENABLE_f95=OFF
    configure.args-append   -DCMAKE_Fortran_COMPILER=\"${configure.fc}\" \
                            -DCMAKE_OSX_DEPLOYMENT_TARGET=\"\" \
                            -DCMAKE_Fortran_FLAGS=\"${configure.fflags} -fno-second-underscore\"
}

For the second example see my CMake-based Root Portfile in #37688 and try it out with +gcc45 or one of those flags (but it might take a long time to compile it). It breaks with

Building Fortran object misc/minicern/CMakeFiles/minicern.dir/src/hbook.o
cd /Users/me/.macports/opt/local/var/macports/build/_Users_me_app_macports_science_root-devel/root-devel/work/build/misc/minicern && /opt/local/bin/gfortran-mp-4.5  -Dminicern_EXPORTS -m64 -std=legacy -O3 -arch x86_64 -fPIC -I/Users/me/.macports/opt/local/var/macports/build/_Users_me_app_macports_science_root-devel/root-devel/work/build/include -I/Users/me/.macports/opt/local/var/macports/build/_Users_me_app_macports_science_root-devel/root-devel/work/trunk/misc/minicern/inc    -c /Users/me/.macports/opt/local/var/macports/build/_Users_me_app_macports_science_root-devel/root-devel/work/trunk/misc/minicern/src/hbook.f -o CMakeFiles/minicern.dir/src/hbook.o
f951: error: unrecognized command line option "-arch"
make[2]: *** [misc/minicern/CMakeFiles/minicern.dir/src/hbook.o] Error 1
make[2]: Leaving directory `/Users/me/.macports/opt/local/var/macports/build/_Users_me_app_macports_science_root-devel/root-devel/work/build'
make[1]: *** [misc/minicern/CMakeFiles/minicern.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....

Replying to sean@…:

Ah, you're right, I remember now. This issue comes up for me when a port uses one of the FSF compilers *only for fortran*. When the configure.compiler is checked and, let's say, "clang" is returned, then all flags get the "-arch" switch which will then break any fortran compile.

I believe that's exactly what happens: the fortran compiler is set separately from the rest. I used clang/clang++ and only tried to set gfortran-mp-4.X. (Since there aren't that many ports using fortran, it's probably orders of magnitude less tested as all the C compilers. I didn't yet try to set the gcc compiler for C/C++ since the port author claims that it failed to work for him. A compilation takes about one hour, so I didn't try to force something that's know to fail until I get it working with clang.)

Last edited 8 years ago by ryandesign (Ryan Schmidt) (previous) (diff)

comment:9 in reply to:  8 Changed 8 years ago by jmroot (Joshua Root)

Replying to mojca@…:

I checked the cmake portgroup and it doesn't seem to have anything to do with FFLAGS either. So it must be MacPorts base.

Proof please. Show a build log where any of the fortran-related environment variables contain -arch.

comment:10 Changed 8 years ago by mojca (Mojca Miklavec)

I'm totally confused. I don't see the -arch x86_64 flag in FFLAGS or FCFLAGS indeed. And yet, when I compile the sources outside of MacPorts with the same compiler I end up with

Fortran_FLAGS =  -m64 -std=legacy -fPIC -I<some includes>

and inside MacPorts I end up with

Fortran_FLAGS =  -m64 -std=legacy -O3 -arch x86_64 -fPIC -I<some includes>

in build/misc/minicern/CMakeFiles/minicern.dir/flags.make for example.

However:

DEBUG: Environment: CPATH='/opt/local/include' CFLAGS='-pipe -O2 -arch x86_64' CPPFLAGS='-I/opt/local/include' CXXFLAGS='-pipe -O2 -arch x86_64' LIBRARY_PATH='/opt/local/lib' MACOSX_DEPLOYMENT_TARGET='10.7' CXX='/usr/bin/clang++' CC_PRINT_OPTIONS_FILE='/Users/mojca/.macports/opt/local/var/macports/build/_Users_mojca_app_macports_localports_science_root-devel/root-devel/work/.CC_PRINT_OPTIONS' F90FLAGS='-pipe -O2 -m64' LDFLAGS='-L/opt/local/lib -arch x86_64' FCFLAGS='-pipe -O2 -m64' OBJC='/usr/bin/clang' INSTALL='/usr/bin/install -c' FC='/opt/local/bin/gfortran-mp-4.5' OBJCFLAGS='-pipe -O2 -arch x86_64' FFLAGS='-pipe -O2 -m64' CC_PRINT_OPTIONS='YES' CC='/usr/bin/clang'

I'm using the same cmake and same compilers to compile both inside and outside of MacPorts. Any clues?

comment:11 Changed 8 years ago by jmroot (Joshua Root)

You should probably look for the answer to the question I asked about CMAKE_OSX_ARCHITECTURES earlier.

comment:12 in reply to:  11 Changed 8 years ago by mojca (Mojca Miklavec)

Replying to jmr@…:

You should probably look for the answer to the question I asked about CMAKE_OSX_ARCHITECTURES earlier.

Oh, I got it now. If I use

cmake -DCMAKE_OSX_ARCHITECTURES="x86_64" ...

then I get

Fortran_FLAGS =  -m64 -std=legacy -arch x86_64 -fPIC -I<...>

in misc/minicern/CMakeFiles/minicern.dir/flags.make indeed. So is that a bug in CMake passing the wrong flags to Fortran compiler then? On one hand it's true that it doesn't make sense to pass more than one architecture to C compiler if Fortran compiler is not able to create fat binaries. But on the other it doesn't make any sense at all if CMake passes -arch to Fortran.

comment:13 Changed 8 years ago by jmroot (Joshua Root)

So the portgroup probably needs an option to allow turning off use of CMAKE_OSX_ARCHITECTURES. Whether there's a bug in cmake is another question.

comment:14 Changed 8 years ago by mojca (Mojca Miklavec)

The CMake developers have confirmed the bug but aren't likely to act on it any time soon. CMake simply applies the flag to any given compiler on Mac OS X when CMAKE_OSX_ARCHITECTURES is present: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5876.

What do you think about changing the title of this ticket into something like "Provide a user-friendly option to avoid usage of CMAKE_OSX_ARCHITECTURES in the cmake portgroup" and reopening the ticket? (The option would probably have to be tightly coupled to disabling the universal builds.)

comment:15 in reply to:  14 Changed 8 years ago by seanfarley (Sean Farley)

Replying to mojca@…:

The CMake developers have confirmed the bug but aren't likely to act on it any time soon. CMake simply applies the flag to any given compiler on Mac OS X when CMAKE_OSX_ARCHITECTURES is present: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5876.

Son of a …

comment:16 Changed 8 years ago by jmroot (Joshua Root)

Component: baseports
Resolution: invalid
Status: closedreopened
Summary: fortran compilers don't accept -arch flagscmake portgroup needs an option to disable use of CMAKE_OSX_ARCHITECTURES

comment:17 Changed 8 years ago by cooljeanius (Eric Gallager)

Cc: egall@… added

Cc Me!

comment:18 Changed 7 years ago by mojca (Mojca Miklavec)

I submitted a bug report to CMake's bug tracker: http://www.cmake.org/Bug/view.php?id=14252. But it would still be great to be able to disable CMAKE_OSX_ARCHITECTURES as it might take time to fix CMake.

comment:19 Changed 7 years ago by mojca (Mojca Miklavec)

Cc: jeremyhu@… added
Priority: NormalHigh
Version: 2.1.2

I have changed the priority of this ticket to high.

It's increasingly annoying that no single port can now use both Fortran and the CMake PortGroup simultaneously (and it's probably a relatively simple patch to make). I would really like to switch to CMake for ROOT for example, but this is one of the major showstoppers for that.

Related tickets:

  • #37034 (plplot cannot use the PortGroup at all)
  • #37688#comment:41 (ROOT cannot compile an Fortran code at all unless the cmake PortGroup gets removed)
  • there are other ports like Geant4 suffering from this

Yes, it's a bug in CMake, but unless someone knows how to fix that bug, we need a workaround in MacPorts.

There is a related enhancement request for the PortGroup from me: #33259.

Last edited 7 years ago by mojca (Mojca Miklavec) (previous) (diff)

comment:20 Changed 7 years ago by mojca (Mojca Miklavec)

An interesting observation, GCC no longer complains:

> /opt/local/bin/gfortran-mp-4.7 hello.f -arch x86_64
> /opt/local/bin/gfortran-mp-4.5 hello.f -arch x86_64
f951: error: unrecognized command line option "-arch"

So this is no longer an issue with GCC 4.7 and 4.8 (I didn't test 4.6), even though it's still a nasty bug in CMake.

comment:21 Changed 7 years ago by jeremyhu (Jeremy Huddleston Sequoia)

gcc's support is very limited at best. It doesn't support multiple -arch flags (eg, not universal).

comment:22 Changed 6 years ago by michaelld (Michael Dickens)

Cc: michaelld@… added

Cc Me!

comment:23 in reply to:  14 ; Changed 6 years ago by RJVB (René Bertin)

Replying to mojca@…:

The CMake developers have confirmed the bug but aren't likely to act on it any time soon. CMake simply applies the flag to any given compiler on Mac OS X when CMAKE_OSX_ARCHITECTURES is present: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5876.

Is the location in the CMake source code (or the core .cmake files) where this happens identified? IIUC correcting the issue would require adding a list of compilers that don't understand the -arch flag, and take appropriate action for those?

Alternatively, how about replacing -arch i386 with -m32 and -arch x86_64 with -m64 for GCC compilers, on OS X versions where clang is the default (10.7 and higher)?

The original comment states

It seems that one can use -m32 with both to get 32-bit i386 binaries, but I cannot try it out without recompiling gcc with +universal and I don't know yet how to make universal binaries with that approach.

is that because of (runtime) libraries that must be present in 32bit version?

comment:24 in reply to:  23 Changed 6 years ago by mojca (Mojca Miklavec)

Replying to rjvbertin@…:

Replying to mojca@…:

The CMake developers have confirmed the bug but aren't likely to act on it any time soon. CMake simply applies the flag to any given compiler on Mac OS X when CMAKE_OSX_ARCHITECTURES is present: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/5876.

Is the location in the CMake source code (or the core .cmake files) where this happens identified?

Yes. See the bug report:

IIUC correcting the issue would require adding a list of compilers that don't understand the -arch flag, and take appropriate action for those?

Adding -arch flags to FFLAGS is problematic in 99% cases anyway. If they could be removed, that would solve almost all the problems out there.

Alternatively, how about replacing -arch i386 with -m32 and -arch x86_64 with -m64 for GCC compilers, on OS X versions where clang is the default (10.7 and higher)?

And breaking most of universal builds?

We just need to solve a problem for a very small number of ports that use a fortran compiler and cannot use the -arch flag. On the other hand it might be that this is no longer an issue with fortran compilers from the latest gcc versions. Maybe we should just test that and conclude that a fix is no longer needed.

The original comment states

It seems that one can use -m32 with both to get 32-bit i386 binaries, but I cannot try it out without recompiling gcc with +universal

is that because of (runtime) libraries that must be present in 32bit version?

I'm not sure if I understand the question, but it's also possible that I don't know the answer.

and I don't know yet how to make universal binaries with that approach.

Read as: one can get universal binaries with xFLAGS="-arch i386 -arch x86_64". Setting xFLAGS="-m32 -m64" probably doesn't give you universal binaries?

comment:25 Changed 6 years ago by larryv (Lawrence Velázquez)

Owner: changed from macports-tickets@… to larryv@…
Status: reopenednew
Summary: cmake portgroup needs an option to disable use of CMAKE_OSX_ARCHITECTUREScmake-1.0: provide option to disable CMAKE_OSX_ARCHITECTURES

comment:26 Changed 6 years ago by larryv (Lawrence Velázquez)

Mojca (or anyone), do you have a portfile handy that I can use as a test case? It’s fine if you don’t, I can come up with one easily enough.

comment:27 Changed 6 years ago by mojca (Mojca Miklavec)

I would guess that plplot +gcc44 should fail this way if you use the CMake PortGroup. (I didn't try right now.)

Changed 6 years ago by mojca (Mojca Miklavec)

Attachment: plplot.Portfile added

plplot with CMake PortGroup

comment:28 Changed 6 years ago by mojca (Mojca Miklavec)

Indeed. plplot +gcc44 fails with the attached Portfile. It seems that latest versions of gfortran happily ignore the -arch flag, so this no longer seems to be a pressing issue (but it was annoying enough that it was probably the main reason why plplot isn't using the cmake PortGroup yet). And it should be easy enough to fix.

+gcc47 works. (Maybe we should get back to #37034.)

I didn't test 4.5 and 4.6 to check since which version of GCC the flags are ignored (judging from my initial comments gcc 4.5 should probably fail as well). They certainly weren't ignored at the time when I opened the ticket.

comment:29 Changed 5 years ago by michaelld (Michael Dickens)

This issue is still relevant: while maybe gfortran tolerates the -arch flag, it seems like g++ and gcc from gcc5 still do not; haven't checked gcc6 yet.

For better or worse, this issue is at least partly an internal CMake issue: CMake assumes that the compiler can take the -arch flag, without even checking for it. There's even a comment in the code about how this variable should be used, but at least in my reading I don't see that the logic in the comment is carried out. I'll ping the CMake folks about this issue & see what they say.

comment:30 Changed 5 years ago by mojca (Mojca Miklavec)

comment:31 in reply to:  29 Changed 5 years ago by ryandesign (Ryan Schmidt)

Replying to michaelld@…:

This issue is still relevant: while maybe gfortran tolerates the -arch flag, it seems like g++ and gcc from gcc5 still do not; haven't checked gcc6 yet.

gcc and g++ support the -arch flag, from, I believe, version 4.7 onwards. (Works with 4.7.4 on my system.)

comment:32 Changed 5 years ago by jeremyhu (Jeremy Huddleston Sequoia)

Only single instance of it. They don't support building fat with multiple -arch arguments.

comment:33 Changed 5 years ago by mojca (Mojca Miklavec)

I'm still confused about the following claim then:

Macports' gcc5 fails due to the missing -arch switch.

from comment:5:ticket:51359. Even though I'm not sure if the reason for the problem was because of an attempt to build universally.

comment:34 Changed 2 years ago by mf2k (Frank Schima)

Resolution: fixed
Status: newclosed

This appears to be fixed in the cmake-1.1 portgroup.

Note: See TracTickets for help on using tickets.