Mixed languages link error with meson build system (Fortran/C++) - c++

I am encountering issues when trying to compile fortran code using meson build system on an HPC cluster.
On the cluster, I am using Intel compiler suite. The meson compile command aborts at the linking step with:
ld: /usr/bin/../lib64/crt1.o: in function `_start':
(.text+0x20): undefined reference to `main'
ninja: build stopped: subcommand failed.
The interesting thing is that the link command issued by meson is something like this:
icpc -o main main.p/somefile.o ..., so it is using Intel's C++ compiler to link my fortran code. I tried to use the exact same command line, replacing icpc with ifort and adding -lstdc++. That actually worked.
So, I wonder, is there a way to force Meson to link my code with ifort, instead of icpc? Or, should I do something else?
I am afrad I cannot share the code at this moment. But, I'm open to showing bits and pieces of the meson.build file(s), if needed.
Details
The codebase consists of fortran source and a CMake C++ subproject; Essentially, the C++ subproject is a wrapper for OpenCV image plotting functions. This is why I needed to add -lstdc++ to my successful manual link command above.
Meson version: 0.55.3
Intel Fortran compiler: ifort (IFORT) 19.1.3.304 20200925
Intel C++ compiler: icpc (ICC) 19.1.3.304 20200925
The code is MPI parallelised.
The same code compiles well with GNU compilers v10 on a normal workstation.

Meson is not going to do any hand-holding when it comes to mixing languages. Here is what I found out works for Intel compilers:
fc=meson.get_compiler('fortran')
# cxx=meson.get_compiler('cpp')
...
if (fc.get_id() == 'intel')
#if (cxx.get_id() == 'intel')
...
add_global_link_arguments('-cxxlib',language : 'fortran')
add_global_link_arguments('-nofor_main', language : 'cpp')
endif
...
executable('myprog','myprog.f90', ..., link_language : 'fortran')
#executable('myprog','myprog.f90',...)

Related

(Clang Error) compilation error: ld: library not found for -lcrt0.o. Any ideas?

The full terminal output is as follows:
>g++ -std=c++98 -static mainP1.o -o mainP1
>
>ld: library not found for -lcrt0.o
>
>clang: error: linker command failed with exit code 1 (use -v to see invocation)
>
>make: *** [mainP1] Error 1
I'm on a 2020 MacBook Pro with an intel CPU using Visual Studio Code. When I write basic OOP programs in C++ it compiles fine without any clang errors. However, when working with big OOP programs with multiple classes inheriting from a base class I would get this error.
I tried searching online for solutions, but no solution or explanation was found. I double-checked my makefile to ensure I was not linking classes incorrectly.
I thought maybe I should just dual-boot with UBUNTU Linux to avoid this weird XCODE issue I was encountering with clang, but that was also a fruitless endeavor.
The problem was my compiler path in Visual Studio Code.
I changed it to clang++, and now all my code compiles and executes without any problems.
How I changed it:
CMD + SHIFT + P
Typed in: C/C++: Edit Configurations (UI)
Made sure that "Mac" was selected under configuration name.
Changed Compiler Path to: /usr/bin/clang++

How to use nvcc as compiler in ns3

I'm trying to use cuda in ns3, but when I tried to run CXX="nvcc" ./waf configure, it shows the following message on the screen:
Checking for 'g++' (C++ compiler) : not found
Checking for 'clang++' (C++ compiler) : not found
Checking for 'icpc' (C++ compiler) : not found
could not configure a C++ compiler!
(complete log in /home/kelu/workspace/ns-3.24/build/config.log)
I checked the config.log, it says the following:
Checking for 'g++' (C++ compiler)
find program='nvcc' paths=['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/local/cuda/bin'] var='CXX' -> ['nvcc']
from /home/kelu/workspace/ns-3.24: Could not determine the compiler type
not found
----------------------------------------
Checking for 'clang++' (C++ compiler)
find program='nvcc' paths=['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/local/cuda/bin'] var='CXX' -> ['nvcc']
from /home/kelu/workspace/ns-3.24: Not clang/clang++
not found
----------------------------------------
Checking for 'icpc' (C++ compiler)
find program='nvcc' paths=['/usr/local/sbin', '/usr/local/bin', '/usr/sbin', '/usr/bin', '/sbin', '/bin', '/usr/local/cuda/bin'] var='CXX' -> ['nvcc']
from /home/kelu/workspace/ns-3.24: Not icc/icpc
not found
from /home/kelu/workspace/ns-3.24: could not configure a C++ compiler!
nvcc is located in /usr/local/cuda/bin, which is in path. But it seems to me that the building script of ns3 does not resolve nvcc as a compiler.
Could anybody please tell me the right way to make nvcc the CXX compiler in ns3?
Thanks.
Your problem probably was that Waf actually checks the compiler's built-in #defines to check whether a compiler invoked as "gcc" actually is gcc or not. As a concrete example, it will error out if it detects that the compiler is Intel's icc (because it #defined __INTEL_COMPILER) but was invoked with a "gcc" command line!
The code that does the identification is at https://waf.io/apidocs/_modules/waflib/Tools/c_config.html#get_cc_version .
So, if you don't have a compiler which tries hard to look like one of the supported ones, looks like you are supposed to write your own Waf tool.
However, you can try to hack your way through. For example, let's say that your compiler is compatible enough with gcc but still it doesn't get past Waf's absurdly stringent test. A fix is to run "waf configure" using the real gcc, and then edit the file where Waf stores the detection results, so at the build step Waf will actually run your compiler instead of gcc. You can do this by editing build/c4che/_cache.py: change the CC definition to your compiler's full path.
I haven't found a way to use nvcc in ns-3, but I did find a work around for this problem. I'm happy to share my solution here to help others:
Make your cuda code a static library:
ar rcs libcudacode.a a.o b.o c.o (you need to make the *.o files first using g++, nvcc, or anything else you want)
put libcudacode.a in /your/lib/folder/ and put your cuda code in /your/src/folder
Add lib folder and src folder into waf:
CXXFLAGS_EXTRA="-I/your/src/folder -I/your/cuda/dir/include" LINKFLAGS_EXTRA="-L/your/lib/folder -L/your/cuda/dir/lib64 -lcudacode -lcudart" ./waf configure.
./waf
Your code should be compiled now. You can access any public functions in your cuda code by #including "corresponding_header.h"
A little bit explanation:
CXXFLAGS_EXTRA and LINKFLAGS_EXTRA add compilation flags in ns-3's compiling system. You need to add both your cuda code and NVidia's cuda library to use the functions.
If you used any other libraries, also put them in CXXFLAGS_EXTRA and LINKFLAGS_EXTRA
Check the cuda directory name in your system. It's probably not lib64 in your machine.

MacPorts clang not using its own headers

I'm trying to get emscripten to work on OS X 10.8, see this post for some related issues there. Apparently the clang++ version shipped with Xcode is too old, so I got a recent clang 3.7.0 using MacPorts. I even told CMake to use that compiler (passing -DCMAKE_CXX_COMPILER=clang++-mp-3.7 on the command line), but it still fails:
[ 33%] Building CXX object CMakeFiles/optimizer.dir/parser.cpp.o
/opt/local/bin/clang++-mp-3.7 -std=c++11 -fno-exceptions -fno-rtti -O3 -DNDEBUG
-o CMakeFiles/optimizer.dir/parser.cpp.o
-c …/emsdk/emscripten/master/tools/optimizer/parser.cpp
In file included from …/emsdk/emscripten/master/tools/optimizer/parser.cpp:2:
In file included from …/emsdk/emscripten/master/tools/optimizer/parser.h:12:
…/emsdk/emscripten/master/tools/optimizer/istring.h:3:10: fatal error:
'unordered_set' file not found
#include <unordered_set>
^
1 error generated.
I can reproduce that issue by launching the compiler from the command line. In parallel build mode, sometimes it's instead complaining about <cstdint> for optimizer.cpp instead. Both these headers exist in /opt/local/libexec/llvm-3.7/include/c++/v1/.
What's the canonical way to use the macports-installed version of clang++ including its headers? Do I have to use -I and work out the full path, or is there something shorter?
Can I safely do so without also switching the runtime library to the one shipped with MacPorts' clang? If not, can I somehow encode the full path of the runtime library into the created binary, either for that single library or using the -rpath argument to ld or some equivalent alternative?
Update: I get unresolved symbols when I try to link stuff after specifying the include directory manually, and I don't know how to solve that. The libcxx package from MacPorts is empty except for a readme file.
I've solved the original problem by adding CXXFLAGS=--stdlib=libc++ to the environment. Then even the system version of clang will do everything I need. That flag works magic for MacPorts' version of clang as well: specifying that I get a successful build, and I can even verify (using the -E compiler switch) that it's using the headers I mentioned before. I'm still not certain whether there is anything to ensure that the headers match the system's version of libc++, though.

Undefined reference to gfortran_runtime_error

I would like to run a model is written Fortran90 under Ubuntu 14.04. I use gfortran 95 compiler (gfortran 4:4.8.2-1ubuntu6). The required netCDF libraries (netCDF C and Fortran netCDF) are installed as suggested in: http://www.unidata.ucar.edu/software/netcdf/docs/. The netcdf is built as shared library so libnetcdf.so and libnetcff.so files there are in the library directory. The libgfortran3 4.8.2-19ubuntu1 is installed for GNU fortran application linked against the shared library.
The LDFLAGS is set in the compiler_options.inc file by the following way:
INCDF=-I$(NCPATH)/include
LNCDF=-L$(NCPATH)/lib -lnetcdff -lnetcdf
LDFLAGS=$(INCDF) $(LNCDF)
When I compile the model I get the following messages:
/home/Beata/kid_a_setup/src/test_cases_2d.f90:1446: undefined reference to `_gfortran_runtime_error_at
Could someone explain me what causes the error and how I can fix it?
undefined reference to _gfortran_runtime_error_at means that the libgfortran library has not been found.
Either your system is misconfigured (can you compile, link and run a "Hello, world" program using gfortran?), or you are using the gcc command for linking instead of gfortran for linking. gcc does not know about the libgfortran library, where _gfortran_runtime_error_at is defined.

Library not found for -lfl

I was using flex and bison to build a simple calculator project I cloned from Github.
But after I typed make in terminal, I got the following message:
gcc -o calc calc.tab.c lex.yy.c -lfl
calc.y:48:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
main() {
^~~~
1 warning generated.
ld: library not found for -lfl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [calc] Error 1
How could I resolve this problem?
let me guess, trying to use flex on OS/X?
Try -ll instead of -lfl
Using Flex on OS/X
So yea, the flex library name on OS/X is just arbitrarily different for some reason. OS/X is not exactly Linux, but it's pretty close. You have some options here.
You can just simply have a separate build system and source files for OS/X. Certainly Apple might like that with their pushing XCode, objective-C and not much interoperability.
You can build vs Linux and then engage with Mac Ports and Homebrew.
You can create your project using autotools. That's not an awesome link, learning this system is rough going, but it's a standard thing for Linux for sure. This will actually work, I find if you have the patience for it, OS/X is close enough that autotools based builds will work on it.
Lately, I've been turned on to Cocoapods, which I believe to be an attempt to join the open source community and XCode. It's kind of half 1 and 3 sorta with an emphasis on modularizing the external source and getting it compiled into a .app (via Xcode).
warning: type specifier missing, defaults to 'int'
mean that you should declare return type for main function. Place int in function difinition.
ld: library not found for -lfl
flag -l mean that compiller must use libfl.a to build programm. As #waTeim said above, for Mac OS you can use libl.a instead, but this lib can be not exist alse. There is another way is to place
%option noyywrap
at the top of flex *.l file. In this case you can compile without additional libs.