Nvc/nvc++/nvfortan try to link when they should not

Dear all,

the compiler binaries try to link when a -l flag is present, even in absence of an object file to link. The GCC compilers do not do this. This breaks ./configure scripts, e.g. when the mpicc compiler wrapper calls nv* with the mpi libraries:

$ mpicc -show
nvc -I<some includes> -L<some library locations> -lmpi

and as consequence:

$ mpicc --version
nvc 24.9-0 64-bit target on x86-64 Linux -tp skylake-avx512 
NVIDIA Compilers and Tools
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
/.../ld: /usr/lib64/crt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'

which will cause ./configure (of any package checking the compiler version) to fail.

After this motivation, a simple reproducer:

$ nvc --version -lm
nvc 24.9-0 64-bit target on x86-64 Linux -tp skylake-avx512 
NVIDIA Compilers and Tools
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
/.../ld: /usr/lib64/crt1.o: in function `_start':
(.text+0x1b): undefined reference to `main'

In comparison, gcc:

$ gcc --version -lm
gcc (GCC) 13.3.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This issue is present in 25.1, too:

nvc --version -lm

nvc 25.1-0 linuxarm64 target on aarch64 Linux -tp neoverse-v2 
NVIDIA Compilers and Tools
Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
/usr/bin/ld: /usr/lib64/crt1.o: in function `__wrap_main':
(.text+0x38): undefined reference to `main'

In 25.3:

 $ ./nvc --version -lm

nvc 25.3-0 linuxarm64 target on aarch64 Linux -tp cortex-a72 
NVIDIA Compilers and Tools
Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
/usr/bin/ld: cannot open output file a.out: Permission denied

If the behaviour could be harmonised to GCC, it would be highly appreciated.

As workaround, one could define a wrapper:

mpicc () {

        mpicc_exe=<your mpi location here>/bin/mpicc

        [[ --version =~ $@ && 1 -eq $# ]] && nvc --version && return 0

        $mpicc_exe $@
}

Thanks for reading my rant until this point!

Cheers, Peter

Hi Peter,

Thanks for reading my rant until this point!

No worries! We’d rather hear about these than you go away frustrated.

Now I’m not able to reproduce the issue with the MPI drivers, it seem to be ok for me (see below), but do see the issue with the NVHPC compiler drivers. I added an issue report, TPR #37255, and asked engineering to take a look on what can be done.

It doesn’t matter for the core issue, but when I tried using the OpenMPI4 and HPCX MPIs that we ship with the NVHPC SDK, I didn’t see the issue. I’m not sure what accounts for the difference in what you’re seeing.

% mpicc -show
nvc -I/proj/nv/Linux_aarch64/24.9/comm_libs/12.6/openmpi4/openmpi-4.1.5/include -L/proj/nv/Linux_aarch64/24.9/comm_libs/12.6/openmpi4/openmpi-4.1.5/lib -L/proj/nv/libraries/Linux_aarch64/24.9/openmpi4-12/262096-rel-2/comm_libs/12.4/openmpi4/openmpi-4.1.5/lib -Wl,-rpath,$ORIGIN:$ORIGIN/../../lib:$ORIGIN/../../../../../compilers/lib:$ORIGIN/../../../../../../compilers/lib -Wl,-rpath -Wl,/proj/nv/Linux_aarch64/24.9/comm_libs/12.6/openmpi4/openmpi-4.1.5/lib -Wl,-rpath -Wl,/proj/nv/libraries/Linux_aarch64/24.9/openmpi4-12/262096-rel-2/comm_libs/12.4/openmpi4/openmpi-4.1.5/lib -lmpi
% mpicc -V

nvc 24.9-0 linuxarm64 target on aarch64 Linux -tp grace
NVIDIA Compilers and Tools
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
%

-Mat

Hello Mat,

thanks for looking into this. The reason you don’t reproduce this is because you’re using OpenMPI. The opal_wrapper re-formats your request to a simple nvc --version.

If you have the time, please try with e.g. mpich’s mpiexec.

Otherwise, a simple

nvc --version -lm

vs. gcc’s

gcc --version -lm

will show the difference.

Cheers, Peter

Hello Mat,
did your developers get back to you on this?
Cheers, Peter

Hi Peter,

They’re resistant to changing the behavior. Basically to get to work the way you want, we’d need to follow what gcc does, which is to not compile/link and only print the version when the flag is enabled. However our “-V” flag also lets a user change the version so folks can easily switch between versions. Hence when an object or library is included on the command line, it continues with the link.

I tried to see if we could split the behavior between --version and -V, keeping -V as is and having --version match gcc, but the concern there is that the two flags are synonyms. As this is same behavior the compiler has had since it’s beginning days of PGI (long before NVIDIA bought us), changing this may cause other users problems as compilation would stop.

I can try again. Though see if it might be a way we can add a third option which stops after printing the version.

-Mat

-MAt

Hello Mat,

thanks for the follow up and your work-around hints. I wasn’t aware of the possibility to change the version on the fly with the -V flag.
Personally, I don’t have an issue with the developers standpoint. However, it might break a lot of other software’s ./configure steps, if these expect gcc-like behaviour (i.e. not linking when not given object files).

Cheers, Peter