diff mbox

driver test autotools issue

Message ID 20161025183909.GA51131@vm-arch-01.localdomain
State New
Headers show

Commit Message

Brian Brooks Oct. 25, 2016, 6:39 p.m. UTC
On 11/01 08:17:24, Christophe Milard wrote:
> On 31 October 2016 at 22:32, Brian Brooks <brian.brooks@linaro.org> wrote:

> > On 10/31 18:48:38, Christophe Milard wrote:

> >> Thanks for trying Brian.

> >>

> >> ...Tried this as well :-)...

> >>

> >>

> >> On 31 October 2016 at 18:03, Brian Brooks <brian.brooks@linaro.org> wrote:

> >> > On Fri, Oct 28, 2016 at 8:58 AM, Christophe Milard

> >> > <christophe.milard@linaro.org> wrote:

> >> >> Hi,

> >> >>

> >> >> The ODP driver development is does not progress due to an autotool

> >> >> problem to which I didn't find any nice solution:

> >> >>

> >> >> INTRODUCTION:

> >> >>

> >> >> ODP will be given the possibility to "include" user space NIC drivers.

> >> >> By "include", I mean either staticaly linked or dlopen()'d. I wish

> >> >> Both methods to be supported.

> >> >> The same driver should be loadable both ways (simply said for linux, a

> >> >> driverX.a and driverX.so should be built from driverX.c). Many drivers

> >> >> might be loaded at the same time (for different NICs).

> >> >>

> >> >> Because many drivers might be loaded at the same time, no

> >> >> 'known-symbol' can be exported by the driver to ODP to perform its

> >> >> initialisation: defining a driver_init() function in all drivers (that

> >> >> ODP could call) would result in double definition of driver_init() as

> >> >> soon as more than one driver is loaded.

> >> >> Defining a driverX_init() in each driver would require ODP to know the

> >> >> list of driver in advance, which is simply not acceptable.

> >> >>

> >> >> So the drivers should use a private "startup" function to perform

> >> >> their initialization. By this I mean a function that is put in the

> >> >> .init section or a function on which the __constructor__ gcc attribute

> >> >> has been applied, i.e. a function that gets called automatically at

> >> >> init time.

> >> >>

> >> >> ODP (the main lib) would then export an odp_driver_register() function

> >> >> which would be called by each registering driver from its startup

> >> >> function.

> >> >> Nothing special so far.

> >> >> just note that the driver is using an interface exported by ODP.

> >> >>

> >> >> The problem is to write autotools tests to test the driver. Each test

> >> >> should include a test main program linked to ODP, and test-driver,

> >> >> test_xxx_driver.la.

> >> >> The test should load the driver (or be staticaly linked to it before running).

> >> >> Being able to test both "loading" ways would be great, but at this

> >> >> stage, I would be very pleased to succeed with one way (static linking

> >> >> or "dlopen")...

> >> >> The driver should initialize as described above.

> >> >> These tests should be passing make check, distcheck, out of tree build...

> >> >> And should be OS independent (no hack to tune LD_LIBRARY_PATH which

> >> >> would assume linux)

> >> >>

> >> >>

> >> >> LINKING STATICALLY:

> >> >>

> >> >> Regarding statically linking, I reached a dead-end (I feel) as I could

> >> >> not affect the order in which the libs are passed to the linker by

> >> >> autotools. Autotools would pass  the test program and the ODP lib

> >> >> before the driver lib, hence assuming that the driver would define

> >> >> symbols used by {ODP+test}. But  we have the reverse situation, as we

> >> >> know. If the linker has options to handle this situation

> >> >> (--start-group, whole archive), it feels that autotools cannot handle

> >> >> them.

> >> >>

> >> >> You can refer to the following mail,

> >> >> http://lists.gnu.org/archive/html/automake/2016-10/msg00000.html

> >> >> which I sent on the automake mailing list. The mail includes another

> >> >> link that I suggest you should follow, if any of you would feel like

> >> >> investigating this track.

> >> >>

> >> >> My current branch if you wish something to play with:

> >> >> https://git.linaro.org/people/christophe.milard/odp.git/shortlog/refs/heads/drv_init_autohell_static_fail_v0.0

> >> >

> >> > Did you have a branch for static linking that also includes a test binary?

> >> > I can't see the link ordering issue desc above in

> >> > drv_init_autohell_static_fail_v0.0

> >> >

> >>

> >> I just pushed branch "drv_init_autohell_static_fail_v0.2". which is

> >> one of the tries I did on static.

> >> I am afraid this is really a dead end though.

> >> (I just pushed so you may have to wait a little before it shows up)

> >>

> >> Having said that, there was not as much objection about the "hack" to

> >> poke the .libs/xxx.so file into the Makefile.am and use rpath. I don't

> >> like it personally, but I cannot remain stuck forever either.

> >>

> >> I am about to send a patch with this hack. :-(

> >>

> >> >> DYNAMIC LINKING

> >> >>

> >> >> The other approach is to use dynamic linking: Not linking at program

> >> >> start, but really linking at run-time using dl_open(): This is really

> >> >> what is going to happen (application may ask to load specific

> >> >> drivers), so probably, it is not a too bad approach!

> >> >>

> >> >> But, it seems to be hard to get autotools to know what should be

> >> >> loaded (in a platform independent way)  and the path to it, as it

> >> >> varies for different cases (make check, distcheck, VPATH...): *.so

> >> >> files are naturally hidden by autotools (behind *.la), and autotools

> >> >> does not provide any nice way (I could find) to nicely refer to those

> >> >> .so files...

> >> >>

> >> >> BUT: autotools provides a lib called ltdl, whose aim is to enable

> >> >> autotools lib (.la) loading by applications, hence abstracting the

> >> >> real shared lib mechanism (.dll, .so...)! Sounded great...

> >> >>

> >> >> My understanding was that the -dlopen/preopen option of the LDADD

> >> >> suffix of autotools/libtool would be just made to do that: tracking

> >> >> where the lib(.la) goes, and setting the LD_LIBRARY_PATH for

> >> >> lt_dlopen() (called LTDL_LIBRARY_PATH) to whatever was needed to find

> >> >> the lib to be opened.

> >> >> see:

> >> >> https://www.gnu.org/software/libtool/manual/html_node/Libltdl-interface.html

> >> >>

> >> >> But I never succeeded passing  any options in the Makefile.am that

> >> >> seemed to have any impact on the search lib (.la) search path.

> >> >> Morerover I discovered that the ltdl lib (at least on my machine) did

> >> >> not seem to match the rest of the autotools as I had to redefine a

> >> >> symbol

> >> >> (lt__PROGRAM__LTX_preloaded_symbols vs

> >> >> lt_libltdl_LTX_preloaded_symbols). Strange. Not much on internet about

> >> >> that...

> >> >> All in All, I now understand that ltdl is *not* widely used. And I am

> >> >> now in doubt if this is the answer to our problem either...

> >> >>

> >> >> Looking at other projects, I could only find libcurl having the same

> >> >> problem and fixing it by poking the path the the .so file and setting

> >> >> the rpath.... the exact same thing I would really like not to do!

> >> >>

> >> >> My current try for dynamic with ltdl:

> >> >> https://git.linaro.org/people/christophe.milard/odp.git/shortlog/refs/heads/drv_init_autohell_dynamic_with_ltlib_v1

> >> >>

> >> >> More doc on modules and ltdt:

> >> >> https://autotools.io/libtool/plugins.html

> >> >>

> >> >> https://www.geekbooks.me/book/view/autotools has the autotools

> >> >> practitioner' guide on line. from page 189. Probably the best

> >> >> document...

> >> >>

> >> >>

> >> >> CONCLUSION:

> >> >>

> >> >> The only thing I got to work -I hope, not fully tested- is poking

> >> >> directely at the *.so file PATH in rpath:

> >> >> https://git.linaro.org/people/christophe.milard/odp.git/shortlog/refs/heads/drv_init_autohell_dynamic_so_only_v0

> >> >

> >> > Tried "-dlopen empty_driver.la" without success.

> >> > Eliminated libtestdrvinit.la and added drvinit.c to drvinit_main_SOURCES with

> >> > "-dlopen empty_driver.la" without success, but now there will be a nice libtool

> >> > error at build time.

> >> >

> >>

> >> ...Tried this as well :-)...

> >>

> >> > Tempted to just recreate this in a tiny sandbox just to see whether

> >> > it's possible.

> >> > If so, then it's just a matter of reverse engineering the advanced

> >> > Autotools usage

> >> > here, e.g. could Automake manual Section 8.3.3 be in effect somewhere due to

> >> > a deeply included include file?

> >> >

> >>

> >> I have put a lot of time trying many solution. wonder how much more we

> >> should put it this...

> >> Christophe.

> >

> > Replicated dlopen'ing a .so in an Autotools environment from scratch with

> > success. So, back to drv_init_autohell_dynamic_so_only_v0

> >

> > It works if libtestdrvinit.la is in lib_LTLIBRARIES instead of

> > noinst_LTLIBRARIES. Now, "-dlopen empty_driver.la" can be added to either

> > libtestdrvinit_la_LDFLAGS or drvinit_main_LDFLAGS.

> > Prefer libtestdrvinit_la_LDFLAGS since it actually has the code using the

> > .so name?

> 

> Not sure what you have succeeded with at his stage, but very interresting...

> 1) are you using lt_dlopen (the ltdl lib) or just dlopen?

> 2) Did you succeed without the rpath?

> 3) Did you have the ltdl symbol issue

> (lt__PROGRAM__LTX_preloaded_symbols vs

> lt_libltdl_LTX_preloaded_symbols)?

> My goal was to have a fully OS independant Makefile.am, i.e. with no

> rpath (because the use of rpath implies a risk of picking the wrong

> file) and without any *.so filename (because this filename is *.os

> dependant). Have any branch I can look at?


Working on ability to push to git.linaro.org/people/brian.brooks/

Here is the patch to drv_init_autohell_dynamic_so_only_v0:



> Christophe

> 

> > The .so will be picked up from .libs.. something to do with LT_OBJDIR and

> > have a feeling m4/libtool.m4 should not be in the repo but instead installed

> > via "autoreconf --install" ./bootstrap.sh phase.

> > No idea why this doesn't work if the lib is noinst_LTLIBRARIES.

> >

> > These changes to configure.ac might also be necessary:

> >

> > +LT_PREREQ([2.2.6])

> >  LT_INIT([dlopen])

> > -AC_SUBST([LIBTOOL_DEPS])

> > -AM_PROG_LIBTOOL

> > -AC_SUBST([LIBTOOL_DEPS])

> >

> >> >> This last approach is the worse, I think. But the only which possibly

> >> >> work. Should we really go this way???

> >> >>

> >> >> I am lacking ideas at this point. But if we want driver test as part

> >> >> of make check, we have to progress or take a decision.

> >> >>

> >> >> Regards,

> >> >>

> >> >> Christophe.
diff mbox

Patch

diff --git a/test/common_plat/validation/drv/drvinit/Makefile.am b/test/common_plat/validation/drv/drvinit/Makefile.am
index c2a3a09..e9ab0db 100644
--- a/test/common_plat/validation/drv/drvinit/Makefile.am
+++ b/test/common_plat/validation/drv/drvinit/Makefile.am
@@ -3,11 +3,14 @@  include $(top_srcdir)/platform/@with_platform@/Makefile.inc
 
 ABS_TEST_BUILDDIR = $(abs_top_builddir)/test/common_plat/validation/drv/drvinit
 
-noinst_LTLIBRARIES = libtestdrvinit.la
+lib_LTLIBRARIES =
+
+lib_LTLIBRARIES += libtestdrvinit.la
 libtestdrvinit_la_SOURCES = drvinit.c
+libtestdrvinit_la_LDFLAGS = -dlopen empty_driver.la
 
 #the minimalist driver:
-lib_LTLIBRARIES = empty_driver.la
+lib_LTLIBRARIES += empty_driver.la
 empty_driver_la_SOURCES = empty_driver.c
 empty_driver_la_LDFLAGS = $(AM_LDFLAGS) -module -shared -export-dynamic \
 			  -avoid-version
@@ -18,7 +21,4 @@  test_PROGRAMS = drvinit_main$(EXEEXT)
 drvinit_main_SOURCES = drvinit_main.c
 drvinit_main_LDADD = libtestdrvinit.la $(LIBCUNIT_COMMON) $(LIBODP)
 
-drvinit_main_LDFLAGS = $(AM_LDFLAGS) \
-		     -rpath $(ABS_TEST_BUILDDIR)/.libs
-
 EXTRA_DIST = drvinit.h