vvp: build and install libvvp as a versioned shared library

Uses the package version for the SONAME and full library version.

For linking, a pkg-config file is generated, and when building on
Windows, an import library is created that can be used with both
GCC and MSVC compilers.

On non-Windows platforms, all object files are compiled with -fPIC
to ensure compatibility with shared libraries.

On Windows use 'lib' prefix for library name with MinGW compiler
only. Other compiler like MSVC normally are not using any library
prefix.

The shared library is assumed to be ABI-stable within the same
major version, so the SONAME reflects only the major version
number.
This commit is contained in:
Ralf Habacker 2026-04-28 21:56:47 +02:00
parent 4f33082d09
commit 8182194d5d
3 changed files with 129 additions and 11 deletions

View File

@ -15,6 +15,16 @@ AC_SUBST([VERSION], ["VER_MAJOR.VER_MINOR (VER_EXTRA)"])
# used in res.rc
AC_SUBST([PRODUCTVERSION], ["VER_MAJOR,VER_MINOR,0,0"])
# setup libvvp soversion, which depends on abi not package version
AC_SUBST([LIBVVP_SOVERSION], [1])
# setup libvvp version
AC_SUBST([LIBVVP_VERSION], [VER_MAJOR.VER_MINOR])
# setup libvvp soversion, which depends on abi not package version
AC_SUBST([LIBVVP_SOVERSION], [1])
# setup libvvp version
AC_SUBST([LIBVVP_VERSION], [VER_MAJOR.VER_MINOR])
AC_CONFIG_SRCDIR([netlist.h])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_HEADERS([_pli_types.h])
@ -203,7 +213,14 @@ AC_FUNC_FSEEKO
# Build VVP as a library and stub
AC_ARG_ENABLE([libvvp],
[AS_HELP_STRING([--enable-libvvp], [build VVP as a shared library])],
[AC_SUBST(LIBVVP, yes)],[])
[enable_libvvp=yes],
[enable_libvvp=no])
AC_SUBST([LIBVVP], [$enable_libvvp])
AS_IF([test "x$enable_libvvp" = "xyes"],
[AC_MSG_NOTICE([Building with libvvp support enabled])],
[AC_MSG_NOTICE([Building with libvvp support disabled])])
AC_ARG_ENABLE([libveriuser],
[AS_HELP_STRING([--enable-libveriuser], [include support for PLI 1 (deprecated)])],
@ -429,6 +446,7 @@ AC_CONFIG_FILES([
vhdlpp/Makefile
vpi/Makefile
vvp/Makefile
vvp/libvvp.pc
vvp/vvp.man
])
AC_OUTPUT

View File

@ -23,6 +23,7 @@ prefix = @prefix@
exec_prefix = @exec_prefix@
srcdir = @srcdir@
datarootdir = @datarootdir@
abs_builddir = @abs_builddir@
VPATH = $(srcdir)
@ -33,6 +34,7 @@ mandir = @mandir@
# It is a little different from the generic includedir.
includedir = @includedir@/iverilog$(suffix)
pdfdir = @docdir@
pkgconfigdir = $(libdir)/pkgconfig
# For a cross compile these defines will need to be set accordingly.
HOSTCC = @CC@
@ -63,12 +65,79 @@ CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
LDFLAGS = @rdynamic@ @LDFLAGS@
LIBS = @LIBS@ @EXTRALIBS@ @DLLIB@
ifeq (@WIN32@,yes)
LIBVVP_VERSION = @LIBVVP_VERSION@
LIBVVP_SOVERSION = @LIBVVP_SOVERSION@
LIBBASENAME=vvp$(suffix)
LDFLAGS_SHARED = @rdynamic@ @shared@ @LDFLAGS@
ifeq (@MINGW32@,yes)
SLDIR=$(bindir)
SLEXT=dll
IMPEXT=dll.a
LIBPREFIX=lib
LIBNAME=$(LIBPREFIX)$(LIBBASENAME)
LIBSONAME=$(LIBNAME).$(SLEXT).$(LIBVVP_SOVERSION)
LIBREALNAME=$(LIBNAME).$(SLEXT).$(LIBVVP_VERSION)
LIBLINKNAME=$(LIBNAME).$(SLEXT)
LIBTARGET=$(LIBNAME)-$(LIBVVP_SOVERSION).$(SLEXT)
LIBBUILD=$(LIBTARGET)
LIBLINKFLAGS=-Wl,--out-implib,$(LIBNAME).$(IMPEXT) -Wl,--no-undefined
LIBPOSTBUILD=@true
LIBINSTALL=$(LIBTARGET)
LIBDEVELINSTALL=$(LIBNAME).$(IMPEXT)
else ifeq (@WIN32@,yes)
SLDIR=$(bindir)
SLEXT=dll
IMPEXT=lib
LIBPREFIX=
LIBNAME=$(LIBPREFIX)$(LIBBASENAME)
LIBSONAME=$(LIBNAME).$(SLEXT).$(LIBVVP_SOVERSION)
LIBREALNAME=$(LIBNAME).$(SLEXT).$(LIBVVP_VERSION)
LIBLINKNAME=$(LIBNAME).$(SLEXT)
LIBTARGET=$(LIBLINKNAME)
LIBBUILD=$(LIBLINKNAME)
LIBLINKFLAGS=
LIBPOSTBUILD=@true
LIBINSTALL=$(LIBTARGET)
LIBDEVELINSTALL=
else ifneq (,$(findstring darwin,@host_os@))
CXXFLAGS+= -fPIC
CFLAGS+= -fPIC
SLDIR=$(libdir)
SLEXT=dylib
LIBPREFIX=lib
LIBNAME=$(LIBPREFIX)$(LIBBASENAME)
LIBSONAME=$(LIBNAME).$(LIBVVP_SOVERSION).$(SLEXT)
LIBREALNAME=$(LIBNAME).$(LIBVVP_VERSION).$(SLEXT)
LIBLINKNAME=$(LIBNAME).$(SLEXT)
LIBTARGET=$(LIBREALNAME)
LIBBUILD=$(LIBTARGET)
LDFLAGS_SHARED=-dynamiclib
LIBLINKFLAGS= \
-Wl,-install_name,$(libdir)/$(LIBSONAME) \
-Wl,-compatibility_version,$(LIBVVP_SOVERSION) \
-Wl,-current_version,$(LIBVVP_VERSION)
LIBPOSTBUILD= \
ln -sf $(LIBREALNAME) $(LIBSONAME) && \
ln -sf $(LIBSONAME) $(LIBLINKNAME)
LIBINSTALL=$(LIBTARGET)
LIBDEVELINSTALL=
else
CXXFLAGS+= -fPIC
CFLAGS+= -fPIC
SLDIR=$(libdir)
SLEXT=so
LIBPREFIX=lib
LIBNAME=$(LIBPREFIX)$(LIBBASENAME)
LIBSONAME=$(LIBNAME).$(SLEXT).$(LIBVVP_SOVERSION)
LIBREALNAME=$(LIBNAME).$(SLEXT).$(LIBVVP_VERSION)
LIBLINKNAME=$(LIBNAME).$(SLEXT)
LIBTARGET=$(LIBREALNAME)
LIBBUILD=$(LIBLINKNAME)
LIBLINKFLAGS=-Wl,-soname,$(LIBSONAME)
LIBPOSTBUILD=ln -sf $(LIBREALNAME) $(LIBSONAME) && ln -sf $(LIBSONAME) $(LIBLINKNAME)
LIBINSTALL=$(LIBTARGET)
LIBDEVELINSTALL=
endif
MDIR1 = -DMODULE_DIR1='"$(libdir)/ivl$(suffix)"'
@ -110,7 +179,7 @@ else
endif
clean:
rm -f *.o *~ parse.cc parse.h lexor.cc tables.cc libvvp$(suffix).$(SLEXT)
rm -f *.o *~ parse.cc parse.h lexor.cc tables.cc $(LIBNAME)*.$(SLEXT)* libvvp.pc
rm -rf dep vvp@EXEEXT@ parse.output vvp.man vvp.ps vvp.pdf vvp.exp
distclean: clean
@ -137,16 +206,15 @@ dep:
ifeq (@LIBVVP@,yes)
CPPFLAGS+= -fpic
# To avoid setting LD_LIBRARY_PATH when running vvp from the build tree,
# add option -Wl,-rpath=`pwd` to the CXX command below.
vvp@EXEEXT@: main.o $(srcdir)/vvp.def libvvp$(suffix).$(SLEXT)
vvp@EXEEXT@: main.o $(srcdir)/vvp.def $(LIBBUILD)
$(CXX) $(LDFLAGS) -o vvp@EXEEXT@ main.o -L. $(LDFLAGS) -lvvp$(suffix) $(LIBS)
libvvp$(suffix).$(SLEXT): $LIB_OBJ
$(CXX) -shared $(LDFLAGS) -o libvvp$(suffix).$(SLEXT) $^ $(LIBS) $(dllib)
$(LIBBUILD): $(LIB_OBJ)
$(CXX) $(LDFLAGS_SHARED) $(LIBLINKFLAGS) -o $(LIBTARGET) $^ $(LIBS)
$(LIBPOSTBUILD)
else
ifeq (@WIN32@,yes)
# To support cocotb, we export the VPI functions directly. This allows
@ -221,7 +289,7 @@ stamp-config-h: $(srcdir)/config.h.in ../config.status
cd ..; ./config.status --header=vvp/config.h
config.h: stamp-config-h
install: all installdirs installfiles
install: all installdirs installfiles installpkgconfig
F = ./vvp@EXEEXT@ $(srcdir)/libvvp.h $(INSTALL_DOC)
@ -234,7 +302,16 @@ installpdf: vvp.pdf installdirs
installfiles: $(F) | installdirs
$(INSTALL_PROGRAM) ./vvp@EXEEXT@ "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@"
ifeq (@LIBVVP@,yes)
$(INSTALL_PROGRAM) ./libvvp$(suffix).$(SLEXT) "$(DESTDIR)$(SLDIR)/libvvp$(suffix).$(SLEXT)"
$(INSTALL_PROGRAM) ./$(LIBINSTALL) "$(DESTDIR)$(SLDIR)/$(LIBINSTALL)"
ifeq (@WIN32@,yes)
ifneq ($(LIBDEVELINSTALL),)
$(INSTALL_PROGRAM) ./$(LIBDEVELINSTALL) "$(DESTDIR)$(libdir)/$(LIBDEVELINSTALL)"
endif
else
# Install real library
ln -sf $(LIBREALNAME) "$(DESTDIR)$(SLDIR)/$(LIBSONAME)"
ln -sf $(LIBSONAME) "$(DESTDIR)$(SLDIR)/$(LIBLINKNAME)"
endif
$(INSTALL_DATA) $(srcdir)/libvvp.h "$(DESTDIR)$(includedir)/libvvp.h"
endif
@ -245,12 +322,25 @@ installdirs: $(srcdir)/../mkinstalldirs
"$(DESTDIR)$(INSTALL_DOCDIR)" \
"$(DESTDIR)$(INSTALL_PDFDIR)"
installpkgconfig:
$(INSTALL) -d "$(DESTDIR)$(pkgconfigdir)"
$(INSTALL_DATA) libvvp.pc "$(DESTDIR)$(pkgconfigdir)/libvvp$(suffix).pc"
uninstall: $(UNINSTALL32)
rm -f "$(DESTDIR)$(bindir)/vvp$(suffix)@EXEEXT@"
rm -f "$(DESTDIR)$(mandir)/man1/vvp$(suffix).1" "$(DESTDIR)$(pdfdir)/vvp$(suffix).pdf"
ifeq (@LIBVVP@,yes)
rm -f "$(DESTDIR)$(SLDIR)/libvvp$(suffix).$(SLEXT)"
rm -f "$(DESTDIR)$(SLDIR)/$(LIBINSTALL)"
ifeq (@WIN32@,yes)
ifneq ($(LIBDEVELINSTALL),)
rm -f "$(DESTDIR)$(libdir)/$(LIBDEVELINSTALL)"
endif
else
rm -f "$(DESTDIR)$(SLDIR)/$(LIBLINKNAME)"
rm -f "$(DESTDIR)$(SLDIR)/$(LIBSONAME)"
rm -f "$(DESTDIR)$(SLDIR)/$(LIBREALNAME)"
endif
rm -f "$(DESTDIR)$(pkgconfigdir)/libvvp$(suffix).pc"
rm -f "$(DESTDIR)$(includedir)/libvvp.h"
endif

10
vvp/libvvp.pc.in Normal file
View File

@ -0,0 +1,10 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libvvp@install_suffix@
Version: @LIBVVP_VERSION@
Description: Icarus Verilog VVP runtime library
Libs: -L${libdir} -lvvp@install_suffix@
Cflags: -I${includedir}/iverilog