diff --git a/app/test-pmd/meson.build b/app/test-pmd/meson.build
index 72fe818c7..3e591683d 100644
--- a/app/test-pmd/meson.build
+++ b/app/test-pmd/meson.build
@@ -75,6 +75,5 @@ executable('dpdk-testpmd',
 	sources,
 	link_whole: link_libs,
 	dependencies: dep_objs,
-	link_args: eal_extra_link_arg, # add -ldl for linux, -lexecinfo for BSD
 	install_rpath: join_paths(get_option('prefix'), driver_install_path),
 	install: true)
diff --git a/config/meson.build b/config/meson.build
index 8e4a703c7..d7fb64422 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -33,10 +33,24 @@
 machine = get_option('machine')
 dpdk_conf.set('RTE_MACHINE', machine)
 add_project_arguments('-march=@0@'.format(machine), language: 'c')
+
+# use pthreads
+add_project_link_arguments('-pthread', language: 'c')
+dpdk_extra_ldflags += '-pthread'
+
 # some libs depend on maths lib
 add_project_link_arguments('-lm', language: 'c')
 dpdk_extra_ldflags += '-lm'
 
+# for linux link against dl, for bsd execinfo
+if host_machine.system() == 'linux'
+	link_lib = 'dl'
+else
+	link_lib = 'execinfo'
+endif
+add_project_link_arguments('-l' + link_lib, language: 'c')
+dpdk_extra_ldflags += '-l' + link_lib
+
 # check for libraries used in multiple places in DPDK
 has_libnuma = 0
 numa_dep = cc.find_library('numa', required: false)
diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
index 3c59cbca5..ba85cab6f 100644
--- a/doc/guides/contributing/coding_style.rst
+++ b/doc/guides/contributing/coding_style.rst
@@ -840,6 +840,15 @@ headers
 	source files, these should be specified using the meson ``files()``
 	function.
 
+includes:
+	**Default Value = []**.
+	Used to indicate any additional header file paths which should be
+	added to the header search path for other libs depending on this
+	library. EAL uses this so that other libraries building against it
+	can find the headers in subdirectories of the main EAL directory. The
+	base directory of each library is always given in the include path,
+	it does not need to be specified here.
+
 name
 	**Default Value = library name derived from the directory name**.
 	If a library's .so or .a file differs from that given in the directory
diff --git a/drivers/net/e1000/base/meson.build b/drivers/net/e1000/base/meson.build
index 9592762c9..7c0710ec9 100644
--- a/drivers/net/e1000/base/meson.build
+++ b/drivers/net/e1000/base/meson.build
@@ -60,6 +60,6 @@ foreach flag: error_cflags
 endforeach
 
 base_lib = static_library('e1000_base', sources,
-	dependencies: rte_eal,
+	dependencies: dep_rte_eal,
 	c_args: c_args)
 base_objs = base_lib.extract_all_objects()
diff --git a/drivers/net/fm10k/base/meson.build b/drivers/net/fm10k/base/meson.build
index e351f96da..8a371b6ca 100644
--- a/drivers/net/fm10k/base/meson.build
+++ b/drivers/net/fm10k/base/meson.build
@@ -50,6 +50,6 @@ foreach flag: error_cflags
 endforeach
 
 base_lib = static_library('fm10k_base', sources,
-	dependencies: rte_eal,
+	dependencies: dep_rte_eal,
 	c_args: c_args)
 base_objs = base_lib.extract_all_objects()
diff --git a/drivers/net/i40e/base/meson.build b/drivers/net/i40e/base/meson.build
index 2eae30fc7..8b491ad89 100644
--- a/drivers/net/i40e/base/meson.build
+++ b/drivers/net/i40e/base/meson.build
@@ -51,6 +51,6 @@ foreach flag: error_cflags
 endforeach
 
 base_lib = static_library('i40e_base', sources,
-	dependencies: rte_eal,
+	dependencies: dep_rte_eal,
 	c_args: c_args)
 base_objs = base_lib.extract_all_objects()
diff --git a/drivers/net/ixgbe/base/meson.build b/drivers/net/ixgbe/base/meson.build
index 5a3d73311..1781f2eb3 100644
--- a/drivers/net/ixgbe/base/meson.build
+++ b/drivers/net/ixgbe/base/meson.build
@@ -55,6 +55,6 @@ foreach flag: error_cflags
 endforeach
 
 base_lib = static_library('ixgbe_base', sources,
-	dependencies: rte_eal,
+	dependencies: dep_rte_eal,
 	c_args: c_args)
 base_objs = base_lib.extract_all_objects()
diff --git a/lib/librte_eal/bsdapp/eal/meson.build b/lib/librte_eal/bsdapp/eal/meson.build
index f9473a1d0..df93a00f4 100644
--- a/lib/librte_eal/bsdapp/eal/meson.build
+++ b/lib/librte_eal/bsdapp/eal/meson.build
@@ -29,7 +29,9 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-sources = ['eal_alarm.c',
+env_objs = []
+env_headers = []
+env_sources = files('eal_alarm.c',
 		'eal_debug.c',
 		'eal_hugepage_info.c',
 		'eal_interrupts.c',
@@ -38,35 +40,5 @@ sources = ['eal_alarm.c',
 		'eal_timer.c',
 		'eal.c',
 		'eal_memory.c',
-]
-
-eal_extra_link_arg = '-lexecinfo'
-
-if get_option('per_library_versions')
-	lib_version = '@0@.1'.format(version)
-	so_version = '@0@'.format(version)
-else
-	pver = meson.project_version().split('.')
-	lib_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
-	so_version = lib_version
-endif
-
-eal_lib = library('rte_eal', sources, eal_common_sources, eal_common_arch_sources,
-			dependencies: dependency('threads'),
-			include_directories : eal_inc,
-			version: lib_version,
-			soversion: so_version,
-			c_args: '-D_GNU_SOURCE',
-			link_depends: version_map,
-			link_args: [eal_extra_link_arg,
-				'-Wl,--version-script=' + version_map],
-			install: true
 )
 
-dpdk_libraries += eal_lib
-dpdk_extra_ldflags += ['-pthread', eal_extra_link_arg]
-
-rte_eal = declare_dependency(link_with: eal_lib,
-		include_directories: eal_inc,
-		dependencies: dependency('threads'))
-set_variable('dep_rte_eal', rte_eal)
diff --git a/lib/librte_eal/bsdapp/meson.build b/lib/librte_eal/bsdapp/meson.build
deleted file mode 100644
index eadfca438..000000000
--- a/lib/librte_eal/bsdapp/meson.build
+++ /dev/null
@@ -1,55 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2017 Intel Corporation.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-subdir('eal')
-kmods = ['contigmem', 'nic_uio']
-
-# for building kernel modules, we use kernel build system using make, as
-# with Linux. We have a skeleton BSDmakefile, which pulls many of its
-# values from the environment. Each module only has a single source file
-# right now, which allows us to simplify things. We pull in the source files
-# from the individual meson.build files, and then use a custom target to call
-# make, passing in the values as environmental parameters.
-kmod_cflags = ['-I' + meson.build_root(),
-		'-I' + join_paths(meson.source_root(), 'config'),
-		'-include rte_config.h']
-foreach k:kmods
-	subdir(k)
-	custom_target(k,
-		input: [files('BSDmakefile.meson'), sources],
-		output: k + '.ko',
-		command: ['make', '-f', '@INPUT0@',
-			'KMOD_SRC=@INPUT1@',
-			'KMOD=' + k,
-			'VPATH=' + join_paths(meson.current_source_dir(), k),
-			'KMOD_CFLAGS=' + ' '.join(kmod_cflags)],
-		build_by_default: get_option('enable_kmods'))
-endforeach
diff --git a/lib/librte_eal/common/arch/meson.build b/lib/librte_eal/common/arch/meson.build
deleted file mode 100644
index 9e2539fde..000000000
--- a/lib/librte_eal/common/arch/meson.build
+++ /dev/null
@@ -1,33 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2017 Intel Corporation.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-eal_inc += include_directories(arch_subdir)
-subdir(arch_subdir)
diff --git a/lib/librte_eal/common/include/arch/meson.build b/lib/librte_eal/common/include/arch/meson.build
deleted file mode 100644
index 9e2539fde..000000000
--- a/lib/librte_eal/common/include/arch/meson.build
+++ /dev/null
@@ -1,33 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2017 Intel Corporation.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-eal_inc += include_directories(arch_subdir)
-subdir(arch_subdir)
diff --git a/lib/librte_eal/common/include/meson.build b/lib/librte_eal/common/include/meson.build
deleted file mode 100644
index 57b45d1d0..000000000
--- a/lib/librte_eal/common/include/meson.build
+++ /dev/null
@@ -1,71 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2017 Intel Corporation.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-eal_inc += include_directories('.')
-
-common_headers = [
-	'rte_alarm.h',
-	'rte_branch_prediction.h',
-	'rte_bus.h',
-	'rte_bitmap.h',
-	'rte_common.h',
-	'rte_debug.h',
-	'rte_devargs.h',
-	'rte_dev.h',
-	'rte_eal.h',
-	'rte_eal_interrupts.h',
-	'rte_eal_memconfig.h',
-	'rte_errno.h',
-	'rte_hexdump.h',
-	'rte_interrupts.h',
-	'rte_keepalive.h',
-	'rte_launch.h',
-	'rte_lcore.h',
-	'rte_log.h',
-	'rte_malloc.h',
-	'rte_malloc_heap.h',
-	'rte_memory.h',
-	'rte_memzone.h',
-	'rte_pci_dev_feature_defs.h',
-	'rte_pci_dev_features.h',
-	'rte_per_lcore.h',
-	'rte_random.h',
-	'rte_service.h',
-	'rte_service_component.h',
-	'rte_string_fns.h',
-	'rte_tailq.h',
-	'rte_time.h',
-	'rte_version.h']
-
-install_headers(common_headers)
-install_subdir('generic', install_dir : get_option('includedir'))
-
-subdir('arch')
diff --git a/lib/librte_eal/common/meson.build b/lib/librte_eal/common/meson.build
index 3bec97c14..f806d8e42 100644
--- a/lib/librte_eal/common/meson.build
+++ b/lib/librte_eal/common/meson.build
@@ -29,9 +29,11 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-eal_inc += include_directories('.')
+eal_inc += include_directories('.', 'include',
+		join_paths('include/arch', arch_subdir))
 
-eal_common_sources = files(
+common_objs = []
+common_sources = files(
 	'eal_common_bus.c',
 	'eal_common_cpuflags.c',
 	'eal_common_devargs.c',
@@ -64,5 +66,61 @@ eal_common_sources = files(
 	'rte_service.c'
 )
 
-subdir('include')
-subdir('arch')
+# get architecture specific sources and objs
+eal_common_arch_sources = []
+eal_common_arch_objs = []
+subdir(join_paths('arch', arch_subdir))
+common_sources += eal_common_arch_sources
+common_objs += eal_common_arch_objs
+
+common_headers = files(
+	'include/rte_alarm.h',
+	'include/rte_branch_prediction.h',
+	'include/rte_bus.h',
+	'include/rte_bitmap.h',
+	'include/rte_common.h',
+	'include/rte_debug.h',
+	'include/rte_devargs.h',
+	'include/rte_dev.h',
+	'include/rte_eal.h',
+	'include/rte_eal_memconfig.h',
+	'include/rte_eal_interrupts.h',
+	'include/rte_errno.h',
+	'include/rte_hexdump.h',
+	'include/rte_interrupts.h',
+	'include/rte_keepalive.h',
+	'include/rte_launch.h',
+	'include/rte_lcore.h',
+	'include/rte_log.h',
+	'include/rte_malloc.h',
+	'include/rte_malloc_heap.h',
+	'include/rte_memory.h',
+	'include/rte_memzone.h',
+	'include/rte_pci_dev_feature_defs.h',
+	'include/rte_pci_dev_features.h',
+	'include/rte_per_lcore.h',
+	'include/rte_random.h',
+	'include/rte_service.h',
+	'include/rte_service_component.h',
+	'include/rte_string_fns.h',
+	'include/rte_tailq.h',
+	'include/rte_time.h',
+	'include/rte_version.h')
+
+# special case install the generic headers, since they go in a subdir
+generic_headers = files(
+	'include/generic/rte_atomic.h',
+	'include/generic/rte_byteorder.h',
+	'include/generic/rte_cpuflags.h',
+	'include/generic/rte_cycles.h',
+	'include/generic/rte_io.h',
+	'include/generic/rte_memcpy.h',
+	'include/generic/rte_pause.h',
+	'include/generic/rte_prefetch.h',
+	'include/generic/rte_rwlock.h',
+	'include/generic/rte_spinlock.h',
+	'include/generic/rte_vect.h')
+install_headers(generic_headers, subdir: 'generic')
+
+# get and install the architecture specific headers
+subdir(join_paths('include/arch', arch_subdir))
diff --git a/lib/librte_eal/linuxapp/eal/meson.build b/lib/librte_eal/linuxapp/eal/meson.build
index dc93a0236..ce3518aec 100644
--- a/lib/librte_eal/linuxapp/eal/meson.build
+++ b/lib/librte_eal/linuxapp/eal/meson.build
@@ -32,7 +32,9 @@
 eal_inc += include_directories('include')
 install_subdir('include/exec-env', install_dir: get_option('includedir'))
 
-sources = ['eal_alarm.c',
+env_objs = []
+env_headers = []
+env_sources = files('eal_alarm.c',
 		'eal_debug.c',
 		'eal_hugepage_info.c',
 		'eal_interrupts.c',
@@ -44,38 +46,8 @@ sources = ['eal_alarm.c',
 		'eal_vfio_mp_sync.c',
 		'eal.c',
 		'eal_memory.c',
-]
+)
 
-eal_extra_link_arg = '-ldl'
 if has_libnuma == 1
 	dpdk_conf.set10('RTE_EAL_NUMA_AWARE_HUGEPAGES', true)
 endif
-
-if get_option('per_library_versions')
-	lib_version = '@0@.1'.format(version)
-	so_version = '@0@'.format(version)
-else
-	pver = meson.project_version().split('.')
-	lib_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
-	so_version = lib_version
-endif
-
-eal_lib = library('rte_eal', sources, eal_common_sources, eal_common_arch_sources,
-			dependencies: dependency('threads'),
-			include_directories : eal_inc,
-			version: lib_version,
-			soversion: so_version,
-			c_args: '-D_GNU_SOURCE',
-			link_depends: version_map,
-			link_args: [eal_extra_link_arg,
-				'-Wl,--version-script=' + version_map],
-			install: true
-)
-
-dpdk_libraries += eal_lib
-dpdk_extra_ldflags += ['-pthread', eal_extra_link_arg]
-
-rte_eal = declare_dependency(link_with: eal_lib,
-		include_directories: eal_inc,
-		dependencies: dependency('threads'))
-set_variable('dep_rte_eal', rte_eal)
diff --git a/lib/librte_eal/linuxapp/igb_uio/meson.build b/lib/librte_eal/linuxapp/igb_uio/meson.build
index 4712756ea..9408e312a 100644
--- a/lib/librte_eal/linuxapp/igb_uio/meson.build
+++ b/lib/librte_eal/linuxapp/igb_uio/meson.build
@@ -29,6 +29,12 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+kernel_dir = get_option('kernel_dir')
+if kernel_dir == ''
+	kernel_version = run_command('uname', '-r').stdout().strip()
+	kernel_dir = '/lib/modules/' + kernel_version + '/build'
+endif
+
 mkfile = custom_target('igb_uio_makefile',
 	output: 'Makefile',
 	command: ['touch', '@OUTPUT@'])
@@ -43,4 +49,4 @@ custom_target('igb_uio',
 			'/../../common/include',
 		'modules'],
 	depends: mkfile,
-	build_by_default: true)
+	build_by_default: get_option('enable_kmods'))
diff --git a/lib/librte_eal/linuxapp/meson.build b/lib/librte_eal/linuxapp/meson.build
deleted file mode 100644
index 16a3f6b8b..000000000
--- a/lib/librte_eal/linuxapp/meson.build
+++ /dev/null
@@ -1,42 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2017 Intel Corporation.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-subdir('eal')
-
-if get_option('enable_kmods')
-	kernel_dir = get_option('kernel_dir')
-	if kernel_dir == ''
-		kernel_version = run_command('uname', '-r').stdout().strip()
-		kernel_dir = '/lib/modules/' + kernel_version + '/build'
-	endif
-
-	subdir('igb_uio')
-endif
diff --git a/lib/librte_eal/meson.build b/lib/librte_eal/meson.build
index 71f973991..a2dceee23 100644
--- a/lib/librte_eal/meson.build
+++ b/lib/librte_eal/meson.build
@@ -29,17 +29,52 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-version = 4  # the version of the EAL API
+# Custom EAL processing. EAL is complicated enough that it can't just
+# have a straight list of headers and source files.
+# Initially pull in common settings
 eal_inc = [global_inc]
-subdir('common')
+subdir('common') # defines common_sources, common_objs, etc.
 
-version_map = join_paths(meson.current_source_dir(), 'rte_eal_version.map')
+# Now do OS/exec-env specific settings, including building kernel modules
+# The <exec-env>/eal/meson.build file should define env_sources, etc.
 if host_machine.system() == 'linux'
 	dpdk_conf.set('RTE_EXEC_ENV_LINUXAPP', 1)
-	subdir('linuxapp')
+	subdir('linuxapp/eal')
+	subdir('linuxapp/igb_uio')
+
 elif host_machine.system() == 'freebsd'
 	dpdk_conf.set('RTE_EXEC_ENV_BSDAPP', 1)
-	subdir('bsdapp')
+	subdir('bsdapp/eal')
+	kmods = ['contigmem', 'nic_uio']
+
+	# for building kernel modules, we use kernel build system using make, as
+	# with Linux. We have a skeleton BSDmakefile, which pulls many of its
+	# values from the environment. Each module only has a single source file
+	# right now, which allows us to simplify things. We pull in the sourcer
+	# files from the individual meson.build files, and then use a custom
+	# target to call make, passing in the values as env parameters.
+	kmod_cflags = ['-I' + meson.build_root(),
+			'-I' + join_paths(meson.source_root(), 'config'),
+			'-include rte_config.h']
+	foreach k:kmods
+		subdir(join_paths('bsdapp', k))
+		custom_target(k,
+			input: [files('bsdapp/BSDmakefile.meson'), sources],
+			output: k + '.ko',
+			command: ['make', '-f', '@INPUT0@',
+				'KMOD_SRC=@INPUT1@',
+				'KMOD=' + k,
+				'VPATH=' + join_paths(meson.current_source_dir(), k),
+				'KMOD_CFLAGS=' + ' '.join(kmod_cflags)],
+			build_by_default: get_option('enable_kmods'))
+	endforeach
 else
 	error('unsupported system type @0@'.format(hostmachine.system()))
 endif
+
+version = 6  # the version of the EAL API
+cflags += '-D_GNU_SOURCE'
+sources = common_sources + env_sources
+objs = common_objs + env_objs
+headers = common_headers + env_headers
+includes = eal_inc
diff --git a/lib/meson.build b/lib/meson.build
index b0e405f1e..76cac1023 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -29,9 +29,6 @@
 #   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 #   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# special case for eal, not a simple lib, and compat, just a header
-subdir('librte_eal')
-subdir('librte_compat')
 
 # process all libraries equally, as far as possible
 # "core" libs first, then others alphebetically as far as possible
@@ -39,7 +36,8 @@ subdir('librte_compat')
 # sometimes skip deps that would be implied by others, e.g. if mempool is
 # given as a dep, no need to mention ring. This is especially true for the
 # core libs which are widely reused, so their deps are kept to a minimum.
-libraries = ['ring', 'mempool', 'mbuf', 'net', 'ether', 'pci', # core
+libraries = [ 'compat', # just a header, used for versioning
+	'eal', 'ring', 'mempool', 'mbuf', 'net', 'ether', 'pci', # core
 	'metrics', # bitrate/latency stats depends on this
 	'hash',    # efd depends on this
 	'kvargs',  # cryptodev depends on this
@@ -60,13 +58,18 @@ foreach l:libraries
 	version = 1
 	sources = []
 	headers = []
+	includes = []
 	cflags = []
-	objs = [] # other object files to link against, used e.g. for instruction-
-	          # optimized versions of code
+	objs = [] # other object files to link against, used e.g. for
+	          # instruction-set optimized versions of code
+
 	# use "deps" for internal DPDK dependencies, and "ext_deps" for
 	# external package/library requirements
-	deps = ['eal']
 	ext_deps = []
+	deps = ['eal']   # eal is standard dependency except for itself
+	if l == 'eal'
+		deps = []
+	endif
 
 	dir_name = 'librte_' + l
 	subdir(dir_name)
@@ -75,39 +78,48 @@ foreach l:libraries
 		dpdk_conf.set('RTE_LIBRTE_' + name.to_upper(), 1)
 		install_headers(headers)
 
-		dep_objs = ext_deps
-		foreach d:deps
-			dep_objs += [get_variable('dep_rte_' + d)]
-		endforeach
+		libname = 'rte_' + name
+		includes += include_directories(dir_name)
 
-		if get_option('per_library_versions')
-			lib_version = '@0@.1'.format(version)
-			so_version = '@0@'.format(version)
+		if sources.length() == 0
+			# if no C files, just set a dependency on header path
+			dep = declare_dependency(include_directories: includes)
 		else
-			pver = meson.project_version().split('.')
-			lib_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
-			so_version = lib_version
-		endif
+			dep_objs = ext_deps
+			foreach d:deps
+				dep_objs += [get_variable('dep_rte_' + d)]
+			endforeach
 
-		version_map = '@0@/@1@/rte_@2@_version.map'.format(
-				meson.current_source_dir(), dir_name, name)
-		libname = 'rte_' + name
-		lib = library(libname,
-				sources,
-				objects: objs,
-				c_args: cflags,
-				dependencies: dep_objs,
-				include_directories: include_directories(dir_name),
-				link_args: '-Wl,--version-script=' + version_map,
-				link_depends: version_map,
-				version: lib_version,
-				soversion: so_version,
-				install: true)
-		dep = declare_dependency(link_with: lib,
-				include_directories: include_directories(dir_name),
-				dependencies: dep_objs)
-		set_variable('dep_' + libname, dep)
+			if get_option('per_library_versions')
+				lib_version = '@0@.1'.format(version)
+				so_version = '@0@'.format(version)
+			else
+				prj_ver = meson.project_version().split('.')
+				lib_version = '@0@.@1@'.format(
+						prj_ver.get(0), prj_ver.get(1))
+				so_version = lib_version
+			endif
 
-		dpdk_libraries = [lib] + dpdk_libraries
-	endif
+			version_map = '@0@/@1@/rte_@2@_version.map'.format(
+					meson.current_source_dir(), dir_name, name)
+			lib = library(libname,
+					sources,
+					objects: objs,
+					c_args: cflags,
+					dependencies: dep_objs,
+					include_directories: includes,
+					link_args: '-Wl,--version-script=' + version_map,
+					link_depends: version_map,
+					version: lib_version,
+					soversion: so_version,
+					install: true)
+			dep = declare_dependency(link_with: lib,
+					include_directories: includes,
+					dependencies: dep_objs)
+
+			dpdk_libraries = [lib] + dpdk_libraries
+		endif # sources.length() > 0
+
+		set_variable('dep_' + libname, dep)
+	endif # if build
 endforeach
