C++ strings: missing space for null terminator
[helenos.git] / uspace / lib / meson.build
blob4fdaebeca5b5dfcf853c0cd07bac1406330fc030
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         'device',
57         'block',
58         'clui',
59         'codepage',
60         'compress',
61         'cpp',
62         'crypto',
63         'dltest',
64         'fbfont',
65         'fdisk',
66         'fmtutil',
67         'fs',
68         'gfx',
69         'http',
70         'label',
71         'math',
72         'minix',
73         'nettl',
74         'ofw',
75         'pcm',
76         'pcut',
77         'pixconv',
78         'posix',
79         'riff',
80         'scsi',
81         'sif',
82         'tbarcfg',
83         'trackmod',
84         'untar',
85         'uri',
87         'bithenge',
88         'congfx',
89         'drv',
90         'ext4',
91         'gfxfont',
92         'gfximage',
93         'hound',
94         'ipcgfx',
95         'memgfx',
96         'nic',
97         'usb',
98         'usbdev',
99         'usbhid',
100         'usbhost',
101         'usbvirt',
102         'virtio',
104         'ieee80211',
105         'ddev',
106         'dispcfg',
107         'display',
108         'wndmgt',
110         'ui',
113 # Generated list of include directory paths
114 include_paths = []
116 # Generated list of test sources
117 testfiles = []
119 # Text of the install script.
120 uspace_lib_devel_install_script_text = []
122 foreach l : libs
123         # Variables that might be defined in library meson files:
125         # List of source files.
126         # To set it correctly, use files('list.c', 'of.c', 'files.c')
127         # Often this is the only variable that needs to be set.
128         src = files()
130         # Public include directories. These are used by everyone who depends
131         # on this library.
132         # Use include_directories('include_dir1', 'include_dir2') to set this.
133         # If the variable is omitted, it defaults to 'include' subdirectory
134         # if it exists, or the source directory otherwise.
135         # If the library has no headers, you can use
136         # includes += include_directories()
137         includes = []
139         # Private include directories.
140         # Unnecessary if you always include private headers using relative
141         # paths, but may be useful if you need to override system headers.
142         private_includes = []
144         # List of dependency names.
145         # E.g. to use libnic and libuntar use
146         # `deps = [ 'nic', 'untar' ]`
147         deps = []
149         # Extra arguments for the C compiler.
150         # Don't use for arguments involving file paths.
151         c_args = []
153         # Shared object version of the library.
154         version = '0.0'
156         # Sources of unit tests.
157         # Automatically get compiled into a test binary,
158         # but not into the library itself.
159         test_src = []
161         # Language of the library.
162         # Currently supported options are 'c' and 'cpp', with 'c' being default.
163         language = 'c'
165         # Whether the library can be dynamically linked.
166         # Eventually, all libraries will be shared by default and this will go away.
167         allow_shared = false
169         subdir(l)
171         # Add `include` or `.` subdirectory to include dirs if needed.
172         if includes.length() == 0
173                 incdir = join_paths(l, 'include')
174                 if run_command('[', '-d', incdir, ']').returncode() == 0
175                         includes += include_directories(incdir)
177                         if installed_libs.contains(l)
178                                 _sdir = meson.current_source_dir() / l / 'include'
179                                 uspace_lib_devel_install_script_text += 'cp -R -L -T "@0@" "${DESTDIR}include/lib@1@"'.format(_sdir, l)
180                         endif
181                 else
182                         includes += include_directories(l)
184                         if installed_libs.contains(l)
185                                 _sdir = meson.current_source_dir() / l
186                                 uspace_lib_devel_install_script_text += 'mkdir -p "${DESTDIR}include/lib@0@"'.format(l)
187                                 uspace_lib_devel_install_script_text += 'cp -L -t "${DESTDIR}include/lib@0@" "@1@"/*.h || true'.format(l, _sdir)
188                         endif
189                 endif
190         endif
192         # Pretty much everything depends on libc.
193         if l != 'c'
194                 deps += 'c'
195         endif
197         if language == 'cpp' and l != 'cpp'
198                 deps += 'cpp'
199         endif
201         mapfile = meson.current_build_dir() / 'lib' + l + '.map'
203         link_args = [ '-Wl,--no-undefined,--no-allow-shlib-undefined' ]
204         # We want linker to generate link map for debugging.
205         link_args += [ '-Wl,-Map,' + mapfile ]
207         # Convert strings to dependency objects
208         # TODO: this dependency business is way too convoluted due to issues in current Meson
209         _any_deps = []
210         _static_deps = []
211         _shared_deps = []
212         _include_deps = []
213         foreach s : deps
214                 _any_deps += get_variable('lib' + s).get('any')
215                 _static_deps += get_variable('lib' + s).get('static')
216                 if not always_static
217                         _shared_deps += get_variable('lib' + s).get('shared')
218                 endif
219                 _include_deps += get_variable('lib' + s).get('include')
220         endforeach
222         install_static_lib = CONFIG_DEVEL_FILES and installed_libs.contains(l)
223         install_shared_lib = allow_shared
225         _shared_dep = disabler()
227         if src.length() > 0
228                 if not always_static
229                         _libname = 'lib' + l + '.so.' + version.split('.')[0]
231                         _shared_lib = shared_library(l, src,
232                                 # TODO: Include private headers using #include "quoted",
233                                 #       and get rid of private_includes.
234                                 include_directories: [ private_includes, includes ],
235                                 dependencies: _shared_deps,
236                                 c_args: arch_uspace_c_args + c_args,
237                                 cpp_args: arch_uspace_c_args + c_args,
238                                 link_args: arch_uspace_c_args + arch_uspace_link_args + link_args,
239                                 version: version,
240                                 build_by_default: true,
241                         )
243                         if install_shared_lib
244                                 install_files += [[ 'lib', _shared_lib.full_path(), _libname ]]
245                                 install_deps += [ _shared_lib ]
246                         endif
248                         if install_shared_lib and install_debug_files
249                                 install_files += [[ 'debug/lib', mapfile, _libname + '.map' ]]
250                         endif
252                         if disassemble
253                                 _disasm = custom_target('lib' + l + '.disasm',
254                                         command: [ objdump, '-S', '@INPUT@' ],
255                                         input: _shared_lib,
256                                         output: 'lib' + l + '.disasm',
257                                         capture: true,
258                                         build_by_default: true,
259                                 )
261                                 if install_shared_lib and install_debug_files
262                                         install_files += [[ 'debug/lib', _disasm.full_path(), _libname + '.disasm' ]]
263                                         install_deps += [ _disasm ]
264                                 endif
265                         endif
267                         _shared_dep = declare_dependency(
268                                 link_with: _shared_lib,
269                                 # TODO: Always use `include` subdirectory for public headers,
270                                 #       and ditch the variable.
271                                 include_directories: includes,
272                                 dependencies: _shared_deps,
273                         )
274                 endif
276                 _static_lib = static_library(l, src,
277                         # TODO: Include private headers using #include "quoted",
278                         #       and get rid of private_includes.
279                         include_directories: [ private_includes, includes ],
280                         dependencies: _include_deps,
281                         c_args: arch_uspace_c_args + c_args,
282                         cpp_args: arch_uspace_c_args + c_args,
283                 )
285                 if install_static_lib
286                         install_files += [[ 'lib', _static_lib.full_path(), 'lib' + l + '.a' ]]
287                         install_deps += [ _static_lib ]
288                 endif
290                 _static_dep = declare_dependency(
291                         link_with: _static_lib,
292                         # TODO: Always use `include` subdirectory for public headers,
293                         #       and ditch the variable.
294                         include_directories: includes,
295                         dependencies: _static_deps,
296                 )
298                 if always_static or not allow_shared
299                         _any_dep = declare_dependency(
300                                 link_with: _static_lib,
301                                 # TODO: Always use `include` subdirectory for public headers,
302                                 #       and ditch the variable.
303                                 include_directories: includes,
304                                 dependencies: _any_deps,
305                         )
306                 else
307                         _any_dep = declare_dependency(
308                                 link_with: _shared_lib,
309                                 # TODO: Always use `include` subdirectory for public headers,
310                                 #       and ditch the variable.
311                                 include_directories: includes,
312                                 dependencies: _any_deps,
313                         )
314                 endif
316                 _include_dep = declare_dependency(
317                         # TODO: Always use `include` subdirectory for public headers,
318                         #       and ditch the variable.
319                         include_directories: includes,
320                         dependencies: _include_deps,
321                 )
322         else
323                 # Header-only library.
324                 _any_dep = declare_dependency(
325                         include_directories: includes,
326                         dependencies: _any_deps,
327                 )
328                 _static_dep = declare_dependency(
329                         include_directories: includes,
330                         dependencies: _static_deps,
331                 )
332         endif
334         if test_src.length() > 0
335                 testfiles += [ {
336                         'name': l,
337                         'src': test_src,
338                         'includes': [ private_includes, includes ],
339                 } ]
340         endif
342         set_variable('lib' + l, {
343                 'any': _any_dep,
344                 'static': _static_dep,
345                 'shared': _shared_dep,
346                 'include': _include_dep,
347         })
348 endforeach
350 if not CONFIG_PCUT_TESTS
351         subdir_done()
352 endif
354 # Test binaries
355 foreach test : testfiles
356         _testname = test['name']
357         _libname = _testname.split('-')[0]
358         _ldargs = []
359         _test_binname = 'test-lib' + _testname
361         if link_map
362                 # We want linker to generate link map for debugging.
363                 _ldargs += [ '-Wl,-Map,' + meson.current_build_dir() / _test_binname + '.map' ]
364         endif
366         _bin = executable(_test_binname, test.get('src'),
367                 include_directories: test.get('includes'),
368                 dependencies: [ get_variable('lib' + _libname).get('any'), libpcut.get('any') ],
369                 link_whole: libstartfiles,
370                 c_args: arch_uspace_c_args,
371                 cpp_args: arch_uspace_c_args,
372                 link_args: arch_uspace_c_args + arch_uspace_link_args + _ldargs,
373                 build_by_default: true,
374         )
376         install_files += [[ 'test', _bin.full_path(), _test_binname ]]
377         install_deps += [ _bin ]
379         if disassemble
380                 _disasm = custom_target(_test_binname + '.disasm',
381                         command: [ objdump, '-S', '@INPUT@' ],
382                         input: _bin,
383                         output: _test_binname + '.disasm',
384                         capture: true,
385                         build_by_default: true,
386                 )
388                 if install_debug_files
389                         install_files += [[ 'debug/test', _disasm.full_path(), _test_binname + '.disasm' ]]
390                         install_deps += [ _disasm ]
391                 endif
392         endif
393 endforeach