Closed GoogleCodeExporter closed 9 years ago
The previous version (20111001) was actually the broken one (issue #127). I've
just tried moving all libopencv* files to /usr/local/lib/ and it works just
fine on my system. I have no idea why it does not work on your system at the
moment... Please keep my informed of more details when you have some.
BTW, java.library.path isn't what you are looking for:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6745024 (Be sure to put your
vote there if this is important to you.) What you are looking for depends on
the platform, well until this gets implemented in Java. Here are some things
that work:
- Under Linux, add the path to the LD_LIBRARY_PATH environment variable
- Under Mac OS X, add it to the DYLD_FALLBACK_LIBRARY_PATH environment variable
- Under Windows, add it path to the PATH environment variable
Voila, hope it helps, and let me know if you figure out why JavaCV doesn't look
into /usr/local/lib (You may have some old version of JavaCV lying in your
classpath somewhere.. ? Make sure `java -jar javacv.jar` displays the right
version.)
Original comment by samuel.a...@gmail.com
on 23 Jan 2012 at 10:03
I see now there's lit bit o gray area how java handles the non jni dependent
libraries, opencv in our case. Since its a must in my project to have
everything packed into a jar, I'm going to try your suggestion of setting the
env variable to point the location of the unpacked libraries, instead of
loading it myself. Will report back in case something goes wrong.
Original comment by frust...@gmail.com
on 24 Jan 2012 at 3:51
There's also the option of statically linking everything in the
libjni*/jni*.dll files, this way we don't need dependent libraries...
Another option consists of writing a special native library whose job is to set
the environment variables with setenv() (under Windows this does not work, we
need to call SetDllDirectory() instead)... I considered adding that to JavaCPP,
but bundling a native lib with JavaCPP dependent on native APIs /just/ for that
was kind of silly IMO, but if it's very important to you, it can be done.
If in the end you plan on making this application run via Web Start, I think
that comes with the required functionality built-in, but I have not
investigated that yet...
Original comment by samuel.a...@gmail.com
on 24 Jan 2012 at 6:17
You hit the point there. It makes more sense from the end user perspective to
have it statically linked, he doesn't bother a bit about opencv being used. It
makes more sense from the developers perspective to have it dynamically linked,
because it will save disk and system memory. Would be great to support both
cases.
Original comment by frust...@gmail.com
on 24 Jan 2012 at 10:30
It already does, just rebuild JavaCV using the static libs instead of the
dynamic ones... The paths to change for OpenCV are at the top of the
opencv_core.java file.
Original comment by samuel.a...@gmail.com
on 24 Jan 2012 at 10:33
I'll try that then makes even more sense for self contained projects, but
having a javacv statically linked package ready to be used would be a plus.
Original comment by frust...@gmail.com
on 24 Jan 2012 at 10:48
Well, let me know if you would like to contribute by providing those builds! :)
Oh BTW, it might be a good idea to execute the JavaCPP Builder with the "-d"
(as in "dump everything in that one file") option flag, which gets executed
from the build.xml file. Otherwise the opencv_core static code, among others,
is going to get copied across all other JNI modules for OpenCV...
Original comment by samuel.a...@gmail.com
on 24 Jan 2012 at 10:57
Oops, sorry, not the "-d" option, but the "-o" option as in "output everything
in that one file" ... "-d" is to set the output /directory/
Original comment by samuel.a...@gmail.com
on 24 Jan 2012 at 10:58
Issue 173 has been merged into this issue.
Original comment by samuel.a...@gmail.com
on 17 Mar 2012 at 6:51
Ok let's give this issue a better name...
Please let me know if anyone reading this wants to make a contribution! thank
you
Original comment by samuel.a...@gmail.com
on 17 Mar 2012 at 6:56
[deleted comment]
Samuel,
I've spent many hours trying to build this project, and all I want is a
relative path setting. In the list of paths to look for the library files,
could you simply add a relative path "lib\" type argument and build it? I'm
sure some besides me would find it beneficial for portability (Jenkins/Hudson
and such).
It's a massive headache for me, but a small tweak for you? I'll take the jars
directly from you would rather wait for a release.
-Benny
Original comment by benny....@gmail.com
on 19 Mar 2012 at 10:44
Benny, the easy way to do this is to set the environment variable required for
the underlying platform. (Refer to the comments above.) There is unfortunately
no easy way to do what you want otherwise... So, is setting an environment
variable acceptable for your application?
Original comment by samuel.a...@gmail.com
on 20 Mar 2012 at 10:14
Hi Samuel,
I tried to rebuild the javacv with a modified library path as you mentioned in
the previous comment.
What I have done is to change the path definition at the beginning of the
opencv_core.java:
public static final String genericLinkpath =
"/opt/local/lib/:/opt/local/lib64/:/usr/local/lib/:/usr/local/lib64/";
into something like:
public static final String genericLinkpath = "/usr/local/test/";
and compiled it to have opencv_core*.class
Then I used the javacpp builder to build the library file:
java -jar ../../javacpp.jar com/googlecode/javacv/cpp/opencv_core.*
The javacpp builder did find the opencv library files put under the
/usr/local/test/ and generated a library file: libjniopencv_core.dylib
However when I used the otool -L libjniopencv_core.dylib to check what is
linked with it. It gave me:
com/googlecode/javacv/cpp/macosx-x86_64/libjniopencv_core.dylib:
/Volumes/Old 320G/programming/javacv/build/classes/com/googlecode/javacv/cpp/macosx-x86_64/libjniopencv_core.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/local/lib/libopencv_core.2.3.1.dylib (compatibility version 2.3.0, current version 2.3.1)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
And with the final program, I still get the error:
java.lang.UnsatisfiedLinkError:
/private/var/folders/yv/n0r2_88d127__4plq2zg2y800000gn/T/libjniopencv_core713414
703132293992.dylib: Library not loaded:
/usr/local/lib/libopencv_core.2.3.1.dylib Referenced from:
/private/var/folders/yv/n0r2_88d127__4plq2zg2y800000gn/T/libjniopencv_core713414
703132293992.dylib Reason: image not found
Despite of the modification in the opencv_core.java, javacv always looked for
linked library at the (default?) path: /usr/local/lib/
I am wondering what should be done in order to get the library linked to a
given path (instead of /usr/local/lib/)
Thanks for your help,
Original comment by Qzts...@gmail.com
on 20 Mar 2012 at 10:18
Qztseng, this is perfectly normal given the current state of Java. Please read
the comments above.
Original comment by samuel.a...@gmail.com
on 21 Mar 2012 at 3:10
Hi Samuel,
I understand it could be circumvented by setting the DYLD_FALLBACK_LIBRARY_PATH
to my desired path (i.e. /usr/local/test/)
But what I don't understand here is why even after modifying the
"genericLinkpath" to my desired path (/usr/local/test/) in opencv_core.java,
recompile it and build with javacpp. The resulted libjnixxxxx.dylib file is
still linked to the /usr/local/lib/libopencv_core.2.3.1.dylib which apparently
appeared nowhere in the opencv_core.java code.
Maybe I missed something or didn't understand at all the above comments.....
Thanks for your reply,
Original comment by Qzts...@gmail.com
on 21 Mar 2012 at 8:48
Hum, according to what I can understand from
http://stackoverflow.com/questions/4513799/how-to-set-the-runtime-path-rpath-of-
an-executable-with-gcc-under-mac-osx
and other references it looks like your
/usr/local/test/libopencv_core.2.3.1.dylib wasn't linked with the
"-install_name @rpath/libopencv_core.2.3.1.dylib" or
whatever-it's-supposed-to-be option. You'll probably have to get this straight
first...?
Original comment by samuel.a...@gmail.com
on 21 Mar 2012 at 9:46
Hi Samuel,
It is indeed related to the install name as you mentioned. When the jni
libraries were generated, it is not linked to what was specified in the
genericLinkpath in the opencv_core.java, but linked to the install name of the
opencv native libraries. As a result, one has to change the install name of the
given opencv native libraries to the desired location so that when jni
libraries was called, it will search the right place(specified by the install
name).
By using the relative path "@loader_path", and some tweeks in your javacpp
code, the native libraries can also be put into a jar archive. So that the
whole javacv project could be put anywhere in the system without dealing with
the default library loading pathes.
I hope these information will be useful for someone else.
Best regards,
Original comment by Qzts...@gmail.com
on 3 Apr 2012 at 7:17
Qz,
I am extremely interested in this. As you can see from this thread, I have
spent much time just trying to build. I have given up for now, but I am
reinvigorated by your progress. I would like to know exactly how you did this.
Have you already accomplished this? Could you build a jar file for me with
relative paths (project portability)?
What OS did you build on?
So many questions, I would really really love to have a jar that I could put
into Eclipse projects (specifically Web Objects), which would allow for server
use without environment dependencies.
-Benny
Original comment by benny....@gmail.com
on 3 Apr 2012 at 7:25
Hi Benny,
I am working on Mac OSX.
What I have done is to change the install name of the opencv libraries by using
the install_name_tool into something like "@loader_path/the name of the
library.dylib" and put the library in com/googlecode/javacv/cpp/macosx-x86_64/
Run the javacpp builder to build the opencv_core but with the -cpp option so
that it will only generate the cpp file.
build the library with the command like:
g++ -I/system/headers "your/cpp/files/" -march=x86-64 -m64 -Wall -03 -fPIC
-dynamiclib -o "the destination folder for the jnixxxx.dylib"
-L/where/you/have/put/opencv/native/libraries/ -lopencv_core
you will see now the jni library is now linked with "@loader_path/xxxxx.dylib"
However, since java can't load library within jar archive, we need to extract
the native library into a temporary folder as Samuel already did in the
Loader.class by a little modification of Loader of javacpp. (see the attached
file).
Original comment by Qzts...@gmail.com
on 4 Apr 2012 at 11:11
Attachments:
@Qztseng, thanks for the feedback, but I am afraid your solution isn't
portable... Would you know by any chance a way to make this work well on Linux
and Windows too?
Original comment by samuel.a...@gmail.com
on 15 Apr 2012 at 3:00
Hi Samuel,
What do you mean not portable ?
I will try first to test on Linux probably.
Original comment by Qzts...@gmail.com
on 25 Apr 2012 at 8:09
Portable in this case means that it works on Linux and Windows too. If you find
a solution that works well on all platforms, I would be interested! We could
fix this "issue" with that.
Original comment by samuel.a...@gmail.com
on 26 Apr 2012 at 5:00
FYI, in the lastest release, I have made it easier to create one massive
statically linked native library by passing something like "-Xcompiler
-Wl,-static -o javacv" as command line options to JavaCPP, usually from inside
build.xml or pom.xml.
Also, if anyone wishes to contribute a build, please feel free to upload it
here! Thank you
And if you encounter any issues when trying to create such a static build,
please let us know
Original comment by samuel.a...@gmail.com
on 12 May 2012 at 10:55
@Samuel, Regarding to the portability issue. I tried with linux and found it is
even easier than mac. One just need to use something like "-rpath='$ORIGIN/"
during the javacpp building process. One can simply put the native library
along with the generated jni library together into the jar archive. With a
modified javacpp Loader, both the jni library and native library will be
extracted into system's temporary folder, and the jni library will search the
native library according to the path specified by the "rpath" option.
By the way, I tried to build the project with statically linked library by
passing the "-Wl,-static -o javacv". However I got error message:
>undefined symbols for architecture x86_64: "_main", referenced from:
> start in crt1.10.6.o
>ld: symbol(s) not found for architecture x86_64
>collect2: ld returned 1 exit status
While the dynamically linked jnilibrary build without error. Do you have any
idea ?
Original comment by Qzts...@gmail.com
on 12 May 2012 at 6:32
Attachments:
Looks like Mac OS X doesn't provide a simple method to link statically:
http://stackoverflow.com/questions/4576235/mixed-static-and-dynamic-link-on-mac-
os
These Apple guys sure know how to make things complicated for no good reason...
Interesting, I admit I hadn't thought of rpath on Linux supporting a relative
path! Thanks for letting me know
On Windows and Android, we can use System.load() to "preload" libraries, so we
don't need to do anything special for those.
So, if you could get this to work somehow on Mac OS X without having to create
a "lib" subdirectory or something depending on how the library was linked, it
would make for a nice enhancement to JavaCPP. Keep up updated on your progress,
thanks!
Original comment by samuel.a...@gmail.com
on 13 May 2012 at 10:40
@Samuel, the delicate part for a mac build is only at the linking step. The
original install name given to the native library will also be burned into the
jni library, no matter whether the "-install_name PATH" option is passed to the
g++ command.
As long as the install name of the native library is changed to a relative path
like "@loader_path" before running the g++ linking step, the relative searching
path will be burned into the jni library. During runtime, the jni library
extracted into the system temporary folder will then search for native
libraries according to the relative path (@loader_path) given by the install
name. By packaging the native libraries along with the jni libraries in the jar
archive, and with the modified Loader class which will also extract the native
library into the temporary folder, the project becomes completely portable
(User only need the jar file, without installing opencv library or putting the
library files in some specific system folder)
Original comment by Qzts...@gmail.com
on 13 May 2012 at 3:47
So, is it possible to have a single libjniopencv_core.dylib file, that will
look for a libopencv_core.2.4.0.dylib file, in the same directory, first, and
then if it does not find it there, have it look also inside /usr/local/lib and
/opt/local/lib and what not?
Original comment by samuel.a...@gmail.com
on 14 May 2012 at 2:48
Yes, the libjniopencv_core.dylib will first look for the libopencv_core.dylib
according to the path given by the install name defined by us as "@loader_path"
which will then be the same directory as libjniopencv_core.dylib. If it fails
to find it there, it will also look inside the system defined paths.
Original comment by Qzts...@gmail.com
on 14 May 2012 at 7:06
From what I understand, from e.g.
http://mikeash.com/pyblog/friday-qa-2009-11-06-linking-and-install-names.html
we just need to add "-Wl,-rpath,@loader_path/." as command line option to g++
when compiling libjni*dylib. Is this correct?
Then, if the user of JavaCV has compiled the libraries of OpenCV, etc. with
"-install_name @loader_path/.", or uses install_name_tool, and places them (or
Loader.load() places them) in the same directory as libjni*dylib, then Mac OS X
will load them properly...?
Original comment by samuel.a...@gmail.com
on 14 May 2012 at 8:00
Yes, exactly.
Moreover, what I have tried until now shows that the option
"-Wl,-rpath,@loader_path/" is even not necessary, since in the absence of
rpath, the libjni*.dylib will still look for the linked libopencv*.dylib
according to the install name.
Original comment by Qzts...@gmail.com
on 14 May 2012 at 11:07
Hum, no, it seems I got that wrong. Mac OS X does not actually provide anything
like -rpath on Linux. So, let me try this again.
If the libraries we depend on (e.g.: libopencv_core.2.4.dylib) have not been
linked with the right "-install_name", there is absolutely nothing else we can
do, but to call `install_name_tool`, is one way or another. Is this correct?
Original comment by samuel.a...@gmail.com
on 19 May 2012 at 11:50
In theory, the -rpath should be valid for mac os>=10.5. We can put several
searching paths including the one with relative path like @loader_path into the
rpath list. However, it seems to me that the install_name of the native library
should be imperatively set to our specific relative path during the linking
process.
In short, what I have tried (and it worked) was to change the install name of
the libopencv_core.dylib by the install_name_tool. Afterward, the linking of
the libjniopencv_core.dylib would pickup the correct install name given by us
for its dependency. The install name of the linked jni library somehow doesn't
matter.
You can have a look at the modified native library and the linked jni library
in the attached files.
Original comment by Qzts...@gmail.com
on 19 May 2012 at 1:06
Attachments:
I just used Macports to install opencv 2.4 [on Mac OSX 10.7.4] which installed
it in /opt/local/lib but when running a javacv example program I got the
following error.
Library not loaded: lib/libopencv_core.2.4.dylib
When I copied the all libopencv* files to /usr/local/lib/ [as suggested above]
it worked fine. But I look forward to a better fix. Thanks!
Original comment by ste...@StevenGlicker.com
on 19 May 2012 at 6:08
@Qztseng I updated the source repositories of JavaCPP and JavaCV and added
support for extracting and loading dependent libraries successfully on Linux,
Mac OS X, and Windows! Please test it out, thank you. And I get the gist w.r.t
to `install_name_tool`, but it's just such a PITA to fix all the libraries (no
thanks to you Apple), so if you could come up with a script to do it
automatically, I am sure others would appreciate, thanks!
@steven I'll be recompiling the next release with MacPorts, so all should be
fine then. You can't expect a version of JavaCV that was created before
MacPorts got updated to work.
Original comment by samuel.a...@gmail.com
on 20 May 2012 at 3:32
The new loader in javacpp can deal with the version number in the file
extension, but not with the /lib subfolder issue. It may sound absurd, but when
opencv was built, native libraries such as libopencv_imgproc were linked with
"@loader_path/lib/libopencv_core.xxx.dylib" (it is the built-in dependency not
the install name which we can't easily modify)
As a result, even with libopencv_imgproc.dylib successfully extracted into our
temporary path (which is also the @loader_path), when the
libjniopencv_imgproc.dylib try to load the libopencv_imgproc, it looked for its
dependency: @loader_path/lib/libopencv_core.xxx.dylib. Obviously, it is not
there but in: @loader_path/libopencv_core.xxx.dylib instead.
The easiest (but ugly, I have to admit...) solution comes to my mind was
therefore making a duplicate of libopencv_core in the /lib subfolder. (You can
have a look in the Loader.java I attached previously).
Original comment by Qzts...@gmail.com
on 20 May 2012 at 7:25
Right, but we can fix that with install_name_tool as well
Original comment by samuel.a...@gmail.com
on 21 May 2012 at 8:07
Yes, you are right. After fixing the install name manually, the javacpp loader
worked perfectly!
Original comment by yvon.gri...@gmail.com
on 22 May 2012 at 7:50
@Samuel, many thanks. I will watch for that Macports update.
Original comment by ste...@StevenGlicker.com
on 22 May 2012 at 8:09
Oook, the latest release of JavaCV supports the extraction of dependent native
libraries and it works as evidenced by this applet running on Linux, Mac OS X,
and Windows:
http://code.google.com/p/javacv/wiki/HowToMakeAnApplet
Thank you all for investigating this and helping me getting it working! Before
anyone asks, here is the command required to fix the OpenCV's dylibs under Mac
OS X:
BADPATH=/opt/local/lib # in the case of MacPorts, change as necessary
for f in libopencv*2.4.dylib; do install_name_tool $f -id @rpath/$f \
-add_rpath /opt/local/lib/ -add_rpath /usr/local/lib/ -add_rpath @loader_path/. \
-change $BADPATH/libopencv_core.2.4.dylib @rpath/libopencv_core.2.4.dylib \
-change $BADPATH/libopencv_calib3d.2.4.dylib @rpath/libopencv_calib3d.2.4.dylib \
-change $BADPATH/libopencv_features2d.2.4.dylib @rpath/libopencv_features2d.2.4.dylib \
-change $BADPATH/libopencv_flann.2.4.dylib @rpath/libopencv_flann.2.4.dylib \
-change $BADPATH/libopencv_gpu.2.4.dylib @rpath/libopencv_gpu.2.4.dylib \
-change $BADPATH/libopencv_highgui.2.4.dylib @rpath/libopencv_highgui.2.4.dylib \
-change $BADPATH/libopencv_imgproc.2.4.dylib @rpath/libopencv_imgproc.2.4.dylib \
-change $BADPATH/libopencv_legacy.2.4.dylib @rpath/libopencv_legacy.2.4.dylib \
-change $BADPATH/libopencv_ml.2.4.dylib @rpath/libopencv_ml.2.4.dylib \
-change $BADPATH/libopencv_nonfree.2.4.dylib @rpath/libopencv_nonfree.2.4.dylib \
-change $BADPATH/libopencv_objdetect.2.4.dylib @rpath/libopencv_objdetect.2.4.dylib \
-change $BADPATH/libopencv_photo.2.4.dylib @rpath/libopencv_photo.2.4.dylib \
-change $BADPATH/libopencv_video.2.4.dylib @rpath/libopencv_video.2.4.dylib; done
Original comment by samuel.a...@gmail.com
on 28 May 2012 at 2:16
As a relative newbie to all of this: I've tried installing per instruction and
I am getting the following error:
Exception in thread "Animation Thread" java.lang.UnsatisfiedLinkError:
/private/var/folders/nz/q355m9sx0dlcg9tvnpys7fx00000gq/T/libjniopencv_core598813
8778308280269.dylib: Library not loaded:
/opt/local/lib/libopencv_core.2.3.dylib Referenced from:
/private/var/folders/nz/q355m9sx0dlcg9tvnpys7fx00000gq/T/libjniopencv_core598813
8778308280269.dylib Reason: image not found
Original comment by GarethSi...@gmail.com
on 14 Oct 2012 at 7:15
Original issue reported on code.google.com by
frust...@gmail.com
on 21 Jan 2012 at 6:25