When trying to run Repast HPC executables I get the following error:
./main.exe: error while loading shared libraries: libboost_mpi-mt.so.1.61.0: cannot open shared object file: No such file or directory ./main.exe: error while loading shared libraries: libboost_mpi-mt.so.1.61.0: cannot open shared object
In the make file I define the link to boost in an env file with the below:
BOOST_INCLUDE= -I$(HOME)/sfw/Boost/Boost_1.61/include/
BOOST_LIB_DIR= -L$(HOME)/sfw/Boost/Boost_1.61/lib/
This is linked to a make file with the following make file
include ./env
.PHONY: clean
clean:
rm -f *.o
rm -f *.exe
.PHONY: compile
compile:
$(MPICXX) $(BOOST_INCLUDE) -c Main.cpp -o Main.o
$(MPICXX) $(BOOST_LIB_DIR) -o main.exe Main.o $(BOOST_LIBS)
.PHONY: all
all: clean compile
Boost in tsnow#DESKTOP-IF7CEHL:~/sfw/Boost/Boost_1.61/lib$ so it should link well across.
Any help appreciated, just trying to get a tutorial running.
We typically don't link repast to boost, but rather use rpath to let the model executable know where the boost and repast libraries are. For example in your Makefile:
REPAST_LIB_DIR = $(REPAST_HOME)/lib
BOOST_LIB_DIR = $(HOME)/theta/sfw/boost-1.66.0/lib
RPATHS += -Wl,-rpath -Wl,$(REPAST_LIB_DIR) -Wl,-rpath -Wl,$(BOOST_LIB_DIR)
and then add $(RPATHS) after the list of libraries during linking.
model : $(EXEC_OBJECTS)
$(CXXLD) -fopenmp -dynamic $^ $(LIBS) $(RPATHS) -o $(NAME)
Some of those args might not be appropriate for WSL, but hopefully the RPATHS part makes sense.
So, if after your include directive, you add
RPATHS=-Wl,-rpath -Wl,$(BOOST_LIB_DIR)
and update the second line of your compile target with
$(MPICXX) $(BOOST_LIB_DIR) -o main.exe Main.o $(BOOST_LIBS) $(RPATHS)
The location of your boost libs is compiled into main.exe, and it should find it.
The command:
export LD_LIBRARY_PATH=/home/tsnow/sfw/Boost/Boost_1.61/lib/
allowed boost to be found.
Related
I the GCC Wiki it is stated that support for auto-detection of dependencies has been available since version 4.6:
Support the generation of Makefile dependencies via the -M... flags of GCC; you may need to specify additionally the -cpp option. The dependencies take modules, Fortran's include, and CPP's #include into account. Note: Using -M for the module path is no longer supported, use -J instead.
In my program I have two Fortran files: module_1.f08 and main.f08, where main uses module_1. I am using the following command to try to auto-detect dependencies of main:
gfortran -cpp -M main.f08
If module_1 has been already compiled, the command above returns a list of dependencies as expected, though if module_1 has not been compiled yet, I get an error message instead saying that module_1.mod does not exist.
The way I'm seeing this is that every time a new module is added to the code, it has to be compiled separately before running make all (or we might run make all before using the module in any other file, then use the module and compile again) or else any dependency of it might be compiled before the module itself and a compilation error will be returned.
Another thing is that dependency files have to be created gradually and one-by-one as the project grows, and if .mod files and dependency files got deleted at some point (with a make clean command for example), there will be no way to generate dependency files all at once using the auto-detection feature.
Is there a way to get around these limitations? Is there a way for auto-detection to work even if .mod files do not exist yet?
To start with, you need to add snippets to your Makefile to actually use the dependency generation feature. Additionally, you can use the -MD option to generate dependency files automatically for each target, so you don't need a special target to regenerate your dependencies. For an example project like yours above with a main.f90 that uses a module defined in mod1.f90 a simple Makefile using dependencies could look like:
FC := gfortran
FFLAGS := -O2 -g
LIBS := # Needed libs like -lopenblas
SRCS := mod1.f90 main.f90
OBJS := ${SRCS:f90=o}
DEPS := ${OBJS:o=d}
myprog: $(OBJS)
$(FC) $(FFLAGS) -o $# $^ $(LIBS)
.PHONY: clean
clean:
-rm -f $(OBJS) *.mod
-include $(DEPS)
%.o: %.f90
$(FC) $(FFLAGS) -cpp -MD -c -o $# $<
When you run make you'll see that it generates files main.d and mod1.d containing the dependencies for the corresponding source file.
A (minor?) problem here is that your SRCS variable containing your list of source files must be listed in an order that allows the files to be compiled from left to right before you have any .d files. So the dependency stuff as it's done here doesn't help with ordering a build before the .d files have been generated. (Thus I'd recommend distributing the .d files as part of the source package.)
I'm having some trouble building shared libraries from Ada packages without using GPR's.
I have a package, Numerics, in files "numerics.ads" and "numerics.adb". They have no dependencies. There is a small build script which does:
gnatmake -Os numerics.ad[bs] -cargs -fPIC
gcc -shared numerics.o -o libnumerics.so -Wl,-soname,libnumerics.so
The .so and .ali files are installed at /usr/lib, and the .ads file is installed at /usr/include.
gnatls -v outputs the following relevant parts:
Source Search Path:
<Current_Directory>
/usr/include
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adainclude
Object Search Path:
<Current_Directory>
/usr/lib
/usr/lib/gcc/x86_64-unknown-linux-gnu/5.1.0/adalib
So GNAT should have no problem finding the files.
Then, trying to compile a package that depends on Numerics:
gnatmake -O2 mathematics.ad[bs] -cargs -fPIC
outputs:
gcc -c -fPIC mathematics.adb
gcc -c -I./ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error
This error has me thinking GNAT doesn't recognize the shared library, and is trying to rebuild Numerics.
I'd like to be building shared libraries, and only supply the spec for reference/documentation purposes.
edit:
So, it looks like gprbuild does two things I'm not doing. The first, is also passing -lnumerics to the compiler. The second, which shouldn't matter since libnumerics.so is in a standard directory anyways, is -L«ProjectDirectory». GPRbuild is obviously not doing desired behavior either, even though it's building the dependent project. It should be using the installed library /usr/lib/libnumerics.so, but instead is using «path»/Numerics/build/libnumerics.so. Furthermore, after building Numerics with GPRbuild, and then renaming the body to make it as if the body didn't exist (like with the installed files), when building Mathematics with GPRbuild, it complains about the exact same problem. It's as if the libraries aren't even shared, and GPRBuild is just making them look that way (except readelf reports the correct dependencies inside the libraries).
Adding -lnumerics to the build script accomplishes nothing; the build error is exactly the same. I'm completely lost at this point.
edit:
Following the link from Simon, the buildscript has changed to:
gnatmake -O2 mathematics.ad[bs] \
-aI/usr/include \
-aO/usr/lib \
-cargs -fPIC \
-largs -lnumerics
The error is essentially the same:
gcc -c -O2 -I/usr/include/ -fPIC mathematics.adb
gcc -c -I./ -O2 -I/usr/include/ -fPIC -I- /usr/include/numerics.ads
cannot generate code for file numerics.ads (package spec)
gnatmake: "/usr/include/numerics.ads" compilation error
I thought to check libnumerics.so is actually a correct shared library. ldd reports:
linux-vdso.so.1 (0x00007ffd944c1000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f50d3927000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f50d3ed4000)
So I'm thinking yes, the library is fine, and gnatmake still isn't recognizing it.
In general, you need to install the body of the packages as well (numerics.adb in your case). Also, I suspect you want to set the ALI files
(numerics.ali) as read-only, so that gnatmake does not try to recompile them.
I want to write and compile C++ code that requires the FLTK 1.3.2 GUI libraries.
I would like to use minGW with MSYS.
I have installed minGW and MSYS properly and have been able to build FLTK with ./configure
make. Everything worked up to this point.
Now I am testing the hello program, and can get the compiler to locate the header files, but it returns errors - which I believe are a result of the compiler not finding the location of the FLTK library. I have looked over the minGW site and it seems the difficulty of getting MSYS to direct the compiler to the correct location is not uncommon.
I have worked with C++ minGW for about a year but am completely new to MSYS.
Here is my command:
c++ Hello.cxx -Lc:/fltk-1.3.2/test -Ic:/fltk-1.3.2 -o Hello.exe
(I am not sure if my syntax is correct so any comments are appreciated)
Here is what I get from the compiler:
C:\Users\CROCKE~1\AppData\Local\Temp\ccbpaWGj.o:hello.cxx(.text+0x3c): undefined reference to 'Fl_Window::Fl_Window(int, int, char const*)'
... more similar comments...
collect2: ld returned exit status
It seems the compiler can't find the function definitions which I believe are in c:/fltk-1.3.2/test.
Again, I am a newbie so any help is greatly appreciated.
Thanks.
Your compile command is not good... You only inform LD where to search for additional libraries with the -L parameter, but you do not specify any library you actually want to use. For that you use -l flag.
So the command should be something like: g++ Hello.cxx -Lc:/fltk-1.3.2/test -Ic:/fltk-1.3.2 -o Hello.exe -llibfltk_images -llibfltk -llibwsock32 -llibgdi32 -llibuuid -llibole32
My recommendation - use the provided fltk-config script to obtain the flags.
Here is a MinGW makefile I "stole" from here: http://www.fltk.org/articles.php?L1286 .
# Makefile for building simple FLTK programs
# using MinGW on the windows platform.
# I recommend setting C:\MinGW\bin AND C:\MinGW\msys\1.0\bin
# in the environment %PATH% variable on the development machine.
MINGW=C:/MinGW
MSYS=${MINGW}/msys/1.0
FLTK_CONFIG=${MSYS}/local/bin/fltk-config
INCLUDE=-I${MSYS}/local/include
LIBS=-L${MSYS}/local/lib
CC=${MINGW}/bin/g++.exe
RM=${MSYS}/bin/rm
LS=${MSYS}/bin/ls
EXE=dynamic_buttons_scroll.exe
SRC=$(shell ${LS} *.cxx)
OBJS=$(SRC:.cxx=.o)
CFLAGS=${INCLUDE} `${FLTK_CONFIG} --cxxflags`
LINK=${LIBS} `${FLTK_CONFIG} --ldflags`
all:${OBJS}
${CC} ${OBJS} ${LINK} -o ${EXE}
%.o: %.cxx
${CC} ${INCLUDE} ${CFLAGS} -c $*.cxx -o $*.o
clean:
- ${RM} ${EXE}
- ${RM} ${OBJS}
tidy: all
- ${RM} ${OBJS}
rebuild: clean all
# Remember, all indentations must be tabs... not spaces.
I try to compile some C code for an embedded (custom) ARM-based Linux system. I set up an Ubuntu VM with a cross-compiler named arm-linux-gnueabi-gcc-4.4 because it looked like what I needed. Now when I compile my code with this gcc, it produces a binary like this:
$ file test1
test1: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.31,
BuildID[sha1]=0x51b8d560584735be87adbfb60008d33b11fe5f07, not stripped
When I try to run this binary on the embedded Linux, I get
$ ./test1
-sh: ./test1: not found
Permissions are sufficient. I can only imagine that something's wrong with the binary format, so I looked at some working binary as reference:
$ file referenceBinary
referenceBinary: ELF 32-bit LSB executable, ARM, version 1, dynamically linked
(uses shared libs), stripped
I see that there are some differences, but I do not have the knowledge to derive what exactly I need to fix and how I can fix that. Can someone explain which difference is critical?
Another thing I looked at are the dependencies:
$ ldd test1
libc.so.6 => not found (0x00000000)
/lib/ld-linux.so.3 => /lib/ld-linux.so.3 (0x00000000)
(Interestingly, this works on the target system although it cannot execute the binary.) The embedded system only has a libc.so.0 available. I guess I need to tell the compiler the libc version I want to link against, but as I understand it, gcc just links against the version it comes with, is this correct? What can I do about it?
Edit: Here's the Makefile I use:
CC=/usr/bin/arm-linux-gnueabi-gcc-4.4
STRIP=/usr/bin/arm-linux-gnueabi-strip
CFLAGS=-I/usr/arm-linux-gnueabi/include
LDFLAGS=-nostdlib
LDLIBS=../libc.so.0
SRCS=test1.c
OBJS=$(subst .c,.o,$(SRCS))
all: test1
test1: $(OBJS)
$(CC) $(LDFLAGS) -o main $(OBJS) $(LDLIBS)
$(STRIP) main
depend: .depend
.depend: $(SRCS)
rm -f ./.depend
$(CC) $(CFLAGS) -MM $^>>./.depend;
clean:
rm -f $(OBJS)
include .depend
What you should probably do is to install libc6 on the embedded system. Read this thread about a similar problem. The solution in post #5 was to install:
libc6_2.3.6.ds1-13etch9_arm.deb
linux-kernel-headers_2.6.18-7_arm.deb
libc6-dev_2.3.6.ds1-13etch9_arm.deb
Your other option is to get the libc from the embedded system onto your VM and then pass it to the gcc linker and use the -static option.
This solution was also mentioned in the above thread. Read more about static linking here.
Other things to try:
In this thread they suggest removing the -mabi=apcs-gnu flag from your makefile if you're using one.
This article suggests feedint gcc the -nostdlib flag if you're compiling from the command line.
Or you could switch to using the arm-none-eabi-gcc compiler. References on this can be found here and here.
I have built a shared library (i.e libabc.so) and an executable (i.e myapp) which uses my shared library. I have placed both the shared library and my executable in my filesystem but when I run my executable it gives me the following error
error while loading shared libraries: <target_lib_path>/<mylib>.so cannot open shared object file: No such file or directory.
Now my dev environment is I have a different target filesystem which is placed at ~/targetfs after building my shared library I am installing it in ~/targetfs/usr/local/abc/lib. During linking my application I give it
LDFLAGS += -L~/targetfs/usr/local/abc/lib
My application builds fine. But when I run my application in an environment where ~/targetfs is my filesystem, then my application complains
error while loading shared libraries:
/home/user/targetfs/usr/local/abc/lib/libabc.so: can not open shared object file. No such file or directory exist.
Now, of course the path my application is searching for the shared library that does not exist, but I want my application to be independent of this path, rather it should look for my shared library in /lib, /usr/lib, /usr/local/lib or LD_LIBRARY_PATH location.
How can I make my application to link libraries independent of its location?
Makefiles for my shared library & application is given below.
-------------- Shared library makefile. (Omitting un-necessary info)
CC = $(CROSS_COMPILE)gcc
CFLAGS = -Wall -shared -fpic
LDFLAGS = -Xlinker --gc-sections --allow-shlib-undefined
LIBRARY = libabc.so
OBJ_DIR = obj
SRC_DIR = src
CHK_DIR_EXISTS = test -d
MKDIR = mkdir -p
# Project Source Files
C_SOURCES += $(SRC_DIR)/abc.c
OBJECTS += $(OBJ_DIR)/abc.o
INCLUDES += -Iinc
$(LIBRARY): $(OBJECTS)
#echo ""
#echo "Linking..." $(LIBRARY)
#$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $(OBJ_DIR)/$(LIBRARY)
---------- Application Makefile (Omitting un-necessary info)
LDFLAGS += $(TARGETFS)/usr/local/abc/lib/libabc.so \
-lpthread -lrt
Any thoughts what's missing in my Makefiles.
You can ask the linker to put multiple search paths into the binary. You introduce those search paths with the -Wl,rpath=... option.
gcc -o abc abc.c
-L~/targetfs/usr/local/abc/lib
-labc
-Wl,-rpath=/usr/local/abc/lib
-Wl,-rpath=...
-Wl,-rpath=...