Я пытаюсь создать расширение sqlite процентиля на ноутбуке M1, используя инструкции на странице:
gcc -g -fPIC -shared percentile.c -o percentile.so
Однако это приводит к следующим ошибкам из clang
:
$ gcc -g -fPIC -shared percentile.c -o percentile.so
Undefined symbols for architecture arm64:
"_sqlite3_aggregate_context", referenced from:
_percentStep in percentile-a11598.o
_percentFinal in percentile-a11598.o
"_sqlite3_create_function", referenced from:
_sqlite3_percentile_init in percentile-a11598.o
_sqlite3_percentile_init in percentile-a11598.o
_sqlite3_percentile_init in percentile-a11598.o
"_sqlite3_free", referenced from:
_percentStep in percentile-a11598.o
_percentFinal in percentile-a11598.o
"_sqlite3_realloc64", referenced from:
_percentStep in percentile-a11598.o
"_sqlite3_result_double", referenced from:
_percentFinal in percentile-a11598.o
"_sqlite3_result_error", referenced from:
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
"_sqlite3_result_error_nomem", referenced from:
_percentStep in percentile-a11598.o
"_sqlite3_user_data", referenced from:
_percentStep in percentile-a11598.o
"_sqlite3_value_double", referenced from:
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
"_sqlite3_value_numeric_type", referenced from:
_percentStep in percentile-a11598.o
_percentStep in percentile-a11598.o
"_sqlite3_value_type", referenced from:
_percentStep in percentile-a11598.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Можно ли создавать расширения sqlite с помощью clang, или мне нужен настоящий GCC, чтобы это работало?
🤔 А знаете ли вы, что...
C предоставляет множество возможностей для манипуляции памятью, что может быть как преимуществом, так и недостатком.
После долгих экспериментов у меня получилось кое-что, что работает. Нужная вам команда больше похожа на следующую, поскольку в macOS библиотеки общих объектов заканчиваются на .dylib
:
gcc -g -fPIC -dynamiclib -undefined suppress percentile.c -o percentile.dylib
хотя оно выдает предупреждение ld: warning: -undefined suppress is deprecated
, с которым может помочь кто-то умнее меня (их много).
Однако при попытке загрузить его произойдет ошибка, если вы используете предоставленную Apple команду sqlite3
в /usr/bin/sqlite3
. Вы можете узнать, какой из них вы используете, запустив:
type sqlite3
sqlite3 is /usr/bin/sqlite3
При попытке загрузить его вы получаете:
sqlite> .load percentile
Error: unknown command or invalid arguments: "load". Enter ".help" for help
Если вы затем проверите, как Apple компилирует sqlite3
с помощью:
sqlite3 :memory: 'select * from pragma_compile_options()'
Выход
ATOMIC_INTRINSICS=1
BUG_COMPATIBLE_20160819
CCCRYPT256
COMPILER=clang-15.0.0
DEFAULT_AUTOVACUUM
DEFAULT_CACHE_SIZE=2000
DEFAULT_CKPTFULLFSYNC
DEFAULT_FILE_FORMAT=4
DEFAULT_JOURNAL_SIZE_LIMIT=32768
DEFAULT_LOOKASIDE=1200,102
...
...
MAX_TRIGGER_DEPTH=1000
MAX_VARIABLE_NUMBER=500000
MAX_VDBE_OP=250000000
MAX_WORKER_THREADS=8
MUTEX_UNFAIR
OMIT_AUTORESET
OMIT_LOAD_EXTENSION <--- OOPS, ".load" not built in
STMTJRNL_SPILL=131072
SYSTEM_MALLOC
TEMP_STORE=1
THREADSAFE=2
USE_URI
Вы можете видеть, что Apple не разрешает команду .load
. Итак, вам нужно либо собрать весь sqlite3
самостоятельно (разумеется, без OMIT_LOAD_EXTENSION
), либо использовать доморощенный вариант для установки их исполняемого файла:
brew install sqlite
Затем вы можете запустить:
/opt/homebrew/Cellar/sqlite/3.46.0/bin/sqlite3 :memory: 'select * from pragma_compile_options()'
и вы увидите, что команда .load
поддерживается. Теперь вы можете сделать:
/opt/homebrew/Cellar/sqlite/3.46.0/bin/sqlite3
sqlite> .load percentile
sqlite>
Обратите внимание, что я использовал /opt/homebrew/Cellar/sqlite/3.46.0/bin/sqlite3
, тогда как вам следует использовать "$(brew --prefix)/Cellar/sqlite/3.46.0/bin/sqlite3"
более правильно, потому что это будет работать на компьютерах Intel Mac (которые используют /usr/local/Cellar
), а также Apple Silicon (которые используют /opt/homebrew/Cellar
).