I received this error at bash interface while compiling my Fortran source code to read a netcdf file.
I used gfortran -o firstrd -I/use/local/include/ rdNetcdf.f90 -L/use/local/lib/ -libnetcdff.a but it returns
/use/bin/ld: cannot find -libnetcdff.a
I followed your previous recommend syntax on this issue before.
I saw libnetcdff.a in the directory /use/local/lib and not /use/lib directory.
nc-config is a tool that comes with the netcdf library that provides information on the library's configuration, including how to compile and link programs that use netcdf. nc-config --help describes the tool's usage. Its output includes the lines:
--fc Fortran compiler
--fflags flags needed to compile a Fortran program
--flibs libraries needed to link a Fortran program
In particular, run nc-config --fc --fflags --flibs on your system to find out how to compile and link Fortran programs that use netcdf.
Related
MPE is very useful for visualizing MPI programs, but it only provides compiler wrappers for C and Fortran: mpecc and mpef77, respectively. How can I use it if my MPI project is written in C++ and is normally compiled with mpic++, not mpicc (and so it can't be compiled with mpecc)?
How do I setup (1) the MPE library itself and (2) my C++ project?
The answer is actually quite simple, nonetheless I struggled with it for days.
Steps shown below works with MPICH 3.3.2 on Linux (Ubuntu 18) run with WSL2 - some adjustments may be necessary in different evnironments.
MPE library setup for c++
You setup the MPE library normally, the same way you would for a C project - the necessary steps are:
Download and extract the latest MPE archive (I've used MPE 2-1.4.9 from here)
Navigate to extracted directory:
cd mpe2-2.4.9b
Configure library's build process - in my case the following command worked:
./configure MPI_CC=mpicc MPI_F77=mpif77 prefix=$HOME/installs/mpe2 MPI_CFLAGS=-pthread MPI_FFLAGS=-pthread
Explanation:
MPE is written in C, so we use mpicc to compile it - we do not (yet) specify how to build our project, so we do not use mpic++. If we use mpic++ as MPI_CC, the MPE library won't compile.
specifying Fortran flags isn't strictly necessary, but this way we avoid unneccessary errors in compilation output
prefix (installation path) is an arbitrary path of your choice, just remember what you have inserted here as it will be necessary in further steps
I had to provide manual linkage of the pthread library - this may/may not be neccessary depending on your system
Compile the MPE library:
make
Install the compiled library:
make install
Using MPE in c++ project
Since we cannot use a predefined compiler wrapper mpecc to compile c++, we have to link the necessary libraries manually, as we would do with any other library.
Suppose we have a file main.cpp with following content:
#include <mpi.h>
#include <mpe.h>
/* other necessary includes */
int main(int argc, char** argv) {
MPI_Init(&argc, &argv);
MPE_Init_log();
/* some MPI and MPE stuff */
MPE_Finish_log("test");
MPI_Finalize();
}
The specific command which allows to build a c++ file with MPI and MPE calls is:
mpic++ main.cpp -o main -I/$HOME/installs/mpe2/include -L/$HOME/installs/mpe2/lib -lmpe -pthread
Explanation:
We use mpic++ to link the all MPI items automatically
$HOME/installs/mpe2 is an arbitrary installation path you've specified when configuring the MPE library
-I flag tells the compiler where to look for header files (the ones we #include)
-L flag tells the compiler where to find the compiled library items (implementation of functions defined in included header files)
-l flag tells compiler to actually link our executable with specific library (which can be found thanks to us specyfing search location with -L flag)
I had to link pthread manually for MPE to work, but that may depend on your system
If you use cmake for building your project, the following CMakeLists.txt should work:
cmake_minimum_required(VERSION 3.5) # not necessarily 3.5, it;s just my setup
project(mpi_test) # arbitrary project name
find_package(MPI REQUIRED)
set(CMAKE_CXX_COMPILER mpic++)
include_directories($ENV{HOME}/installs/mpe2/include) # again, it's the MPE installation path
link_directories($ENV{HOME}/installs/mpe2/lib) # again, it's the MPE installation path
add_executable(main_exp src/main_exp.cpp)
target_link_libraries(main_exp mpe pthread) # again, pthread may/may not be neccessary
Being a Javascript programmer, I'm really not quite familiar with the compiling process. My problem is locating source files during compilation with Emscripten. My "include"-commands refer to source code, such as "Core/main.h", which in turn refers to other source files in the same folder, yet using a similar address, (e.g. "Core/app.h")
How do I overcome these "File not found" errors? How do I indicate to the Emscripten compiler that it should look in the source folder? I've been reading the documentation, but what I'm finding discusses, I think, virtual file systems for use during run time, not included directories during compilation.
It's the one argument that is the same on virtually every C/C++ compiler: -I
emcc -Idir1 -Idir2 ... foo.c
Where the file is at dir1/Core/app.h.
I have 'correctly' installed gsl on mac 10.13.2.
In my c++ program, I am calling like usual, for example:
#include <gsl/gsl_math.h>
However while running the code, it can not find the gsl.
fatal error: 'gsl/gsl_math.h' file not found
I was wondering how to correctly link gsl PATH and libraries.
I have tried,
setting PATH and LD_LIBRARY_PATH in .bash_profile
setting PKG_CONFIG_PATH to .../Gsl2.3/lib/pkgconfig
$which gsl-config returns
/Users/gkdgoutam/Softwares/HEP_Softwares/Install/Gsl2.3/bin/gsl-config
$pkg-config --libs gsl returns
-L/Users/gkdgoutam/Softwares/HEP_Softwares/Install/Gsl2.3/lib -lgsl -lgslcblas -lm
The only solution I can find is to run everytime with gsl linked.
Like:
g++ $(gsl-config --cflags) mycode.cc $(gsl-config --libs) && ./a.out
But I was wondering if the GSL PATH can be set globally so that I can simply run
g++ mycode.cc && ./a.out
This is how c++ code is compiled and built:
COMPILATION
A compilation unit will take each cpp file and work its way through included headers to locate forward declaration of implementations of symbol signatures of used functionality in your code. In your case this involves gsl/gsl.h. If the file cannot be found in the search directories, which you can expand by specifying C_INCLUDE_PATH and or CPLUS_INCLUDE_PATH. If you omit #include <gsl/gsl_math.h>, your code will not compile as there are signatures, which cannot be found for GSL functions, which you use.
LINKING
Once you have compiled all cpp/cc files you need to link the binary, which can be executed. The linking process consists of a search through all symbols in your .o/.obj... files and a matching of the same to what it can find in your object files and the libraries, which you have specified using for example -lgsl. If all goes well, every lookup finds an according binary implementation for your machine's hardware model (i.e. 64bit/32bit ..., Arm, Intel, ... etc). If some are not found you will find linkage errors.
What you are asking is, is there a way that C++ does not work as above? No!
If you leave out #include <gsl/gsl.h> or if said file is not found in your search paths, compilation will not work or. If you omit -lgsl, linking will fail. If you find it annoying to write all the above stuff in the command line, write a Makefile to reduce the building process to ideally a simple command: make.
Don't forget, that if you are linking against the shared library version of GSL, you might need specifying LD_LIBARAY_PATH on Linux and DYLD_LIBRARY_PATH on Macs as well.
TLDR: you cannot ask a c++ compiler / linker to work differently as designed.
I am creating *.h5 files so I have been compiling with:
h5c++ -o output myFile.cpp
However, I added MPI to speed up the code in one of the sections. The same compilation gives me an undefined reference error.
undefined reference to `MPI_Init'
How do I compile the code so that I can use MPI as well as HDF5?
you can tell the HDF5 wrapper to use the MPI wrapper instead of your C++ compiler.
for example, if your MPI wrapper is mpiCC, you can simply
export HDF5_CXX=mpiCC
export HDF5_CLINKER=mpiCC
[this answer has been edited]
Both mpicc, as well as h5cc (and their C++ counterparts), are not compilers, but only wrappers, that only add some flags to the compiler call. These flags typically include linked libraries and include paths. You can actually inspect them!
$ mpicc --showme # OpenMPI
$ mpicc -show # MPICH
$ h5cc -show
So the answer to you question is: Make a compiler call with all flags from both wrappers.
However, typically you should just leave this to a build system like CMake, which will assemble all relevant compiler flags.
This problem is not specific to Fubi, but a general linker issue. These past few days (read as 5) have been full of linking errors, but I've managed to narrow it down to just a handful.
I'm trying to compile Fubi (Full Body Interaction framework) under the Linux environment. It has only been tested on Windows 7, and the web is lacking resources for compiling on a *nix platform.
Now, like I mentioned above, I had a plethora of linking problems that dealt mostly with incorrect g++ flags. Fubi requires OpenNI and NITE ( as well as OpenCV, if you want ) in order to provide it's basic functionality. I've been able to successfully compile both samples from the OpenNI and NITE frameworks.
As far as I understand, Fubi is a framework, thus I would need to compile a shared library and not a binary file.
When I try to compile it as a binary file using the following command
g++ *.cpp -lglut -lGL -lGLU -lOpenNI -lXnVNite_1_5_2 -I/usr/include/nite -I/usr/include/ni -I/usr/include/GL -I./GestureRecognizer/ -o FubiBin
and I get the output located here. (It's kind of long and I did not want to ruin the format)
If I instead compile into object files (-c flag), no errors appear and it builds the object files successfully. Note, I'm using the following command:
g++ -c *.cpp -lglut -lGL -lGLU -lOpenNI -lXnVNite_1_5_2 -I/usr/include/nite -I/usr/include/ni -I/usr/include/GL -I./GestureRecognizer/
I then am able to use the ar command to generate a statically linked library. No error [probably] occurs (this is only a guess on my end) because it has not run through the linker yet, so those errors won't appear.
Thanks for being patient and reading all of that. Finally, question time:
1) Is the first error regarding the undefined reference to main normal when trying to compile to a binary file? I searched all of the files within that folder and not a single main function exists.
2) The rest of the undefined reference errors complain that they cannot find the functions mentioned. All of these functions are located in .cpp and .h files in the subdirectory GestureRecognizer/ which is a subdirectory of the path I'm compiling in. So wouldn't the parameter -I./GestureRecognizer/ take care of this issue?
I want to be sure that when I do create the shared library that I won't have any linking issues during run-time. Would all of these errors disappear when trying to compile to a binary file if they were initially linked properly?
You are telling the compiler to create an executable in the first invocation and an executable needs a main() function, which it can't find. So no, the error is not normal. In order to create a shared library, use GCC's "-shared" option for that. Trying some test code here, on my system it also wants "-fPIC" when compiling, but that might differ. Best idea is to dissect the compiler and linker command lines of a few other libraries that build correctly on your system.
In order to add the missing symbols from the subdirs, you have to compile those, too: g++ *.cpp ./GestureRecognizer/*.cpp .... The "-I..." only tells the compiler where to search when it finds an #include .... I wouldn't be surprised if this wasn't even necessary, many projects use #include "GestureRecognizer/Foo.h" to achieve that directly.
BTW:
Consider activating warnings when running the compiler ("-W...").
You can split between compiling ("-c") and linking. In both cases, use "g++" though. This should decrease your turnaround time when testing different linker settings.