sbinddir = join_paths(get_option('prefix'), get_option('sbindir')) moduledir = join_paths(get_option('prefix'), get_option('moduledir')) # doesn't do much so far :( link_static = get_option('link_static') include_base_paths = [ '/usr/include', '/usr/local/include', # '/opt/local/include', ] defs = [ '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE', '-D_LARGE_FILES', '-D_GNU_SOURCE', ] libws2_32 = [] if target_machine.system() == 'windows' libws2_32 = [ compiler.find_library('ws2_32') ] defs += [ '-DNVALGRIND', ] endif compiler = meson.get_compiler('c') conf_data = configuration_data() check_headers = [ 'getopt.h', 'poll.h', 'port.h', 'pwd.h', 'stdlib.h', 'string.h', 'strings.h', 'sys/devpoll.h', 'sys/epoll.h', 'sys/event.h', 'sys/filio.h', 'sys/mman.h', 'sys/poll.h', 'sys/prctl.h', 'sys/resource.h', 'sys/select.h', 'sys/sendfile.h', 'sys/time.h', 'sys/uio.h', 'sys/un.h', 'syslog.h', ] # headers checked in special autoconf macros check_headers += [ 'inttypes.h', 'stdint.h', 'sys/wait.h', ] foreach h: check_headers conf_data.set('HAVE_' + h.to_upper().underscorify(), compiler.has_header(h)) endforeach # will be needed for auth conf_data.set('HAVE_CRYPT_H', compiler.has_header('crypt.h')) if conf_data.get('HAVE_CRYPT_H') # check if we need libcrypt for crypt_r / crypt libcrypt = compiler.find_library('crypt', required: false) # crypt_r in default libs? if compiler.has_function('crypt_r', args: defs, prefix: '#include ') libcrypt = [] conf_data.set('HAVE_CRYPT_R', 1) # crypt_r in -lcrypt ? elif libcrypt.found() and compiler.has_function('crypt_r', args: defs, dependencies: libcrypt, prefix: '#include ') libcrypt = [ libcrypt ] conf_data.set('HAVE_CRYPT_R', 1) # crypt in default libs? elif compiler.has_function('crypt', args: defs, prefix: '#include ') libcrypt = [] conf_data.set('HAVE_CRYPT', 1) # crypt in -lcrypt ? elif libcrypt.found() and compiler.has_function('crypt', args: defs, dependencies: libcrypt, prefix: '#include ') libcrypt = [ libcrypt ] conf_data.set('HAVE_CRYPT', 1) endif endif conf_data.set('HAVE_SOCKLEN_T', compiler.has_type('socklen_t', args: defs, prefix: ''' #include #include ''' )) if compiler.has_header('sys/random.h') conf_data.set('HAVE_GETENTROPY', compiler.has_function( 'getentropy', args: defs, prefix: '#include ' )) endif conf_data.set('HAVE_LINUX_RANDOM_H', compiler.has_header('linux/random.h')) if conf_data.get('HAVE_LINUX_RANDOM_H') conf_data.set('HAVE_GETRANDOM', compiler.has_function( 'getrandom', args: defs, prefix: '#include ' )) endif check_funcs = [ 'arc4random_buf', 'chroot', 'clock_gettime', 'epoll_ctl', 'explicit_bzero', 'fork', 'getloadavg', 'getrlimit', 'getuid', 'gmtime_r', 'inet_pton', 'issetugid', 'jrand48', 'kqueue', 'localtime_r', 'lstat', 'madvise', 'memset_s', 'mmap', 'pathconf', 'pipe2', 'poll', 'port_create', 'select', 'send_file', 'sendfile', 'sendfile64', 'sigaction', 'signal', 'srandom', 'writev', ] foreach f: check_funcs conf_data.set('HAVE_' + f.to_upper(), compiler.has_function(f, args: defs)) endforeach # check whether clock_gettime needs -lrt clock_lib = [] if not(conf_data.get('HAVE_CLOCK_GETTIME')) if compiler.has_function('clock_gettime', args: defs + ['-lrt'], prefix: '#include ') conf_data.set('HAVE_CLOCK_GETTIME', true) clock_lib = [ compiler.find_library('rt') ] endif endif conf_data.set('HAVE_IPV6', compiler.compiles(''' #include #include #include int main() { struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0; return 0; } ''', name: 'IPv6 support', args: defs )) conf_data.set('HAVE_WEAK_SYMBOLS', compiler.compiles(''' __attribute__((weak)) void __dummy(void *x) { } int main() { void *x; __dummy(x); } ''', name: 'weak symbols', args: defs )) conf_data.set('HAVE_STRUCT_TM_TM_GMTOFF', compiler.compiles(''' #include int main(void) { struct tm t; t.tm_gmtoff = 0; return 0; } ''', name: 'struct tm gmt offset', args: defs )) conf_data.set('LIGHTTPD_VERSION_ID', 10400) conf_data.set_quoted('PACKAGE_NAME', meson.project_name()) conf_data.set_quoted('PACKAGE_VERSION', meson.project_version()) conf_data.set_quoted('LIBRARY_DIR', moduledir) conf_data.set('LIGHTTPD_STATIC', get_option('build_static')) libdl = [] if not(get_option('build_static')) if target_machine.system() != 'windows' libdl = [ compiler.find_library('dl') ] if not(compiler.has_function('dlopen', args: defs, dependencies: libdl, prefix: '#include ')) error('Couldn\'t find dlfcn.h or dlopen in lib dl') endif endif endif libbz2 = [] if get_option('with_bzip') libbz2 = [ compiler.find_library('bz2') ] if compiler.has_function('BZ2_bzCompress', args: defs, dependencies: libbz2, prefix: '#include ') conf_data.set('WITH_BZIP', true) else error('Couldn\'t find bz2 header / library') endif endif if get_option('with_dbi') libdbi = dependency('dbi', required: false, static: link_static) if libdbi.found() libdbi = [ libdbi ] else libdbi = [ compiler.find_library('dbi') ] if not(compiler.has_function('dbi_conn_connect', args: defs, dependencies: libdbi, prefix: '#include ')) error('Couldn\'t find dbi/dbi.h or dbi_conn_connect in lib dbi') endif endif conf_data.set('WITH_DBI', true) endif libfam = [] if get_option('with_fam') libfam = [ compiler.find_library('fam') ] if not(compiler.has_function('FAMOpen2', args: defs, dependencies: libfam, prefix: '#include ')) error('Couldn\'t find fam.h or FAMOpen2 in lib fam') endif conf_data.set('HAVE_FAMNOEXISTS', compiler.has_function('FAMNoExists', args: defs, dependencies: libfam, prefix: '#include ')) conf_data.set('WITH_FAM', true) endif libgeoip = [] if get_option('with_geoip') libgeoip = dependency('geoip', required: false, static: link_static) if libgeoip.found() libgeoip = [ libgeoip ] else libgeoip = [ compiler.find_library('GeoIP') ] if not(compiler.has_function('GeoIP_country_name_by_addr', args: defs, dependencies: libgeoip)) error('Couldn\'t find GeoIP_country_name_by_addr in lib GeoIP') endif endif conf_data.set('WITH_GEOIP', true) endif libgdbm = [] if get_option('with_gdbm') libgdbm = [ compiler.find_library('gdbm') ] if not(compiler.has_function('gdbm_open', args: defs, dependencies: libgdbm, prefix: '#include ')) error('Couldn\'t find gdbm.h or gdbm_open in lib gdbm') endif conf_data.set('WITH_GDBM', true) endif libkrb5 = [] libgssapi_krb5 = [] if get_option('with_krb5') libkrb5 = dependency('krb5', required: false, static: link_static) if libkrb5.found() libkrb5 = [ libkrb5 ] else libkrb5 = [ compiler.find_library('krb5') ] if not(compiler.has_function('krb5_init_context', args: defs, dependencies: libkrb5)) error('Couldn\'t find krb5_init_context in lib krb5') endif endif libgssapi_krb5 = dependency('krb5-gssapi', required: false, static: link_static) if libgssapi_krb5.found() libgssapi_krb5 = [ libgssapi_krb5 ] else libgssapi_krb5 = [ compiler.find_library('gssapi_krb5') ] endif conf_data.set('WITH_KRB5', true) endif libldap = [] liblber = [] if get_option('with_ldap') libldap = [ compiler.find_library('ldap') ] if not(compiler.has_function('ldap_bind', args: defs, dependencies: libldap, prefix: ''' /* ldap_bind is part of the deprecated api */ #define LDAP_DEPRECATED 1 #include ''' )) error('Couldn\'t find ldap.h or ldap_bind in lib libldap') endif liblber = [ compiler.find_library('lber') ] if not(compiler.has_function('ber_printf', args: defs, dependencies: liblber, prefix: '#include ')) error('Couldn\'t find lber.h or ber_printf in lib liblber') endif conf_data.set('WITH_LDAP', true) endif libev = [] if get_option('with_libev') libev = dependency('ev', required: false, static: link_static) if libev.found() libev = [ libev ] elif compiler.has_header('ev.h') and compiler.has_function('ev_time', args: defs + ['-lev']) libev = [ compiler.find_library('ev') ] else error('Couldn\'t find libev header / library') endif conf_data.set('WITH_LIBEV', true) endif libunwind = [] if get_option('with_libunwind') libunwind = [ dependency('libunwind', static: link_static) ] conf_data.set('WITH_LIBUNWIND', true) endif liblua = [] if get_option('with_lua') found_lua = false foreach l: ['lua5.3', 'lua-5.3', 'lua5.2', 'lua-5.2', 'lua5.1', 'lua-5.1', 'lua'] if not(found_lua) liblua = dependency(l, required: false, static: link_static) found_lua = liblua.found() endif endforeach if not(found_lua) error('Couldn\'t find any lua library') endif liblua = [ liblua ] conf_data.set('WITH_LUA', true) endif libmemcached = [] if get_option('with_memcached') # manual search: # header: libmemcached/memcached.h # function: memcached (-lmemcached) libmemcached = [ dependency('libmemcached', static: link_static) ] conf_data.set('WITH_MEMCACHED', true) endif libmysqlclient = [] if get_option('with_mysql') # manual search: extend include path with 'mysql/' # header: mysql.h # function: mysql_real_connect (-lmysqlclient) libmysqlclient = [ dependency('mysqlclient', static: link_static) ] conf_data.set('WITH_MYSQL', true) endif libssl = [] libcrypto = [] if get_option('with_openssl') # manual search: # header: openssl/ssl.h # function: SSL_new (-lssl) # function: BIO_f_base64 (-lcrypto) libssl = [ dependency('libssl', static: link_static) ] libcrypto = [ dependency('libcrypto', static: link_static) ] conf_data.set('WITH_OPENSSL', true) endif libpcre = [] if get_option('with_pcre') # manual search: # header: pcre.h # function: pcre_exec (-lpcre) libpcre = [ dependency('libpcre', static: link_static) ] conf_data.set('WITH_PCRE', true) endif libpq = [] if get_option('with_pgsql') # manual search: # header: libpq-fe.h # function: PQsetdbLogin (-lpq) libpq = [ dependency('libpq', static: link_static) ] conf_data.set('WITH_PGSQL', true) endif #if get_option('with_valgrind') #endif libuuid = [] if get_option('with_webdav_locks') if not(get_option('with_webdav_props')) error('webdav locks requires webdav props') endif libuuid = dependency('uuid', required: false, static: link_static) if libuuid.found() libuuid = [ libuuid ] elif compiler.has_function('uuid_generate', args: defs, prefix: '#include ') # uuid_generate in libc, everything is fine, no lib needed libuuid = [] else libuuid = compiler.find_library('uuid') if not(compiler.has_function('uuid_generate', args: defs, dependencies: libuuid, prefix: '#include ' )) error('Couldn\'t find uuid/uuid.h or uuid_generate in lib c and uuid') endif endif conf_data.set('WITH_UUID', true) endif libxml2 = [] libsqlite3 = [] if get_option('with_webdav_props') libxml2 = dependency('libxml-2.0', required: false, static: link_static) if libxml2.found() libxml2 = [ libxml2 ] else libxml2_includes = [] libxml2_includes_dep = [] libxml2_found_header = compiler.has_header('libxml/tree.h') foreach i: include_base_paths if not(libxml2_found_header) message('Searching in ' + join_paths(i, 'libxml2')) i = include_directories(join_paths(i, 'libxml2')) if compiler.has_header('libxml/tree.h', include_directories: i) libxml2_found_header = true libxml2_includes = [ i ] libxml2_includes_dep = [ declare_dependency(include_directories: i) ] endif endif endforeach if not(libxml2_found_header) error('Couldn\'t find libxml/tree.h') endif libxml2 = [ compiler.find_library('xml2') ] if not(compiler.has_function('xmlParseChunk', args: defs, dependencies: libxml2, include_directories: libxml2_includes, prefix: ''' #include ''' )) error('Couldn\'t find xmlParseChunk in lib xml2') endif # has_function doesn't like "internal dependencies" libxml2 += libxml2_includes_dep endif conf_data.set('WITH_XML', true) libsqlite3 = dependency('sqlite31', required: false, static: link_static) if libsqlite3.found() libsqlite3 = [ libsqlite3 ] else libsqlite3 = [ compiler.find_library('sqlite3') ] if not(compiler.has_function('sqlite3_reset', args: defs, dependencies: libsqlite3, prefix: ''' #include ''' )) error('Couldn\'t find sqlite3.h or sqlite3_reset in lib sqlite3') endif endif conf_data.set('WITH_SQLITE3', true) endif libattr = [] if get_option('with_xattr') libattr = compiler.find_library('attr') if libattr.found() libattr = [ libattr ] if not(compiler.has_function('attr_get', args: defs, dependencies: libattr, prefix: ''' #include #include ''' )) error('Couldn\'t find attr/attributes.h or attr_get in lib attr') endif conf_data.set('HAVE_LIBATTR', true) elif compiler.has_function('extattr_get_file', args: defs, prefix: '#include ') # BSD extended attributes, no lib needed libattr = [] conf_data.set('HAVE_EXTATTR', true) endif conf_data.set('WITH_XATTR', true) endif libz = [] if get_option('with_zlib') libz = dependency('zlib', required: false, static: link_static) if libz.found() libz = [ libz ] else # windows alternative names? 'zlib', 'zdll' libz = [ compiler.find_library('z') ] if not(compiler.has_function('deflate', args: defs, dependencies: libz, prefix: '#include ')) error('Couldn\'t find z header / library') endif endif conf_data.set('WITH_ZLIB', true) endif configure_file( output : 'config.h', configuration : conf_data, ) common_src = [ 'algo_sha1.c', 'array.c', 'base64.c', 'buffer.c', 'chunk.c', 'configfile-glue.c', 'connections-glue.c', 'crc32.c', 'data_array.c', 'data_config.c', 'data_integer.c', 'data_string.c', 'etag.c', 'fdevent_freebsd_kqueue.c', 'fdevent_libev.c', 'fdevent_linux_sysepoll.c', 'fdevent_poll.c', 'fdevent_select.c', 'fdevent_solaris_devpoll.c', 'fdevent_solaris_port.c', 'fdevent.c', 'gw_backend.c', 'http_auth.c', 'http_chunk.c', 'http_vhostdb.c', 'http-header-glue.c', 'inet_ntop_cache.c', 'joblist.c', 'keyvalue.c', 'log.c', 'md5.c', 'plugin.c', 'rand.c', 'safe_memclear.c', 'splaytree.c', 'stat_cache.c', 'status_counter.c', 'stream.c', 'vector.c', ] if target_machine.system() == 'windows' common_src += [ 'xgetopt.c' ] endif main_src = [ 'configfile.c', 'connections.c', 'network_darwin_sendfile.c', 'network_freebsd_sendfile.c', 'network_linux_sendfile.c', 'network_solaris_sendfilev.c', 'network_write_mmap.c', 'network_write_no_mmap.c', 'network_write.c', 'network_writev.c', 'network.c', 'proc_open.c', 'request.c', 'response.c', 'server.c', ] lemon = executable('lemon', sources: 'lemon.c', native: true, ) # generator doesn't handle additional "input dependencies" like lempar.c # => use custom_target configparser = custom_target('configparser', input: ['configparser.y', 'lempar.c'], output: ['configparser.c', 'configparser.h'], command: [lemon, '-q', 'o=@OUTDIR@', '@INPUT0@', '@INPUT1@'], ) ssi_exprparser = custom_target('mod_ssi_exprparser', input: ['mod_ssi_exprparser.y', 'lempar.c'], output: ['mod_ssi_exprparser.c', 'mod_ssi_exprparser.h'], command: [lemon, '-q', 'o=@OUTDIR@', '@INPUT0@', '@INPUT1@'], ) common_cflags = defs + [ '-DHAVE_CONFIG_H', ] if compiler.get_id() == 'gcc' or compiler.get_id() == 'clang' common_cflags += [ '-Wall', '-g', '-Wshadow', '-W', '-pedantic', ] if get_option('build_extra_warnings') common_cflags += get_option('warn_cflags').split() endif endif common_flags = [ declare_dependency( compile_args: common_cflags, # tests also use common_flags, and need this include_directories: include_directories('.'), ) ] lighttpd_flags = [] lighttpd_angel_flags = [] test('test_buffer', executable('test_buffer', sources: ['test_buffer.c', 'buffer.c'], dependencies: common_flags + libunwind, build_by_default: false, )) test('test_base64', executable('test_base64', sources: ['test_base64.c', 'buffer.c', 'base64.c'], dependencies: common_flags + libunwind, build_by_default: false, )) test('test_configfile', executable('test_configfile', sources: [ 'test_configfile.c', 'buffer.c', 'array.c', 'data_string.c', 'keyvalue.c', 'vector.c', 'log.c', ], dependencies: common_flags + libpcre + libunwind, build_by_default: false, )) modules = [ [ 'mod_access', [ 'mod_access.c' ] ], [ 'mod_accesslog', [ 'mod_accesslog.c' ] ], [ 'mod_alias', [ 'mod_alias.c' ] ], [ 'mod_auth', [ 'mod_auth.c' ] ], [ 'mod_authn_file', [ 'mod_authn_file.c' ], libcrypt + libcrypto ], [ 'mod_compress', [ 'mod_compress.c' ], libbz2 + libz ], [ 'mod_deflate', [ 'mod_deflate.c' ], libbz2 + libz ], [ 'mod_dirlisting', [ 'mod_dirlisting.c' ], libpcre ], [ 'mod_evasive', [ 'mod_evasive.c' ] ], [ 'mod_evhost', [ 'mod_evhost.c' ] ], [ 'mod_expire', [ 'mod_expire.c' ] ], [ 'mod_extforward', [ 'mod_extforward.c' ] ], [ 'mod_fastcgi', [ 'mod_fastcgi.c' ], libws2_32 ], [ 'mod_flv_streaming', [ 'mod_flv_streaming.c' ] ], [ 'mod_indexfile', [ 'mod_indexfile.c' ] ], [ 'mod_proxy', [ 'mod_proxy.c' ], libws2_32 ], [ 'mod_redirect', [ 'mod_redirect.c' ], libpcre ], [ 'mod_rewrite', [ 'mod_rewrite.c' ], libpcre ], [ 'mod_rrdtool', [ 'mod_rrdtool.c' ] ], [ 'mod_scgi', [ 'mod_scgi.c' ], libws2_32 ], [ 'mod_secdownload', [ 'mod_secdownload.c' ], libcrypto ], [ 'mod_setenv', [ 'mod_setenv.c' ] ], [ 'mod_simple_vhost', [ 'mod_simple_vhost.c' ] ], [ 'mod_ssi', [ ssi_exprparser, 'mod_ssi_expr.c', 'mod_ssi.c' ], libws2_32 ], [ 'mod_staticfile', [ 'mod_staticfile.c' ] ], [ 'mod_status', [ 'mod_status.c' ] ], [ 'mod_uploadprogress', [ 'mod_uploadprogress.c' ] ], [ 'mod_userdir', [ 'mod_userdir.c' ] ], [ 'mod_usertrack', [ 'mod_usertrack.c' ] ], [ 'mod_vhostdb', [ 'mod_vhostdb.c' ] ], [ 'mod_webdav', [ 'mod_webdav.c' ], libsqlite3 + libuuid + libxml2 ], [ 'mod_wstunnel', [ 'mod_wstunnel.c' ], libcrypto ], ] if target_machine.system() != 'windows' modules += [ [ 'mod_cgi', [ 'mod_cgi.c' ] ], ] endif if get_option('with_pcre') and (get_option('with_memcached') or get_option('with_gdbm')) modules += [ [ 'mod_trigger_b4_dl', [ 'mod_trigger_b4_dl.c' ], libpcre + libmemcached + libgdbm ], ] endif if get_option('with_lua') modules += [ [ 'mod_cml', [ 'mod_cml.c', 'mod_cml_lua.c', 'mod_cml_funcs.c' ], liblua + libmemcached ], [ 'mod_magnet', [ 'mod_magnet.c', 'mod_magnet_cache.c' ], liblua ], ] endif if get_option('with_geoip') modules += [ [ 'mod_geoip', [ 'mod_geoip.c' ], libgeoip ], ] endif if get_option('with_mysql') modules += [ [ 'mod_authn_mysql', [ 'mod_authn_mysql.c' ], libcrypt + libmysqlclient ], [ 'mod_mysql_vhost', [ 'mod_mysql_vhost.c' ], libmysqlclient ], [ 'mod_vhostdb_mysql', [ 'mod_vhostdb_mysql.c' ], libmysqlclient ], ] endif if get_option('with_pgsql') modules += [ [ 'mod_vhostdb_pgsql', [ 'mod_vhostdb_pgsql.c' ], libpq ], ] endif if get_option('with_dbi') modules += [ [ 'mod_vhostdb_dbi', [ 'mod_vhostdb_dbi.c' ], libdbi ], ] endif if get_option('with_krb5') modules += [ [ 'mod_authn_gssapi', [ 'mod_authn_gssapi.c' ], libkrb5 + libgssapi_krb5 ], ] endif if get_option('with_ldap') modules += [ [ 'mod_authn_ldap', [ 'mod_authn_ldap.c' ], libldap + liblber ], [ 'mod_vhostdb_ldap', [ 'mod_vhostdb_ldap.c' ], libldap + liblber ], ] endif if get_option('with_openssl') modules += [ [ 'mod_openssl', [ 'mod_openssl.c' ], libssl + libcrypto ], ] endif if get_option('build_static') sh = find_program('sh') plugin_names = [] foreach mod: modules mod_name = mod.get(0) mod_sources = mod.get(1) mod_deps = mod.length() > 2 ? mod.get(2) : [] plugin_names += [ mod_name ] lighttpd_flags += mod_deps + [ declare_dependency( sources: mod_sources, ) ] endforeach # printf repeats the format string until all arguments are handled; # the plugin names should be "sane" ([a-zA-Z0-9_]+) plugin_static_h = custom_target('plugin-static.h', command: [ sh, '-c', 'printf \'PLUGIN_INIT(%s)\n\' ' + ' '.join(plugin_names) ], capture: true, output: [ 'plugin-static.h' ], ) main_src += [ plugin_static_h ] else foreach mod: modules mod_name = mod.get(0) mod_sources = mod.get(1) mod_deps = mod.length() > 2 ? mod.get(2) : [] shared_module(mod_name, sources: mod_sources, dependencies: common_flags + mod_deps, name_prefix: '', install: true, install_dir: moduledir, ) endforeach endif if target_machine.system() == 'windows' lighttpd_flags += [ declare_dependency( compile_args: [ '-DLI_DECLARE_EXPORTS', ], ) ] if compiler.get_id() == 'gcc' libmsvcr70 = [ compiler.find_library('msvcr70') ] lighttpd_flags += libmsvcr70 + [ declare_dependency( link_args: [ '-Wl,-subsystem,console', ], ) ] lighttpd_angel_flags += libmsvcr70 + [ declare_dependency( link_args: [ '-Wl,-subsystem,console', ], ) ] endif endif if compiler.get_id() == 'gcc' or target_machine.system() != 'darwin' lighttpd_flags += [ declare_dependency( link_args: [ '-Wl,-export-dynamic', ], ) ] endif executable('lighttpd-angel', sources: 'lighttpd-angel.c', dependencies: common_flags + lighttpd_angel_flags, c_args: ['-DSBIN_DIR="' + sbinddir + '"'], install: true, install_dir: sbinddir, ) executable('lighttpd', sources: common_src + main_src + [ configparser ], # libssl needed? dependencies: common_flags + lighttpd_flags + libattr + libcrypto + libdl + libev + libfam + libpcre + libunwind + libws2_32 , install: true, install_dir: sbinddir, )