On x86 CPUs supporting it, use write-combining memory mode for framebuffer
[helenos.git] / uspace / lib / meson.build
blob0c5cc14f8b36277d43e7e83c0802190ad3ecdc6d
2 # Copyright (c) 2019 Jiří Zárevúcky
3 # All rights reserved.
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
9 # - Redistributions of source code must retain the above copyright
10 #   notice, this list of conditions and the following disclaimer.
11 # - Redistributions in binary form must reproduce the above copyright
12 #   notice, this list of conditions and the following disclaimer in the
13 #   documentation and/or other materials provided with the distribution.
14 # - The name of the author may not be used to endorse or promote products
15 #   derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 always_static = not CONFIG_BUILD_SHARED_LIBS
31 # Which libraries are installed when CONFIG_DEVEL_FILES is enabled
32 installed_libs = [
33         'c',
34         'math',
35         'display',
36         'pixconv',
37         'posix',
38         'clui',
39         'pcm',
40         'hound',
41         'gfx',
42         'gfximage',
43         'ipcgfx',
44         'congfx',
45         'display',
46         'ui',
49 # IMPORTANT: Dependencies must be listed before libs that depend on them.
50 libs = [
51         'c',
53         'inet',
55         'input',
56         'output',
57         'console',
58         'device',
60         'block',
61         'clipboard',
62         'clui',
63         'codepage',
64         'compress',
65         'corecfg',
66         'cpp',
67         'crypto',
68         'dltest',
69         'fbfont',
70         'fdisk',
71         'fmtutil',
72         'fs',
73         'gfx',
74         'http',
75         'ipctest',
76         'label',
77         'math',
78         'minix',
79         'nettl',
80         'ofw',
81         'pcm',
82         'pcut',
83         'pixconv',
84         'posix',
85         'riff',
86         'scsi',
87         'sif',
88         'tbarcfg',
89         'trackmod',
90         'untar',
91         'uri',
93         'bithenge',
94         'congfx',
95         'drv',
96         'ext4',
97         'gfxfont',
98         'gfximage',
99         'hound',
100         'ipcgfx',
101         'memgfx',
102         'nic',
103         'usb',
104         'usbdev',
105         'usbhid',
106         'usbhost',
107         'usbvirt',
108         'virtio',
110         'ieee80211',
111         'ddev',
112         'dispcfg',
113         'display',
114         'wndmgt',
116         'ui',
119 # Generated list of include directory paths
120 include_paths = []
122 # Generated list of test sources
123 testfiles = []
125 # Text of the install script.
126 uspace_lib_devel_install_script_text = []
128 foreach l : libs
129         # Variables that might be defined in library meson files:
131         # List of source files.
132         # To set it correctly, use files('list.c', 'of.c', 'files.c')
133         # Often this is the only variable that needs to be set.
134         src = files()
136         # Public include directories. These are used by everyone who depends
137         # on this library.
138         # Use include_directories('include_dir1', 'include_dir2') to set this.
139         # If the variable is omitted, it defaults to 'include' subdirectory
140         # if it exists, or the source directory otherwise.
141         # If the library has no headers, you can use
142         # includes += include_directories()
143         includes = []
145         # Private include directories.
146         # Unnecessary if you always include private headers using relative
147         # paths, but may be useful if you need to override system headers.
148         private_includes = []
150         # List of dependency names.
151         # E.g. to use libnic and libuntar use
152         # `deps = [ 'nic', 'untar' ]`
153         deps = []
155         # Extra arguments for the C compiler.
156         # Don't use for arguments involving file paths.
157         c_args = []
159         # Shared object version of the library.
160         version = '0.0'
162         # Sources of unit tests.
163         # Automatically get compiled into a test binary,
164         # but not into the library itself.
165         test_src = []
167         # Language of the library.
168         # Currently supported options are 'c' and 'cpp', with 'c' being default.
169         language = 'c'
171         # Whether the library can be dynamically linked.
172         # Eventually, all libraries will be shared by default and this will go away.
173         allow_shared = false
175         subdir(l)
177         # Add `include` or `.` subdirectory to include dirs if needed.
178         if includes.length() == 0
179                 incdir = join_paths(l, 'include')
180                 if run_command('[', '-d', incdir, ']').returncode() == 0
181                         includes += include_directories(incdir)
183                         if installed_libs.contains(l)
184                                 _sdir = meson.current_source_dir() / l / 'include'
185                                 uspace_lib_devel_install_script_text += 'cp -R -L -T "@0@" "${DESTDIR}include/lib@1@"'.format(_sdir, l)
186                         endif
187                 else
188                         includes += include_directories(l)
190                         if installed_libs.contains(l)
191                                 _sdir = meson.current_source_dir() / l
192                                 uspace_lib_devel_install_script_text += 'mkdir -p "${DESTDIR}include/lib@0@"'.format(l)
193                                 uspace_lib_devel_install_script_text += 'cp -L -t "${DESTDIR}include/lib@0@" "@1@"/*.h || true'.format(l, _sdir)
194                         endif
195                 endif
196         endif
198         # Pretty much everything depends on libc.
199         if l != 'c'
200                 deps += 'c'
201         endif
203         if language == 'cpp' and l != 'cpp'
204                 deps += 'cpp'
205         endif
207         mapfile = meson.current_build_dir() / 'lib' + l + '.map'
209         link_args = [ '-Wl,--no-undefined,--no-allow-shlib-undefined' ]
210         # We want linker to generate link map for debugging.
211         link_args += [ '-Wl,-Map,' + mapfile ]
213         # Convert strings to dependency objects
214         # TODO: this dependency business is way too convoluted due to issues in current Meson
215         _any_deps = []
216         _static_deps = []
217         _shared_deps = []
218         _include_deps = []
219         foreach s : deps
220                 _any_deps += get_variable('lib' + s).get('any')
221                 _static_deps += get_variable('lib' + s).get('static')
222                 if not always_static
223                         _shared_deps += get_variable('lib' + s).get('shared')
224                 endif
225                 _include_deps += get_variable('lib' + s).get('include')
226         endforeach
228         install_static_lib = CONFIG_DEVEL_FILES and installed_libs.contains(l)
229         install_shared_lib = allow_shared
231         _shared_dep = disabler()
233         if src.length() > 0
234                 if not always_static
235                         _libname = 'lib' + l + '.so.' + version.split('.')[0]
237                         _shared_lib = shared_library(l, src,
238                                 # TODO: Include private headers using #include "quoted",
239                                 #       and get rid of private_includes.
240                                 include_directories: [ private_includes, includes ],
241                                 dependencies: _shared_deps,
242                                 c_args: arch_uspace_c_args + c_args,
243                                 cpp_args: arch_uspace_c_args + c_args,
244                                 link_args: arch_uspace_c_args + arch_uspace_link_args + link_args,
245                                 version: version,
246                                 build_by_default: true,
247                         )
249                         if install_shared_lib
250                                 install_files += [[ 'lib', _shared_lib.full_path(), _libname ]]
251                                 install_deps += [ _shared_lib ]
252                         endif
254                         if install_shared_lib and install_debug_files
255                                 install_files += [[ 'debug/lib', mapfile, _libname + '.map' ]]
256                         endif
258                         if disassemble
259                                 _disasm = custom_target('lib' + l + '.disasm',
260                                         command: [ objdump, '-S', '@INPUT@' ],
261                                         input: _shared_lib,
262                                         output: 'lib' + l + '.disasm',
263                                         capture: true,
264                                         build_by_default: true,
265                                 )
267                                 if install_shared_lib and install_debug_files
268                                         install_files += [[ 'debug/lib', _disasm.full_path(), _libname + '.disasm' ]]
269                                         install_deps += [ _disasm ]
270                                 endif
271                         endif
273                         _shared_dep = declare_dependency(
274                                 link_with: _shared_lib,
275                                 # TODO: Always use `include` subdirectory for public headers,
276                                 #       and ditch the variable.
277                                 include_directories: includes,
278                                 dependencies: _shared_deps,
279                         )
280                 endif
282                 _static_lib = static_library(l, src,
283                         # TODO: Include private headers using #include "quoted",
284                         #       and get rid of private_includes.
285                         include_directories: [ private_includes, includes ],
286                         dependencies: _include_deps,
287                         c_args: arch_uspace_c_args + c_args,
288                         cpp_args: arch_uspace_c_args + c_args,
289                 )
291                 if install_static_lib
292                         install_files += [[ 'lib', _static_lib.full_path(), 'lib' + l + '.a' ]]
293                         install_deps += [ _static_lib ]
294                 endif
296                 _static_dep = declare_dependency(
297                         link_with: _static_lib,
298                         # TODO: Always use `include` subdirectory for public headers,
299                         #       and ditch the variable.
300                         include_directories: includes,
301                         dependencies: _static_deps,
302                 )
304                 if always_static or not allow_shared
305                         _any_dep = declare_dependency(
306                                 link_with: _static_lib,
307                                 # TODO: Always use `include` subdirectory for public headers,
308                                 #       and ditch the variable.
309                                 include_directories: includes,
310                                 dependencies: _any_deps,
311                         )
312                 else
313                         _any_dep = declare_dependency(
314                                 link_with: _shared_lib,
315                                 # TODO: Always use `include` subdirectory for public headers,
316                                 #       and ditch the variable.
317                                 include_directories: includes,
318                                 dependencies: _any_deps,
319                         )
320                 endif
322                 _include_dep = declare_dependency(
323                         # TODO: Always use `include` subdirectory for public headers,
324                         #       and ditch the variable.
325                         include_directories: includes,
326                         dependencies: _include_deps,
327                 )
328         else
329                 # Header-only library.
330                 _any_dep = declare_dependency(
331                         include_directories: includes,
332                         dependencies: _any_deps,
333                 )
334                 _static_dep = declare_dependency(
335                         include_directories: includes,
336                         dependencies: _static_deps,
337                 )
338         endif
340         if test_src.length() > 0
341                 testfiles += [ {
342                         'name': l,
343                         'src': test_src,
344                         'includes': [ private_includes, includes ],
345                 } ]
346         endif
348         set_variable('lib' + l, {
349                 'any': _any_dep,
350                 'static': _static_dep,
351                 'shared': _shared_dep,
352                 'include': _include_dep,
353         })
354 endforeach
356 if not CONFIG_PCUT_TESTS
357         subdir_done()
358 endif
360 # Test binaries
361 foreach test : testfiles
362         _testname = test['name']
363         _libname = _testname.split('-')[0]
364         _ldargs = []
365         _test_binname = 'test-lib' + _testname
367         if link_map
368                 # We want linker to generate link map for debugging.
369                 _ldargs += [ '-Wl,-Map,' + meson.current_build_dir() / _test_binname + '.map' ]
370         endif
372         _bin = executable(_test_binname, test.get('src'),
373                 include_directories: test.get('includes'),
374                 dependencies: [ get_variable('lib' + _libname).get('any'), libpcut.get('any') ],
375                 link_whole: libstartfiles,
376                 c_args: arch_uspace_c_args,
377                 cpp_args: arch_uspace_c_args,
378                 link_args: arch_uspace_c_args + arch_uspace_link_args + _ldargs,
379                 build_by_default: true,
380         )
382         install_files += [[ 'test', _bin.full_path(), _test_binname ]]
383         install_deps += [ _bin ]
385         if disassemble
386                 _disasm = custom_target(_test_binname + '.disasm',
387                         command: [ objdump, '-S', '@INPUT@' ],
388                         input: _bin,
389                         output: _test_binname + '.disasm',
390                         capture: true,
391                         build_by_default: true,
392                 )
394                 if install_debug_files
395                         install_files += [[ 'debug/test', _disasm.full_path(), _test_binname + '.disasm' ]]
396                         install_deps += [ _disasm ]
397                 endif
398         endif
399 endforeach