Skip to content

Commit

Permalink
build: add support for meson
Browse files Browse the repository at this point in the history
Co-authored-by: Frank Morgner <frankmorgner@gmail.com>
Co-authored-by: Jussi Pakkanen <jpakkane@gmail.com>
  • Loading branch information
3 people committed Apr 26, 2024
1 parent fe2c1c8 commit 7486ce0
Show file tree
Hide file tree
Showing 20 changed files with 1,150 additions and 8 deletions.
44 changes: 44 additions & 0 deletions etc/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
install_data(
'opensc.conf',
install_dir: get_option('sysconfdir')
)

conf_etc = configuration_data()
conf_etc.set_quoted('pkgdatadir', get_option('prefix') / get_option('datadir') / 'opensc')
conf_etc.set_quoted('DEFAULT_PCSC_PROVIDER', conf.get_unquoted('DEFAULT_PCSC_PROVIDER'))
conf_etc.set_quoted('DEFAULT_SM_MODULE', conf.get_unquoted('DEFAULT_SM_MODULE'))
conf_etc.set_quoted('DEFAULT_SM_MODULE_PATH', conf.get_unquoted('DEFAULT_SM_MODULE_PATH'))
conf_etc.set_quoted('DYN_LIB_EXT', '.' + extension_of_libraries)
conf_etc.set_quoted('LIB_PRE', prefix_of_libraries)
conf_etc.set_quoted('LIBDIR', get_option('prefix') / get_option('libdir'))

if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
conf_etc.set_quoted('DEBUG_FILE', '%TEMP%\\opensc-debug.log')
conf_etc.set_quoted('PROFILE_DIR_DEFAULT', 'obtained from windows registers')
conf_etc.set_quoted('PROFILE_DIR', '')
else
conf_etc.set_quoted('DEBUG_FILE', '/tmp/opensc-debug.log')
conf_etc.set_quoted('PROFILE_DIR_DEFAULT', get_option('prefix') / get_option('datadir') / 'opensc')
conf_etc.set_quoted('PROFILE_DIR', get_option('prefix') / get_option('datadir') / 'opensc')
endif

configure_file(
configuration: conf_etc,
input: 'opensc.conf.example.in',
output: 'opensc.conf',
install: true,
install_dir: get_option('datadir') / 'doc' / 'opensc'
)

if conf.get('ENABLE_OPENPACE')
path = get_option('datadir') / 'opensc' / 'cvc'
if cv_certificates_path.startswith(get_option('prefix'))
path = cv_certificates_path
endif
install_data(
'DESRCACC100001',
'DESCHSMCVCA00001',
install_dir: path
)
unset_variable('path')
endif
255 changes: 255 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
project('opensc', 'c',
version: '0.25.1',
license: 'LGPLv2.1+',
default_options: 'c_std=none',
meson_version: '>= 0.62'
)

modpkgconfig = import('pkgconfig')

all_languages = ['c']
if host_machine.system() == 'windows'
add_languages('cpp')
all_languages += 'cpp'
elif host_machine.system() == 'darwin'
add_languages('objc')
all_languages += 'objc'
endif

prefix_of_libraries = 'lib'
if host_machine.system() == 'cygwin'
prefix_of_libraries = 'cyg'
elif meson.get_compiler('c').get_id() == 'msvc'
prefix_of_libraries = ''
endif

extension_of_libraries = 'so'
if host_machine.system() == 'windows'
extension_of_libraries = 'dll'
elif host_machine.system() == 'darwin'
extension_of_libraries = 'dylib'
endif

#################################################
# Dependencies and configuration
#################################################
conf = configuration_data()
conf.set_quoted('VERSION', meson.project_version())
conf.set_quoted('PACKAGE_NAME', 'OpenSC')
conf.set_quoted('PACKAGE_VERSION', meson.project_version())
conf.set_quoted('OPENSC_VS_FF_COMPANY_NAME', 'OpenSC project')
conf.set_quoted('OPENSC_VS_FF_PRODUCT_NAME', 'OpenSC smartcard framework')
conf.set_quoted('VS_FF_LEGAL_COPYRIGHT', 'OpenSC Project')
conf.set_quoted('VS_FF_LEGAL_COMPANY_NAME', 'OpenSC Project')
conf.set_quoted('VS_FF_LEGAL_COMPANY_URL', 'https://github.com/OpenSC')
conf.set_quoted('VS_FF_COMMENTS', 'Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).')
conf.set_quoted('VS_FF_PRODUCT_NAME', 'OpenSC smartcard framework')
conf.set_quoted('VS_FF_PRODUCT_UPDATES', 'https://github.com/OpenSC/OpenSC/releases')
conf.set_quoted('VS_FF_PRODUCT_URL', 'https://github.com/OpenSC/OpenSC')
conf.set_quoted('SC_PKCS15_PROFILE_DIRECTORY', get_option('prefix') / get_option('datadir') / 'opensc')
conf.set_quoted('OPENSC_CONF_PATH', get_option('prefix') / get_option('sysconfdir') / 'opensc.conf')
conf.set_quoted('DEFAULT_SM_MODULE', prefix_of_libraries + 'smm-local.' + extension_of_libraries)

project_version = meson.project_version().split('.')
conf.set('OPENSC_VERSION_MAJOR', project_version[0])
conf.set('OPENSC_VERSION_MINOR', project_version[1])
conf.set('OPENSC_VERSION_FIX', project_version[2])

if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
conf.set_quoted('DEFAULT_PCSC_PROVIDER', 'winscard.dll')
conf.set_quoted('DEFAULT_SM_MODULE_PATH', '%PROGRAMFILES%\\OpenSC Project\\OpenSC\\tools')
conf.set_quoted('PKCS11_REGISTER_SKIP_FIREFOX', 'on')

elif host_machine.system() == 'darwin'
conf.set_quoted('DEFAULT_PCSC_PROVIDER', '/System/Library/Frameworks/PCSC.framework/PCSC')
conf.set_quoted('DEFAULT_SM_MODULE_PATH', get_option('prefix') / get_option('libdir'))
conf.set_quoted('PKCS11_REGISTER_SKIP_FIREFOX', 'on')

else
conf.set_quoted('DEFAULT_PCSC_PROVIDER', 'libpcsclite.so.1')
conf.set_quoted('DEFAULT_SM_MODULE_PATH', get_option('prefix') / get_option('libdir'))
conf.set_quoted('PKCS11_REGISTER_SKIP_FIREFOX', 'off')
endif

conf.set('ENABLE_MINIDRIVER', get_option('components').contains('minidriver'))
conf.set('ENABLE_SM', get_option('components').contains('sm'))

conf.set('ENABLE_PCSC', false)
conf.set('ENABLE_CRYPTOTOKENKIT', false)
conf.set('ENABLE_OPENCT', false)
conf.set('ENABLE_CTAPI', false)
conf.set('HAVE_WINSCARD_H', false)
conf.set('HAVE_PCSCLITE_H', false)

if get_option('driver') == 'pcsc'
conf.set('ENABLE_PCSC', true)
deppcsclite = dependency('libpcsclite', version: '>= 1.8.22')
conf.set('HAVE_WINSCARD_H', meson.get_compiler('c').has_header('winscard.h', dependencies: deppcsclite))
conf.set('HAVE_PCSCLITE_H', meson.get_compiler('c').has_header('pcsclite.h', dependencies: deppcsclite))

elif get_option('driver') == 'crypttokenkit'
conf.set('ENABLE_CRYPTOTOKENKIT', true)
depcryptotokenkit = dependency('appleframeworks', modules: 'CryptoTokenKit')

elif get_option('driver') == 'openct'
conf.set('ENABLE_OPENCT', true)
depopenct = dependency('openct')

elif get_option('driver') == 'ctapi'
conf.set('ENABLE_CTAPI', true)

else
error('The option "driver" has unknown value')
endif

depopenpace = dependency('libeac', version: '>= 0.9', required: get_option('openpace'))
conf.set('ENABLE_OPENPACE', depopenpace.found())
if depopenpace.found()
cv_certificates_path = depopenpace.get_variable('cvcdir')
conf.set_quoted('CVCDIR', cv_certificates_path)
x509_certificates_path = depopenpace.get_variable('x509dir')
conf.set_quoted('X509DIR', x509_certificates_path)
endif

depopenssl = dependency('openssl', version: '>= 1.1.1', required: get_option('openssl'))
conf.set('ENABLE_OPENSSL', depopenssl.found())

depreadline = dependency('readline', required: get_option('readline'))
conf.set('ENABLE_READLINE', depreadline.found())

depzlib = dependency('zlib', required: get_option('zlib'))
conf.set('ENABLE_ZLIB', depzlib.found())

depcorefoundation = dependency('appleframeworks', modules: 'CoreFoundation', required: get_option('dnie_ui'))
conf.set('ENABLE_DNIE_UI', depcorefoundation.found())

depthreads = dependency('threads', required: false)
conf.set('HAVE_PTHREAD', depthreads.found())

depgio2 = dependency('gio-2.0', required: false)
conf.set('ENABLE_GIO2', depgio2.found())

conf.set('ENABLE_NOTIFY', get_option('notify'))
conf.set('PKCS11_THREAD_LOCKING', get_option('thread_locking'))
conf.set('ENABLE_PIV_SM', get_option('piv_sm'))

depdl = dependency('dl')

conf.set_quoted('DEFAULT_PKCS11_PROVIDER', '')
conf.set_quoted('DEFAULT_ONEPIN_PKCS11_PROVIDER', '')
if get_option('components').contains('pkcs11')
depp11kit = dependency('p11-kit-1', required: false)
if depp11kit.found()
p11kit_modules_path = depp11kit.get_variable('p11_module_path')
p11kit_configs_path = depp11kit.get_variable('p11_module_configs')

conf.set_quoted('DEFAULT_PKCS11_PROVIDER', p11kit_modules_path / 'opensc-pkcs11.' + extension_of_libraries)
conf.set_quoted('DEFAULT_ONEPIN_PKCS11_PROVIDER', p11kit_modules_path / 'opensc-pkcs11.' + extension_of_libraries)
else
if get_option('default_library') != 'static'
conf.set_quoted('DEFAULT_PKCS11_PROVIDER', get_option('prefix') / get_option('libdir') / prefix_of_libraries + 'opensc-pkcs11.' + extension_of_libraries)
conf.set_quoted('DEFAULT_ONEPIN_PKCS11_PROVIDER', get_option('prefix') / get_option('libdir') / prefix_of_libraries + 'opensc-pkcs11.' + extension_of_libraries)
endif
endif
endif

conf.set('HAVE_INTTYPES_H', meson.get_compiler('c').has_header('inttypes.h'))
conf.set('HAVE_STRING_H', meson.get_compiler('c').has_header('string.h'))
conf.set('HAVE_STRINGS_H', meson.get_compiler('c').has_header('strings.h'))
conf.set('HAVE_SYS_TIME_H', meson.get_compiler('c').has_header('sys' / 'time.h'))
conf.set('HAVE_SYS_MMAN_H', meson.get_compiler('c').has_header('sys' / 'mman.h'))
conf.set('HAVE_SYS_ENDIAN_H', meson.get_compiler('c').has_header('sys' / 'endian.h'))
conf.set('HAVE_UNISTD_H', meson.get_compiler('c').has_header('unistd.h'))
conf.set('HAVE_ENDIAN_H', meson.get_compiler('c').has_header('endian.h'))

conf.set('HAVE_GETPASS', meson.get_compiler('c').has_function('getpass'))
conf.set('HAVE_GETTIMEOFDAY', meson.get_compiler('c').has_function('gettimeofday'))
conf.set('HAVE_GETLINE', meson.get_compiler('c').has_function('getline'))
conf.set('HAVE_MEMSET_S', meson.get_compiler('c').has_function('memset_s'))
conf.set('HAVE_EXPLICIT_BZERO', meson.get_compiler('c').has_function('explicit_bzero'))
conf.set('HAVE_STRNLEN', meson.get_compiler('c').has_function('strnlen'))
conf.set('HAVE_SIGACTION', meson.get_compiler('c').has_function('sigaction'))
conf.set('HAVE_BUILTIN_OVERFLOW', meson.get_compiler('c').has_function('__builtin_uadd_overflow'))

opensc_features = ''
opensc_features += conf.get('PKCS11_THREAD_LOCKING')? ' locking' : ''
opensc_features += conf.get('ENABLE_OPENPACE')? ' openpace' : ''
opensc_features += conf.get('ENABLE_OPENSSL')? ' openssl' : ''
opensc_features += conf.get('ENABLE_READLINE')? ' readline' : ''
opensc_features += conf.get('ENABLE_ZLIB')? ' zlib' : ''
opensc_features += conf.get('ENABLE_PCSC')? ' pcsc(@0@)'.format(conf.get_unquoted('DEFAULT_PCSC_PROVIDER')) : ''
opensc_features += conf.get('ENABLE_CRYPTOTOKENKIT')? ' cryptotokenkit' : ''
opensc_features += conf.get('ENABLE_OPENCT')? ' openct' : ''
opensc_features += conf.get('ENABLE_CTAPI')? ' ctapi' : ''
conf.set_quoted('OPENSC_FEATURES', opensc_features.strip())
unset_variable('opensc_features')

proggit = find_program('git', required: false)
if proggit.found()
description = run_command(proggit, 'describe').stdout().strip()
if description == ''
description = run_command(proggit, 'describe', '--tags').stdout().strip()
endif
hash_commit_date = run_command(proggit, 'log', '-1', '--pretty=format:rev: %h, commit-time: %ci').stdout().strip()
tag_commit = run_command(proggit, 'rev-list', '--tags', '--no-walk', '--max-count=1').stdout().strip()
revision = run_command(proggit, 'rev-list', tag_commit + '..HEAD', '--count').stdout().strip()

conf.set_quoted('OPENSC_SCM_REVISION', 'OpenSC-@0@, @1@'.format(description, hash_commit_date))
conf.set_quoted('OPENSC_VERSION_REVISION', revision)

unset_variable('description')
unset_variable('hash_commit_date')
unset_variable('tag_commit')
unset_variable('revision')
else
conf.set_quoted('OPENSC_SCM_REVISION', '<revision is unavailable>')
conf.set_quoted('OPENSC_VERSION_REVISION', '0')
endif

configure_file(
output: 'config.h',
configuration: conf
)
add_project_arguments('-DHAVE_CONFIG_H', language: all_languages)

#################################################
# Build targets
#################################################
core_inc = include_directories('.', 'src')

subdir('src' / 'common')
subdir('src' / 'scconf')
subdir('src' / 'ui')
subdir('src' / 'pkcs15init')
subdir('src' / 'sm')
subdir('src' / 'libopensc')

if get_option('components').contains('pkcs11')
subdir('src' / 'pkcs11')
endif

if get_option('components').contains('tools')
subdir('src' / 'tools')
endif

if get_option('components').contains('minidriver')
subdir('src' / 'minidriver')
endif

if get_option('components').contains('sm')
subdir('src' / 'smm')
endif

subdir('etc')

if get_option('tests')
subdir('src' / 'tests')
#subdir('tests')
endif

#subdir('doc' / 'files')

#################################################
# Summary
#################################################

20 changes: 20 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
option('components', type: 'array', choices: ['pkcs11', 'tools', 'minidriver', 'sm'], value: ['pkcs11', 'tools'])

option('driver', type: 'combo', choices: ['pcsc', 'cryptotokenkit', 'openct', 'ctapi'], value: 'pcsc', description: 'A card reader API that OpenSC will use')

option('openpace', type: 'feature', value: 'auto', description: 'Use OpenPACE')
option('openssl', type: 'feature', value: 'auto', description: 'Use OpenSSL')
option('readline', type: 'feature', value: 'auto', description: 'Use readline')
option('zlib', type: 'feature', value: 'auto', description: 'Use zlib')
option('dnie_ui', type: 'feature', value: 'auto', description: 'Enable to request DNIe user pin with an external program')

option('notify', type: 'boolean', value: true, description: 'Notification support')
option('thread_locking', type: 'boolean', value: true, description: 'Serialize threads in PKCS#11 API')
option('piv_sm', type: 'boolean', value: true, description: 'Enable secure messages in PIV card driver')
option('autostart', type: 'boolean', value: false, description: 'Launch "pkcs11-register" on user login')

option('doc', type: 'boolean', value: true, description: 'Install documentation')
option('man', type: 'boolean', value: true, description: 'Install manual pages')

option('tests', type: 'boolean', value: false, description: 'Build tests')
option('fuzzing', type: 'boolean', value: false, description: 'Build fuzzing tests')
29 changes: 29 additions & 0 deletions src/common/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
libcompat = static_library('compat',
include_directories: core_inc,
sources: files(
'compat_dummy.c',
'compat_getopt.c',
'compat_getopt_main.c',
'compat_getpass.c',
'compat___iob_func.c',
'compat_overflow.c',
'compat_report_rangecheckfailure.c',
'compat_strlcat.c',
'compat_strlcpy.c',
'compat_strnlen.c',
'simclist.c'
)
)

libscdl = static_library('scdl',
include_directories: core_inc,
sources: files('libscdl.c'),
dependencies: depdl
)

libpkcs11_common = static_library('pkcs11',
include_directories: core_inc,
sources: files('libpkcs11.c'),
link_with: libscdl
)

2 changes: 1 addition & 1 deletion src/libopensc/apdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
return r;
}

#if ENABLE_SM
#ifdef ENABLE_SM
if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
&& (apdu->flags & SC_APDU_FLAGS_CHAINING) != 0
&& (apdu->flags & SC_APDU_FLAGS_SM_CHAINING) != 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/libopensc/card-iasecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ iasecc_erase_binary(struct sc_card *card, unsigned int offs, size_t count, unsig
}


#if ENABLE_SM
#ifdef ENABLE_SM
static int
_iasecc_sm_read_binary(struct sc_card *card, unsigned int offs,
unsigned char *buff, size_t count)
Expand Down
2 changes: 1 addition & 1 deletion src/libopensc/iso7816.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,7 +1398,7 @@ static int iso7816_get_data(struct sc_card *card, unsigned int tag, u8 *buf, si
static int
iso7816_init(struct sc_card *card)
{
#if ENABLE_SM
#ifdef ENABLE_SM
memset(&card->sm_ctx, 0, sizeof card->sm_ctx);
#endif
return SC_SUCCESS;
Expand Down

0 comments on commit 7486ce0

Please sign in to comment.