astamm / nloptr

nloptr provides an R interface to NLopt, a free/open-source library for nonlinear optimization providing a common interface to a number of different optimization routines which can handle nonlinear constraints and lower and upper bounds for the controls.
https://astamm.github.io/nloptr/
Other
106 stars 34 forks source link

R installation error: cannot find libnlopt.so.0 #144

Closed giannilmbd closed 1 year ago

giannilmbd commented 1 year ago

Hi, Thanks for making this package available. I get this error when trying installing nloptr (both from CRAN and from your repository) `Error: package or namespace load failed for ‘nloptr’ in dyn.load(file, DLLpath = DLLpath, ...): unable to load shared object '/home/gianni/R/x86_64-redhat-linux-gnu-library/4.3/00LOCK-nloptr/00new/nloptr/libs/nloptr.so': libnlopt.so.0: cannot open shared object file: No such file or directory Error: loading failed Execution halted ERROR: loading failed

I've installed nlopt in various ways (and actually I've been using it extensively for some Fortran programs) I can see that libnlopt.so.0 exists `bash-5.1$ locate libnlopt.so

/usr/local/lib64/libnlopt.so

/usr/local/lib64/libnlopt.so.0

/usr/local/lib64/libnlopt.so.0.11.1 ` Yet R doesn't seem to be able to find it. Any suggestion? Thanks and best Gianni

eddelbuettel commented 1 year ago

Please download the source file ending in tar.gz, unpack it a local directory and run ./configure. Please report what it says. One possibilty is that while you may have the NLopt shared library, maybe pkg-config reports the wrong directory. You can ovveride this by locally editing src/Makevars to fit your system and then renaming/removing configure so that it does not get in the way and overwrites what you edited.

(Formatting in Markdown can help make your message more expressive. There are many tutorials but for starters try embedding you code quotes with three backticks in the respective lines above and below.)

giannilmbd commented 1 year ago

Thanks for the quick reaction. Sorry about the formatting. I trusted the built-in <> code bracketing... Will use Markdown. I realized that in my installation of Almalinux and R, most libraries (eg libnlopt.so.0) are installed in /usr/local/lib64, but R looks only in /usr/lib (though there must be a way to tell R to look in specific folders...).

I thus created a symbolic link into /usr/lib

sudo ln -s /usr/local/lib64/libnlopt.so.0 /usr/lib/.

Now nloptr installs successfully.

Thanks again for your help!

eddelbuettel commented 1 year ago

The symlink is wrong in the "bad idea in the medium to long run to mess with your system like that". Don't do that, if you can avoid it. If you have a moment of patience we should address this. It is "not R" that looks for nlopt, it is this package and I wrote this.

So as I asked you 12 minutes ago, can you please run ./configure and report what you get? You should remove the symlink you created to reproduce the prior setting.

(Ex-ante I think we rely on pkg-config. You may not have it. I cannot tell, but configure output might.)

giannilmbd commented 1 year ago

OK, I'll do it (I picked the shortcut 'cos I have a pile of s*** hanging on my head).

hecking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C++... yes
checking whether g++ -std=gnu++17 accepts -g... yes
checking for g++ -std=gnu++17 option to enable C++11 features... none needed
checking how to run the C++ preprocessor... g++ -std=gnu++17 -E
checking whether the compiler supports GNU C++... (cached) yes
checking whether g++ -std=gnu++17 accepts -g... (cached) yes
checking for g++ -std=gnu++17 option to enable C++11 features... (cached) none needed
checking for pkg-config... /usr/bin/pkg-config
checking if pkg-config knows NLopt... yes
checking for pkg-config checking NLopt version... >= 2.7.0
configure: creating ./config.status
config.status: creating src/Makevars
eddelbuettel commented 1 year ago

Thank you! That is the ideal case. pkg-config was found, it wrote src/Makevars for us. Can you add cat src/Makevars ?

The other possible gotcha is that the dynamic linker may or may not look in /usr/local/lib64. The check for that is ldconfig -p | grep libnlop where for me all is well:

$ ldconfig -p | grep nlopt
        libnlopt.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libnlopt.so.0
        libnlopt.so (libc6,x86-64) => /lib/x86_64-linux-gnu/libnlopt.so
$ 

ie I got nlopt from the distro reliably here.

giannilmbd commented 1 year ago

Will do tomorrow I‘m not at that machine now

On Mon, 25 Sep 2023 at 17:30, Dirk Eddelbuettel @.***> wrote:

Thank you! That is the ideal case. pkg-config was found, it wrote src/Makevars for us. Can you add cat src/Makevars ?

— Reply to this email directly, view it on GitHub https://github.com/astamm/nloptr/issues/144#issuecomment-1733958186, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHLXB3YDSJ2LQWNO53S6CB3X4GPQFANCNFSM6AAAAAA5GGEEYI . You are receiving this because you authored the thread.Message ID: @.***>

giannilmbd commented 1 year ago

Here it is

cat Makevars
CXX_STD = CXX11
PKG_CPPFLAGS = -I../inst/include 
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) -L/usr/local/lib -lnlopt

and

ldconfig -p | grep nlopt
    libnlopt.so.0 (libc6,x86-64) => /lib/libnlopt.so.0

Finally this might also be useful info

locate libnlopt.so
/usr/local/lib64/libnlopt.so
/usr/local/lib64/libnlopt.so.0
/usr/local/lib64/libnlopt.so.0.11.1
eddelbuettel commented 1 year ago

Yes so -L/usr/local/lib is wrong when the library is in fact in /lib -- your second block is somewhat in conflict with your third as /usr/local/lib64 is a different location. You may have an older system nlopt that shadows the newer one you want.

What does pkg-config --libs nlopt say?

eddelbuettel commented 1 year ago

Can you please edit the post at https://github.com/astamm/nloptr/issues/144#issuecomment-1735489680 ? When you do that in the web browser you have a preview feature that is helpful.

giannilmbd commented 1 year ago

Not so clear what is going on. I've made sure there is not libnlopt.so.0 in /usr/local/lib Then re-extracted the tar folder Ran the ./configure command getting

checking whether the C++ compiler works... yes

checking for C++ compiler default output file name... a.out

checking for suffix of executables...

checking whether we are cross compiling... no

checking for suffix of object files... o

checking whether the compiler supports GNU C++... yes

checking whether g++ -std=gnu++17 accepts -g... yes

checking for g++ -std=gnu++17 option to enable C++11 features... none needed

checking how to run the C++ preprocessor... g++ -std=gnu++17 -E

checking whether the compiler supports GNU C++... (cached) yes

checking whether g++ -std=gnu++17 accepts -g... (cached) yes

checking for g++ -std=gnu++17 option to enable C++11 features... (cached)
none needed

checking for pkg-config... /usr/bin/pkg-config

checking if pkg-config knows NLopt... yes

checking for pkg-config checking NLopt version... >= 2.7.0

configure: creating ./config.status

config.status: creating src/Makevars

Then

pkg-config --libs nlopt
-L/usr/local/lib -lnlopt

and

cat src/Makevars
CXX_STD = CXX11
PKG_CPPFLAGS = -I../inst/include 
PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) -L/usr/local/lib -lnlopt

To be sure I recompiled and installed nlopt from scratch. The only place where libnlopt.so.0 is located is \usr\local\lib64

Hence the reference to /usr/local/lib is quite surprising. Where is that information taken from?

eddelbuettel commented 1 year ago

Yes this is what you showed us before and per

checking for pkg-config... /usr/bin/pkg-config
checking if pkg-config knows NLopt... yes
checking for pkg-config checking NLopt version... >= 2.7.0

we are lead to believe we can use and trust pkg-config which then serves you a wrong location as per

$ pkg-config --libs nlopt
-L/usr/local/lib -lnlopt

which make it, I think, clear that this is a problem of us trusting (upstream) NLopt which appears to create a faulty nlopt.pc. For what it is worth, here is what I have in mine:

$ cat /usr/lib/x86_64-linux-gnu/pkgconfig/nlopt.pc
prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: NLopt
Description: nonlinear optimization libary
Version: 2.7.1
Libs: -L${libdir} -lnlopt
Libs.private: -lm
Cflags: -I${includedir}
$ 
giannilmbd commented 1 year ago

Sorry, not clear whether you are asking me some more information...

eddelbuettel commented 1 year ago

No I think we made it to the bottom of the investigation: your installation failed because a 'bad' file src/Makevars was written, and that was caused by 'bad' information supplied by pkg-config which in turn is likely from your local installation of NLopt. With that, I think our issue for nloptr ends here.

aadler commented 1 year ago

@astamm, I think we should close this per @eddelbuettel.

astamm commented 1 year ago

Thanks @eddelbuettel for getting to the bottom of this issue.