Patchwork [V10,4/7] libqblock build system

login
register
mail settings
Submitter Wayne Xia
Date Nov. 20, 2012, 9:46 a.m.
Message ID <1353404767-4495-5-git-send-email-xiawenc@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/200286/
State New
Headers show

Comments

Wayne Xia - Nov. 20, 2012, 9:46 a.m.
Libqblock was placed in new directory ./libqblock, libtool will build
dynamic library there, source files of block layer remains in ./block.
So block related source code will generate 3 sets of binary, first is old
ones used in qemu, second and third are non PIC and PIC ones in ./libqblock.
  GCC compiler flag visibility=hidden was used with special macro, to export
only symbols that was marked as PUBLIC.
  For testing, make check-libqblock will build binaries and execute it, make
clean or make check-clean will delete generated binaries.
  By default this library will be built and tested, out of tree building is
supported.

v10:
  Use $(SRC_PATH) in install rules.
  Call install libqblock from install target in root Makefile.
  Make libqblock and check-libqblock is conditional to a configure option and
libtool now, if libtool is not present it is forced to be disabled.
  removed unnest-vars in libqblock Makfile for that it was done in Makefile.objs.
  picked out only needed objects files for libqblock, added stub objects in
libqblock linking.
  use libtool to link check-libqblock.
  removed -fPIC cc flag replacement in tests/Makefile.
  removed seperate directory for libqblock test case.
  added target subdir-libqblock.
  added targets to .phony.
  generate files at root directory instead of ./libqblock.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 .gitignore                    |    2 +
 Makefile                      |   25 +++++++++++++-
 configure                     |   29 ++++++++++++++++
 libqblock/Makefile            |   74 +++++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock.c         |    6 +++
 libqblock/libqblock.h         |    1 +
 libqblock/libqblock.pc.in     |   13 +++++++
 tests/Makefile                |   31 ++++++++++++++++-
 tests/check-libqblock-qcow2.c |    6 +++
 9 files changed, 183 insertions(+), 4 deletions(-)
 create mode 100644 libqblock/Makefile
 create mode 100644 libqblock/libqblock-error.c
 create mode 100644 libqblock/libqblock-error.h
 create mode 100644 libqblock/libqblock-types.h
 create mode 100644 libqblock/libqblock.c
 create mode 100644 libqblock/libqblock.h
 create mode 100644 libqblock/libqblock.pc.in
 create mode 100644 tests/check-libqblock-qcow2.c
Paolo Bonzini - Nov. 20, 2012, 10:26 a.m.
Mostly looks good...

Il 20/11/2012 10:46, Wenchao Xia ha scritto:
> +libqblock="yes"

Please make the default the empty string, i.e. "build if and only if
libtool is present".

> 
> +##########################################
> +# libqblock probe
> +if test "$libqblock" != "no" ; then
> +# libqblock depends on libtool, default to yes if libtool exist
> +    if ! has $libtool; then
> +        echo
> +        echo "Warning: libqblock needs libtool"
> +        echo "Setting libqblock option to no."
> +        echo
> +        libqblock="no"
> +    fi
> +fi
>  #

Please fail here if libqblock=yes but libtool is not found.

> +#library objects
> +libqblock-obj-y= libqblock/libqblock.o libqblock/libqblock-error.o
> +extra-obj-y= main-loop.o qemu-timer.o qemu-tool.o iohandler.o \
> +             compatfd.o

Are all of these really necessary?  Instead of
main-loop/compatfd/iohandler, I think you can just add a new
libqblock/libqblock-aio.c file, and copy these definitions from main-loop.c:

QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
void qemu_aio_flush(void)
bool qemu_aio_wait(void)
void qemu_aio_set_fd_handler(int fd,
                            IOHandler *io_read,
                            IOHandler *io_write,
                            AioFlushHandler *io_flush,
                            void *opaque);
void qemu_aio_set_event_notifier(EventNotifier *notifier,
                                EventNotifierHandler *io_read,
                                AioFlushEventNotifierHandler *io_flush);

and also include part of qemu_init_main_loop in the creation of a new
QBlockContext (the first time it's called).  We can later map each
QBlockContext to a different AioContext.  Please document somewhere that
the library is not yet thread-safe.

> diff --git a/tests/Makefile b/tests/Makefile
> index ef6c9f2..997dbcc 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -84,6 +84,23 @@ check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)
>  qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a
>  $(check-qtest-y): $(qtest-obj-y)
>  
> +#libqblock build rules
> +check-libqblock-$(CONFIG_LIBQBLOCK) = tests/check-libqblock-qcow2$(EXESUF)
> +
> +$(check-libqblock-y): QEMU_INCLUDES += -I$(SRC_PATH)/tests -I$(SRC_PATH)/$(LIBQBLOCK_DIR)
> +LIBQBLOCK_TEST_DIR = tests/test_images
> +LIBQBLOCK_DIR = libqblock
> +LIBQBLOCK_SO = $(LIBQBLOCK_DIR)/.libs/libqblock.so
> +LIBQBLOCK_SO_LINK_FLAG = -Wl,-rpath,$(LIBQBLOCK_DIR)/.libs

These two should not be required.  Just link in libqblock/libqblock.la
and libtool will do all of its magic.

Paolo

> +
> +#use libtool to link check-libqblock, use LIBQBLOCK_SO_LINK_FLAG to add lib search diretory
> +LTLINK_CHECK_LIBQBLOCK = $(call quiet-command, $(LIBTOOL) --mode=link --quiet --tag=CC \
> +         $(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBQBLOCK_SO_LINK_FLAG) \
> +         -o $@ $(sort $(1)) $(LIBS), "lt LINK $(TARGET_DIR) $@")
> +
> +$(check-libqblock-y): %$(EXESUF): %.o
> +	$(call LTLINK_CHECK_LIBQBLOCK, $^ $(LIBQBLOCK_SO))
Wayne Xia - Nov. 21, 2012, 3:03 a.m.
于 2012-11-20 18:26, Paolo Bonzini 写道:
> Mostly looks good...
>
> Il 20/11/2012 10:46, Wenchao Xia ha scritto:
>> +libqblock="yes"
>
> Please make the default the empty string, i.e. "build if and only if
> libtool is present".
>
   Do you mean adding a probe section later that if libtool is present,
its default is "yes", else set it to "no"?


>>
>> +##########################################
>> +# libqblock probe
>> +if test "$libqblock" != "no" ; then
>> +# libqblock depends on libtool, default to yes if libtool exist
>> +    if ! has $libtool; then
>> +        echo
>> +        echo "Warning: libqblock needs libtool"
>> +        echo "Setting libqblock option to no."
>> +        echo
>> +        libqblock="no"
>> +    fi
>> +fi
>>   #
>
> Please fail here if libqblock=yes but libtool is not found.
>
   OK.

>> +#library objects
>> +libqblock-obj-y= libqblock/libqblock.o libqblock/libqblock-error.o
>> +extra-obj-y= main-loop.o qemu-timer.o qemu-tool.o iohandler.o \
>> +             compatfd.o
>
> Are all of these really necessary?  Instead of
> main-loop/compatfd/iohandler, I think you can just add a new
> libqblock/libqblock-aio.c file, and copy these definitions from main-loop.c:
>
   OK, good idea.

> QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
> void qemu_aio_flush(void)
> bool qemu_aio_wait(void)
> void qemu_aio_set_fd_handler(int fd,
>                              IOHandler *io_read,
>                              IOHandler *io_write,
>                              AioFlushHandler *io_flush,
>                              void *opaque);
> void qemu_aio_set_event_notifier(EventNotifier *notifier,
>                                  EventNotifierHandler *io_read,
>                                  AioFlushEventNotifierHandler *io_flush);
>
> and also include part of qemu_init_main_loop in the creation of a new
> QBlockContext (the first time it's called).  We can later map each
> QBlockContext to a different AioContext.  Please document somewhere that
> the library is not yet thread-safe.
>
   OK.

>> diff --git a/tests/Makefile b/tests/Makefile
>> index ef6c9f2..997dbcc 100644
>> --- a/tests/Makefile
>> +++ b/tests/Makefile
>> @@ -84,6 +84,23 @@ check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)
>>   qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a
>>   $(check-qtest-y): $(qtest-obj-y)
>>
>> +#libqblock build rules
>> +check-libqblock-$(CONFIG_LIBQBLOCK) = tests/check-libqblock-qcow2$(EXESUF)
>> +
>> +$(check-libqblock-y): QEMU_INCLUDES += -I$(SRC_PATH)/tests -I$(SRC_PATH)/$(LIBQBLOCK_DIR)
>> +LIBQBLOCK_TEST_DIR = tests/test_images
>> +LIBQBLOCK_DIR = libqblock
>> +LIBQBLOCK_SO = $(LIBQBLOCK_DIR)/.libs/libqblock.so
>> +LIBQBLOCK_SO_LINK_FLAG = -Wl,-rpath,$(LIBQBLOCK_DIR)/.libs
>
> These two should not be required.  Just link in libqblock/libqblock.la
> and libtool will do all of its magic.
>
   OK.

> Paolo
>
>> +
>> +#use libtool to link check-libqblock, use LIBQBLOCK_SO_LINK_FLAG to add lib search diretory
>> +LTLINK_CHECK_LIBQBLOCK = $(call quiet-command, $(LIBTOOL) --mode=link --quiet --tag=CC \
>> +         $(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBQBLOCK_SO_LINK_FLAG) \
>> +         -o $@ $(sort $(1)) $(LIBS), "lt LINK $(TARGET_DIR) $@")
>> +
>> +$(check-libqblock-y): %$(EXESUF): %.o
>> +	$(call LTLINK_CHECK_LIBQBLOCK, $^ $(LIBQBLOCK_SO))
>
>
Paolo Bonzini - Nov. 21, 2012, 7:56 a.m.
Il 21/11/2012 04:03, Wenchao Xia ha scritto:
>>
>>> +libqblock="yes"
>>
>> Please make the default the empty string, i.e. "build if and only if
>> libtool is present".
>>
>   Do you mean adding a probe section later that if libtool is present,
> its default is "yes", else set it to "no"?

Here, you just do libqblock="".

Then --enable-libqblock and --disable-libqblock set it to yes or no.

Then, if $libqblock = yes, and no libtool, fail.

If $libqblock is empty, and no libtool, set it to no.

If $libqblock is empty, and libtool is there, set it to yes.

Paolo
Wayne Xia - Nov. 22, 2012, 1:47 a.m.
于 2012-11-21 15:56, Paolo Bonzini 写道:
> Il 21/11/2012 04:03, Wenchao Xia ha scritto:
>>>
>>>> +libqblock="yes"
>>>
>>> Please make the default the empty string, i.e. "build if and only if
>>> libtool is present".
>>>
>>    Do you mean adding a probe section later that if libtool is present,
>> its default is "yes", else set it to "no"?
>
> Here, you just do libqblock="".
>
> Then --enable-libqblock and --disable-libqblock set it to yes or no.
>
> Then, if $libqblock = yes, and no libtool, fail.
>
> If $libqblock is empty, and no libtool, set it to no.
>
> If $libqblock is empty, and libtool is there, set it to yes.
>
> Paolo
>

   got it, will change it as comments.

Patch

diff --git a/.gitignore b/.gitignore
index bd6ba1c..77c1910 100644
--- a/.gitignore
+++ b/.gitignore
@@ -93,3 +93,5 @@  cscope.*
 tags
 TAGS
 *~
+tests/check-libqblock-qcow2
+tests/test_images
diff --git a/Makefile b/Makefile
index b04d862..dd01fe7 100644
--- a/Makefile
+++ b/Makefile
@@ -195,6 +195,27 @@  qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) libqemustub.a
 qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y) libqemustub.a
 qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y) libqemustub.a
 
+######################################################################
+# Support building shared library libqblock
+.PHONY: install-libqblock subdir-libqblock
+
+ifeq ($(CONFIG_LIBQBLOCK), y)
+subdir-libqblock: $(GENERATED_HEADERS) $(GENERATED_SOURCES)
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libqblock V="$(V)" TARGET_DIR="$*/" all,)
+
+install-libqblock: subdir-libqblock
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libqblock V="$(V)" TARGET_DIR="$*/" install-libqblock,)
+else
+LIBQBLOCK_WARN = "Libqblock was not enabled, skip. Make sure libtool was installed and libqblock was enabled."
+subdir-libqblock: $(GENERATED_HEADERS) $(GENERATED_SOURCES)
+	@echo $(LIBQBLOCK_WARN)
+
+install-libqblock:
+	@echo $(LIBQBLOCK_WARN)
+endif
+
+###########################################################################
+
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
 vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) libcacard/vscclient.o libqemustub.a
@@ -258,7 +279,7 @@  clean:
 	rm -rf qapi-generated
 	rm -rf qga/qapi-generated
 	$(MAKE) check-clean
-	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
+	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
         done
@@ -331,7 +352,7 @@  install-confdir:
 install-sysconfig: install-datadir install-confdir
 	$(INSTALL_DATA) $(SRC_PATH)/sysconfigs/target/target-x86_64.conf "$(DESTDIR)$(qemu_confdir)"
 
-install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig install-datadir
+install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig install-datadir $(if $(CONFIG_LIBQBLOCK),install-libqblock)
 	$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
 ifneq ($(TOOLS),)
 	$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
diff --git a/configure b/configure
index 801585c..b0cc044 100755
--- a/configure
+++ b/configure
@@ -223,6 +223,7 @@  libiscsi=""
 coroutine=""
 seccomp=""
 glusterfs=""
+libqblock="yes"
 
 # parse CC options first
 for opt do
@@ -871,6 +872,10 @@  for opt do
   ;;
   --enable-glusterfs) glusterfs="yes"
   ;;
+  --disable-libqblock) libqblock="no"
+  ;;
+  --enable-libqblock) libqblock="yes"
+  ;;
   *) echo "ERROR: unknown option $opt"; show_help="yes"
   ;;
   esac
@@ -1119,6 +1124,8 @@  echo "  --with-coroutine=BACKEND coroutine backend. Supported options:"
 echo "                           gthread, ucontext, sigaltstack, windows"
 echo "  --enable-glusterfs       enable GlusterFS backend"
 echo "  --disable-glusterfs      disable GlusterFS backend"
+echo "  --enable-libqblock       enable dynamic library libqblock"
+echo "  --disable-libqblock      disable dynamic library libqblock"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
@@ -2349,6 +2356,18 @@  EOF
   fi
 fi
 
+##########################################
+# libqblock probe
+if test "$libqblock" != "no" ; then
+# libqblock depends on libtool, default to yes if libtool exist
+    if ! has $libtool; then
+        echo
+        echo "Warning: libqblock needs libtool"
+        echo "Setting libqblock option to no."
+        echo
+        libqblock="no"
+    fi
+fi
 #
 # Check for xxxat() functions when we are building linux-user
 # emulator.  This is done because older glibc versions don't
@@ -3101,6 +3120,9 @@  if test "$want_tools" = "yes" ; then
   if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
     tools="qemu-nbd\$(EXESUF) $tools"
   fi
+  if test "$libqblock" = "yes" ; then
+  tools="subdir-libqblock $tools"
+  fi
 fi
 if test "$softmmu" = yes ; then
   if test "$virtfs" != no ; then
@@ -3235,6 +3257,7 @@  echo "build guest agent $guest_agent"
 echo "seccomp support   $seccomp"
 echo "coroutine backend $coroutine_backend"
 echo "GlusterFS support $glusterfs"
+echo "libqblock support $libqblock"
 
 if test "$sdl_too_old" = "yes"; then
 echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -3581,6 +3604,10 @@  if test "$glusterfs" = "yes" ; then
   echo "CONFIG_GLUSTERFS=y" >> $config_host_mak
 fi
 
+if test "$libqblock" = "yes" ; then
+  echo "CONFIG_LIBQBLOCK=y" >> $config_host_mak
+fi
+
 # USB host support
 case "$usb" in
 linux)
@@ -4166,12 +4193,14 @@  DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS qapi-generated"
 DIRS="$DIRS libcacard libcacard/libcacard libcacard/trace"
+DIRS="$DIRS libqblock"
 FILES="Makefile tests/Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 FILES="$FILES tests/tcg/lm32/Makefile libcacard/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES roms/seabios/Makefile roms/vgabios/Makefile"
+FILES="$FILES libqblock/Makefile"
 for bios_file in \
     $source_path/pc-bios/*.bin \
     $source_path/pc-bios/*.rom \
diff --git a/libqblock/Makefile b/libqblock/Makefile
new file mode 100644
index 0000000..256384a
--- /dev/null
+++ b/libqblock/Makefile
@@ -0,0 +1,74 @@ 
+###########################################################################
+# libqblock Makefile
+##########################################################################
+-include ../config-host.mak
+-include $(SRC_PATH)/rules.mak
+-include $(SRC_PATH)/Makefile.objs
+
+#############################################################################
+# Library settings
+#############################################################################
+# src files are in orignial path
+$(call set-vpath, $(SRC_PATH))
+# generated files are in ../
+$(call set-vpath, ../)
+
+#library objects
+libqblock-obj-y= libqblock/libqblock.o libqblock/libqblock-error.o
+extra-obj-y= main-loop.o qemu-timer.o qemu-tool.o iohandler.o \
+             compatfd.o
+
+#there are symbol conflict in stub-obj-y with iohandler.o, so set new version
+stub-obj-new-y= stubs/get-fd.o stubs/fdset-get-fd.o stubs/fdset-find-fd.o \
+             stubs/fdset-remove-fd.o stubs/fdset-add-fd.o
+
+
+QEMU_OBJS= $(libqblock-obj-y) $(block-obj-y) $(oslib-obj-y) $(stub-obj-new-y) \
+           $(extra-obj-y)
+QEMU_OBJS_LIB= $(patsubst %.o, %.lo, $(QEMU_OBJS))
+
+QEMU_CFLAGS+= -I$(SRC_PATH) -I$(SRC_PATH)/include -I../
+#adding magic macro define for symbol hiding and exposing
+QEMU_CFLAGS+= -fvisibility=hidden -D LIBQB_BUILD
+
+#dependency libraries
+LIBS+= -lz $(LIBS_TOOLS)
+
+#header files to be installed
+libqblock_includedir= $(includedir)/qblock
+libqblock_srcpath= $(SRC_PATH)/libqblock
+libqblock-pub-headers= $(libqblock_srcpath)/libqblock.h \
+                       $(libqblock_srcpath)/libqblock-types.h \
+                       $(libqblock_srcpath)/libqblock-error.h
+
+#################################################################
+# Runtime rules
+#################################################################
+.PHONY: clean all libqblock.la libqblock.pc install-libqblock
+
+clean:
+	rm -f *.lo *.o *.d *.la *.pc
+	rm -rf .libs block trace audio fsdev hw net qapi qga qom slirp ui libqblock stubs backends
+
+all: libqblock.la libqblock.pc
+# Dummy command so that make thinks it has done something
+	@true
+
+libqblock.la: $(QEMU_OBJS_LIB)
+	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(LIBS),"  lt LINK $@")
+
+libqblock.pc: $(libqblock_srcpath)/libqblock.pc.in
+	$(call quiet-command,sed -e 's|@LIBDIR@|$(libdir)|' \
+		-e 's|@INCLUDEDIR@|$(libqblock_includedir)|' \
+	    -e 's|@VERSION@|$(shell cat $(SRC_PATH)/VERSION)|' \
+		-e 's|@PREFIX@|$(prefix)|' \
+		< $(libqblock_srcpath)/libqblock.pc.in > libqblock.pc,\
+	"  GEN   $@")
+
+install-libqblock: libqblock.la libqblock.pc
+	$(INSTALL_DIR) "$(DESTDIR)$(libdir)"
+	$(INSTALL_DIR) "$(DESTDIR)$(libdir)/pkgconfig"
+	$(INSTALL_DIR) "$(DESTDIR)$(libqblock_includedir)"
+	$(LIBTOOL) --mode=install $(INSTALL_DATA) libqblock.la "$(DESTDIR)$(libdir)"
+	$(LIBTOOL) --mode=install $(INSTALL_DATA) libqblock.pc "$(DESTDIR)$(libdir)/pkgconfig"
+	$(LIBTOOL) --mode=install $(INSTALL_DATA) $(libqblock-pub-headers) "$(DESTDIR)$(libqblock_includedir)"
diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
new file mode 100644
index 0000000..e69de29
diff --git a/libqblock/libqblock-error.h b/libqblock/libqblock-error.h
new file mode 100644
index 0000000..e69de29
diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
new file mode 100644
index 0000000..e69de29
diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
new file mode 100644
index 0000000..4c18c41
--- /dev/null
+++ b/libqblock/libqblock.c
@@ -0,0 +1,6 @@ 
+#include "libqblock.h"
+
+int libqb_test(void)
+{
+    return 0;
+}
diff --git a/libqblock/libqblock.h b/libqblock/libqblock.h
new file mode 100644
index 0000000..b0f9daf
--- /dev/null
+++ b/libqblock/libqblock.h
@@ -0,0 +1 @@ 
+__attribute__((visibility("default"))) int libqb_test(void);
diff --git a/libqblock/libqblock.pc.in b/libqblock/libqblock.pc.in
new file mode 100644
index 0000000..d2a7d06
--- /dev/null
+++ b/libqblock/libqblock.pc.in
@@ -0,0 +1,13 @@ 
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: qblock
+Description: QEMU block layer library
+Version: @VERSION@
+
+Requires:  rt gthread-2.0 glib-2.0 z curl cap-ng uuid
+Libs: -L${libdir} -lqblock
+Libs.private:
+Cflags: -I${includedir}
diff --git a/tests/Makefile b/tests/Makefile
index ef6c9f2..997dbcc 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -84,6 +84,23 @@  check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)
 qtest-obj-y = tests/libqtest.o $(oslib-obj-y) libqemustub.a
 $(check-qtest-y): $(qtest-obj-y)
 
+#libqblock build rules
+check-libqblock-$(CONFIG_LIBQBLOCK) = tests/check-libqblock-qcow2$(EXESUF)
+
+$(check-libqblock-y): QEMU_INCLUDES += -I$(SRC_PATH)/tests -I$(SRC_PATH)/$(LIBQBLOCK_DIR)
+LIBQBLOCK_TEST_DIR = tests/test_images
+LIBQBLOCK_DIR = libqblock
+LIBQBLOCK_SO = $(LIBQBLOCK_DIR)/.libs/libqblock.so
+LIBQBLOCK_SO_LINK_FLAG = -Wl,-rpath,$(LIBQBLOCK_DIR)/.libs
+
+#use libtool to link check-libqblock, use LIBQBLOCK_SO_LINK_FLAG to add lib search diretory
+LTLINK_CHECK_LIBQBLOCK = $(call quiet-command, $(LIBTOOL) --mode=link --quiet --tag=CC \
+         $(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBQBLOCK_SO_LINK_FLAG) \
+         -o $@ $(sort $(1)) $(LIBS), "lt LINK $(TARGET_DIR) $@")
+
+$(check-libqblock-y): %$(EXESUF): %.o
+	$(call LTLINK_CHECK_LIBQBLOCK, $^ $(LIBQBLOCK_SO))
+
 .PHONY: check-help
 check-help:
 	@echo "Regression testing targets:"
@@ -94,6 +111,7 @@  check-help:
 	@echo " make check-unit           Run qobject tests"
 	@echo " make check-block          Run block tests"
 	@echo " make check-report.html    Generates an HTML test report"
+	@echo " make check-libqblock      Run libqblock tests"
 	@echo " make check-clean          Clean the tests"
 	@echo
 	@echo "Please note that HTML reports do not regenerate if the unit tests"
@@ -126,6 +144,12 @@  $(patsubst %, check-report-qtest-%.xml, $(QTEST_TARGETS)): check-report-qtest-%.
 check-report-unit.xml: $(check-unit-y)
 	$(call quiet-command,gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $^, "GTESTER $@")
 
+# gtester tests with libqblock
+
+.PHONY: $(patsubst %, check-%, $(check-libqblock-y))
+$(patsubst %, check-%, $(check-libqblock-y)): check-%: %
+	$(call quiet-command, LIBQBLOCK_TEST_DIR=$(LIBQBLOCK_TEST_DIR) gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER $*")
+
 # Reports and overall runs
 
 check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check-report-unit.xml
@@ -143,16 +167,19 @@  check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
 
 # Consolidated targets
 
-.PHONY: check-qtest check-unit check
+.PHONY: check-qtest check-unit check check-libqblock check-clean
 check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
 check-unit: $(patsubst %,check-%, $(check-unit-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
-check: check-unit check-qtest
+check-libqblock: $(patsubst %,check-%, $(check-libqblock-y))
+check: check-libqblock check-unit check-qtest
 
 check-clean:
 	$(MAKE) -C tests/tcg clean
 	rm -f $(check-unit-y)
 	rm -f $(check-qtest-i386-y) $(check-qtest-x86_64-y) $(check-qtest-sparc64-y) $(check-qtest-sparc-y)
 	rm -f tests/*.o
+	rm -f $(check-libqblock-y)
+	rm -rf $(LIBQBLOCK_TEST_DIR)
 
 -include $(wildcard tests/*.d)
diff --git a/tests/check-libqblock-qcow2.c b/tests/check-libqblock-qcow2.c
new file mode 100644
index 0000000..50a4df3
--- /dev/null
+++ b/tests/check-libqblock-qcow2.c
@@ -0,0 +1,6 @@ 
+#include "libqblock.h"
+int main(int argc, char **argv)
+{
+    libqb_test();
+    return 0;
+}