libiconv-darwin: init at 99

Corresponds to the version of libiconv in macOS 14.4.
This commit is contained in:
Randy Eckenrode 2024-03-30 13:51:47 -04:00
parent 60fb2a6c19
commit 3157d72860
No known key found for this signature in database
GPG Key ID: 64C1CD4EC2A600D9
4 changed files with 481 additions and 0 deletions

View File

@ -0,0 +1,303 @@
# Build settings based on the upstream Xcode project.
# See: https://github.com/apple-oss-distributions/libiconv/blob/main/libiconv.xcodeproj/project.pbxproj
# Project settings
project('libiconv', 'c', version : '@version@')
fs = import('fs')
# Dependencies
cc = meson.get_compiler('c')
# Definitions
prefix_libdir = get_option('prefix') / get_option('libdir')
prefix_datadir = get_option('prefix') / get_option('datadir')
i18nmoduledir = prefix_libdir / 'i18n'
esdbdir = prefix_datadir / 'i18n/esdb'
csmapperdir = prefix_datadir / 'i18n/csmapper'
# Libraries
libcharset = library(
'charset',
darwin_versions : '1',
install : true,
include_directories : ['libcharset'],
sources : [
'libcharset/libcharset.c'
],
soversion : '1'
)
install_headers(
'libcharset/libcharset.h',
'libcharset/localcharset.h'
)
libiconv = library(
'iconv',
build_rpath : fs.parent(libcharset.full_path()),
c_args : [
f'-D_PATH_I18NMODULE="@i18nmoduledir@"',
f'-D_PATH_ESDB="@esdbdir@"',
f'-D_PATH_CSMAPPER="@csmapperdir@"'
],
darwin_versions : '7',
install : true,
include_directories : ['citrus', 'libcharset'],
link_args : ['-Wl,-reexport_library', fs.name(libcharset.full_path())],
link_depends : [libcharset],
override_options : {'b_asneeded' : false}, # Make sure the libcharset reexport is not stripped
sources : [
'citrus/__iconv_get_list.c',
'citrus/__iconv_free_list.c',
'citrus/__iconv.c',
'citrus/bsd_iconv.c',
'citrus/citrus_bcs_strtol.c',
'citrus/citrus_bcs_strtoul.c',
'citrus/citrus_bcs.c',
'citrus/citrus_csmapper.c',
'citrus/citrus_db.c',
'citrus/citrus_db_factory.c',
'citrus/citrus_db_hash.c',
'citrus/citrus_esdb.c',
'citrus/citrus_hash.c',
'citrus/citrus_iconv.c',
'citrus/citrus_lookup_factory.c',
'citrus/citrus_lookup.c',
'citrus/citrus_mapper.c',
'citrus/citrus_memstream.c',
'citrus/citrus_mmap.c',
'citrus/citrus_module.c',
'citrus/citrus_none.c',
'citrus/citrus_pivot_factory.c',
'citrus/citrus_prop.c',
'citrus/citrus_stdenc.c',
'citrus/iconv_canonicalize.c',
'citrus/iconv_close.c',
'citrus/iconv_compat.c',
'citrus/iconv_open_into.c',
'citrus/iconv_open.c',
'citrus/iconv_set_relocation_prefix.c',
'citrus/iconvctl.c',
'citrus/iconvlist.c',
'citrus/iconv.c',
],
soversion : '2'
)
install_headers(
'citrus/iconv.h'
)
install_man(
'citrus/__iconv_get_list.3',
'citrus/iconv_canonicalize.3',
'citrus/iconv.3',
'citrus/iconvctl.3',
'citrus/iconvlist.3',
)
# Binaries
executable(
'iconv',
install : true,
include_directories : ['citrus', 'libcharset'],
link_with : [libiconv],
sources : [
'iconv/iconv.c'
]
)
install_man('iconv/iconv.1')
# Data
## csmapper
csmapper_modules = [
'APPLE',
'AST',
'BIG5',
'CNS',
'CP',
'EBCDIC',
'GB',
'GEORGIAN',
'ISO-8859',
'ISO646',
'JIS',
'KAZAKH',
'KOI',
'KS',
'MISC',
'TCVN'
]
foreach module : csmapper_modules
mps_files = run_command(
'find', 'i18n/csmapper' / module, '-regex', '.*\\.\\(mps\\|646\\)',
check : true
).stdout().strip().split('\n')
install_data(mps_files, install_dir : csmapperdir / module)
endforeach
install_data(
'i18n/csmapper/charset.pivot',
'i18n/csmapper/charset.pivot.pvdb',
'i18n/csmapper/mapper.dir',
'i18n/csmapper/mapper.dir.db',
install_dir : csmapperdir
)
## esdb
esdb_modules = [
'APPLE',
'AST',
'BIG5',
'CP',
'DEC',
'EBCDIC',
'EUC',
'GB',
'GEORGIAN',
'ISO-2022',
'ISO-8859',
'ISO646',
'KAZAKH',
'KOI',
'MISC',
'TCVN',
'UTF'
]
foreach module : esdb_modules
esdb_files = run_command(
'find', 'i18n/esdb' / module, '-name', '*.esdb',
check : true
).stdout().strip().split('\n')
install_data(esdb_files, install_dir : esdbdir / module)
endforeach
install_data(
'i18n/esdb/esdb.alias',
'i18n/esdb/esdb.alias.db',
'i18n/esdb/esdb.dir',
'i18n/esdb/esdb.dir.db',
install_dir : esdbdir
)
# Modules
libiconv_modules = [
'BIG5',
'DECHanyu',
'DECKanji',
'EUC',
'EUCTW',
'GBK2K',
'HZ',
'ISO2022',
'JOHAB',
'MSKanji',
'UES',
'UTF1632',
'UTF7',
'UTF8',
'UTF8MAC',
'VIQR',
'ZW',
'iconv_none',
'iconv_std',
'mapper_646',
'mapper_none',
'mapper_serial',
'mapper_parallel',
'mapper_std',
'mapper_zone'
]
foreach module : libiconv_modules
module_source = module.to_lower()
module_path = 'libiconv_modules' / module
if module == 'UTF8MAC'
extra_headers = 'libiconv_modules/UTF8'
else
extra_headers = [ ]
endif
# Upstream builds this module under both names.
# See: https://github.com/apple-oss-distributions/libiconv/blob/81be60a93521c931a01aab9c747dd2b078bc0679/libiconv.xcodeproj/project.pbxproj#L2549-L2556
# See also: https://cgit.freebsd.org/src/tree/lib/libiconv_modules/mapper_parallel/Makefile?id=9241ebc796c11cf133c550f188f324bd2c12d89a
if module == 'mapper_parallel'
module_source = 'mapper_serial'
module_path = 'libiconv_modules/mapper_serial'
endif
library(
module,
darwin_versions : '1',
install : true,
install_dir : i18nmoduledir,
include_directories : [module_path, 'citrus', 'libcharset'] + extra_headers,
link_with : [libiconv],
override_options : {'b_asneeded' : false}, # Upstream always links libiconv
sources : [
module_path / f'citrus_@module_source@.c'
]
)
endforeach
# Tests
if get_option('tests') == true
## Only required for running the tests
atf = dependency('atf-c')
foreach suite : ['libiconv_test', 'mbopt_test', 'nixpkgs_test']
test_src = f'tests/libiconv/@suite@.c'
test_exe = executable(
suite,
dependencies : [atf],
include_directories : ['citrus', 'libcharset'],
link_with : [libiconv],
sources : [test_src]
)
# Extract the tests to run from the test source code.
tests = run_command(
'sed', '-n', '-E', 's|.*ATF_TP_ADD_TC\\([^,]*, ([^)]*).*$|\\1|p', test_src,
check : true
).stdout().strip().split('\n')
foreach test : tests
test(test, test_exe, args : [test], suite : suite, timeout : 300)
endforeach
endforeach
# These tests depend on `os_variant_has_internal_content`, which is stubbed out.
# atf_sh = find_program('atf-sh')
# print_charset = executable(
# 'print_charset',
# include_directories : ['citrus', 'libcharset'],
# link_with : [libiconv],
# sources : 'tests/libcharset/print_charset.c'
# )
#
# test_charset = custom_target(
# 'test_charset.sh',
# command : ['cp', '@INPUT@', '@OUTPUT@'],
# depends : print_charset,
# input : 'tests/libcharset/test_charset.sh',
# output : 'test_charset.sh'
# )
#
# # Extract the tests to run from the test source code.
# tests = run_command(
# 'sed', '-n', '-E', 's|.*atf_add_test_case (.*$)|\\1|p', 'tests/libcharset/test_charset.sh',
# check : true
# ).stdout().strip().split('\n')
#
# foreach test : tests
# test(test, atf_sh, args : [test_charset, test], suite : 'libcharset', timeout : 300)
# endforeach
endif

View File

@ -0,0 +1 @@
option('tests', type : 'boolean')

View File

@ -0,0 +1,82 @@
#include <atf-c.h>
#include <iconv.h>
#include <stdint.h>
// The following tests were failing in libarchive due to libiconv issues.
// 218: test_read_format_cab_filename (4 failures)
// 415: test_read_format_zip_filename_CP932_eucJP (4 failures)
// 426: test_read_format_zip_filename_CP932_CP932 (2 failures)
ATF_TC(test_cp932_eucjp);
ATF_TC_HEAD(test_cp932_eucjp, tc)
{
atf_tc_set_md_var(tc, "descr", "regression test for CP932 to EUC-JP conversion");
}
ATF_TC_BODY(test_cp932_eucjp, tc)
{
char expected[] = "\xc9\xbd\xa4\xc0\xa4\xe8\x5c\xb4\xc1\xbb\xfa\x2e\x74\x78\x74";
size_t expected_length = sizeof(expected) - 1;
char input[] = "\x95\x5c\x82\xbe\x82\xe6\x5c\x8a\xbf\x8e\x9a\x2e\x74\x78\x74";
size_t input_length = sizeof(input) - 1;
size_t output_available = sizeof(expected) - 1 ;
char output[sizeof(expected)] = { 0 };
iconv_t cd = iconv_open("eucJP", "CP932");
ATF_REQUIRE((size_t)cd != -1);
char* input_buf = input;
char* output_buf = output;
size_t res = iconv(cd, &input_buf, &input_length, &output_buf, &output_available);
iconv_close(cd);
ATF_CHECK(res != -1);
size_t output_length = sizeof(output) - output_available - 1;
ATF_CHECK_INTEQ(expected_length, output_length);
ATF_CHECK_STREQ(expected, output);
}
ATF_TC(test_cp932_cp932);
ATF_TC_HEAD(test_cp932_cp932, tc)
{
atf_tc_set_md_var(tc, "descr", "regression test for CP932 to CP932 conversion");
}
ATF_TC_BODY(test_cp932_cp932, tc)
{
char expected[] = "\x95\x5c\x82\xbe\x82\xe6\x5c\x8a\xbf\x8e\x9a\x2e\x74\x78\x74";
size_t expected_length = sizeof(expected) - 1;
char input[] = "\x95\x5c\x82\xbe\x82\xe6\x5c\x8a\xbf\x8e\x9a\x2e\x74\x78\x74";
size_t input_length = sizeof(input) - 1;
size_t output_available = sizeof(expected) - 1 ;
char output[sizeof(expected)] = { 0 };
iconv_t cd = iconv_open("CP932", "CP932");
ATF_REQUIRE((size_t)cd != -1);
char* input_buf = input;
char* output_buf = output;
size_t res = iconv(cd, &input_buf, &input_length, &output_buf, &output_available);
iconv_close(cd);
ATF_CHECK(res != -1);
size_t output_length = sizeof(output) - output_available - 1;
ATF_CHECK_INTEQ(expected_length, output_length);
ATF_CHECK_STREQ(expected, output);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, test_cp932_eucjp);
ATF_TP_ADD_TC(tp, test_cp932_cp932);
return atf_no_error();
}

View File

@ -0,0 +1,95 @@
{
lib,
stdenv,
fetchFromGitHub,
fetchpatch,
atf,
libiconvReal,
meson,
ninja,
pkg-config,
gitUpdater,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "libiconv";
version = "99";
outputs = [
"out"
"dev"
];
src = fetchFromGitHub {
owner = "apple-oss-distributions";
repo = "libiconv";
rev = "libiconv-${finalAttrs.version}";
hash = "sha256-TGt6rsU52ztfW2rCqwnhMAExLbexI/59IoDOGY+XGu0=";
};
inherit (libiconvReal) setupHooks;
postPatch =
''
substitute ${./meson.build} meson.build --subst-var version
cp ${./meson.options} meson.options
# Work around unnecessary private API usage in libcharset
mkdir -p libcharset/os && cat <<-header > libcharset/os/variant_private.h
#pragma once
#include <stdbool.h>
static inline bool os_variant_has_internal_content(const char*) { return false; }
header
cp ${./nixpkgs_test.c} tests/libiconv/nixpkgs_test.c
'';
strictDeps = true;
nativeBuildInputs = [
meson
ninja
];
mesonBuildType = "release";
mesonFlags = [ (lib.mesonBool "tests" finalAttrs.doInstallCheck) ];
postInstall = lib.optionalString stdenv.isDarwin ''
${stdenv.cc.targetPrefix}install_name_tool "$out/lib/libiconv.2.dylib" \
-change '@rpath/libcharset.1.dylib' "$out/lib/libcharset.1.dylib"
'';
# Tests have to be run in `installCheckPhase` because libiconv expects to `dlopen`
# modules from `$out/lib/i18n`.
nativeInstallCheckInputs = [ pkg-config ];
installCheckInputs = [ atf ];
doInstallCheck = stdenv.buildPlatform.canExecute stdenv.hostPlatform;
# Cant use `mesonCheckPhase` because it runs the wrong hooks for `installCheckPhase`.
installCheckPhase = ''
runHook preInstallCheck
meson test --no-rebuild
runHook postInstallCheck
'';
passthru.updateScript = gitUpdater { rev-prefix = "libiconv-"; };
__structuredAttrs = true;
meta = {
description = "An iconv(3) implementation";
homepage = "https://opensource.apple.com/releases/";
license =
with lib.licenses;
[
bsd2
bsd3
]
++ lib.optional finalAttrs.doInstallCheck apsl10;
mainProgram = "iconv";
maintainers = with lib.maintainers; [ reckenrode ];
platforms = lib.platforms.darwin;
};
})