Why Xcode 7 shows *.tbd instead of *.dylib?
Asked Answered
C

4

149

Xcode 7 In Target > BuildPhases > Link Binary With Libraries > tap + button

When choosing frameworks to add, you cannot find *.dylib, you'll see *.tbd instead.

What is the reason for this?

**For people who need dylib, follow from this post

  1. Choose "Add other"
  2. Once in the file selection window do "CMD"+Shift+G (Go to folder) & type /usr/lib/
  3. From /user/lib you can find the *.dylib files
Console answered 16/7, 2015 at 9:42 Comment(2)
It's all part of Apples "secret plan"...Willpower
adding *.dylib from /usr/lib/ This only works for me when running my app on the simulator, it does not work with device.Avant
A
161

I've scoured Google but the only thing I can find so far is the following quote from the Apple developer forums:

For those who are curious, the .tbd files are new "text-based stub libraries", that provide a much more compact version of the stub libraries for use in the SDK, and help to significantly reduce its download size.

Hopefully more documentation will be coming soon.

Update

As an example, here is the entire contents of libsqlite3.tbd. It is just a text file. Note that the install-name is libsqlite3.dylib.

---
archs:           [ armv7, armv7s, arm64 ]
platform:        ios
install-name:    /usr/lib/libsqlite3.dylib
current-version: 216.4
compatibility-version: 9.0
exports:         
  - archs:           [ armv7, armv7s, arm64 ]
    symbols:         [ __sqlite3_lockstate, __sqlite3_purgeEligiblePagerCacheMemory, 
                       __sqlite3_system_busy_handler, __sqlite_auto_profile, 
                       __sqlite_auto_profile_syslog, __sqlite_auto_trace, 
                       __sqlite_auto_trace_syslog, _sqlite3OsShmHasMultipleLinks, 
                       _sqlite3OsShmRenamedWhileOpen, _sqlite3OsShmWasTruncated, 
                       _sqlite3OsShmWasUnlinkedWhileOpen, _sqlite3VersionNumber, 
                       _sqlite3VersionString, _sqlite3_aggregate_context, 
                       _sqlite3_aggregate_count, _sqlite3_auto_extension, 
                       _sqlite3_backup_finish, _sqlite3_backup_init, _sqlite3_backup_pagecount, 
                       _sqlite3_backup_remaining, _sqlite3_backup_step, 
                       _sqlite3_bind_blob, _sqlite3_bind_blob64, _sqlite3_bind_double, 
                       _sqlite3_bind_int, _sqlite3_bind_int64, _sqlite3_bind_null, 
                       _sqlite3_bind_parameter_count, _sqlite3_bind_parameter_index, 
                       _sqlite3_bind_parameter_name, _sqlite3_bind_text, 
                       _sqlite3_bind_text16, _sqlite3_bind_text64, _sqlite3_bind_value, 
                       _sqlite3_bind_zeroblob, _sqlite3_blob_bytes, _sqlite3_blob_close, 
                       _sqlite3_blob_open, _sqlite3_blob_read, _sqlite3_blob_reopen, 
                       _sqlite3_blob_write, _sqlite3_busy_handler, _sqlite3_busy_timeout, 
                       _sqlite3_cancel_auto_extension, _sqlite3_changes, 
                       _sqlite3_clear_bindings, _sqlite3_close, _sqlite3_close_v2, 
                       _sqlite3_collation_needed, _sqlite3_collation_needed16, 
                       _sqlite3_column_blob, _sqlite3_column_bytes, _sqlite3_column_bytes16, 
                       _sqlite3_column_count, _sqlite3_column_decltype, 
                       _sqlite3_column_decltype16, _sqlite3_column_double, 
                       _sqlite3_column_int, _sqlite3_column_int64, _sqlite3_column_name, 
                       _sqlite3_column_name16, _sqlite3_column_text, _sqlite3_column_text16, 
                       _sqlite3_column_type, _sqlite3_column_value, _sqlite3_commit_hook, 
                       _sqlite3_compileoption_get, _sqlite3_compileoption_used, 
                       _sqlite3_complete, _sqlite3_complete16, _sqlite3_config, 
                       _sqlite3_context_db_handle, _sqlite3_create_collation, 
                       _sqlite3_create_collation16, _sqlite3_create_collation_v2, 
                       _sqlite3_create_function, _sqlite3_create_function16, 
                       _sqlite3_create_function_v2, _sqlite3_create_module, 
                       _sqlite3_create_module_v2, _sqlite3_data_count, 
                       _sqlite3_data_directory, _sqlite3_db_config, _sqlite3_db_filename, 
                       _sqlite3_db_handle, _sqlite3_db_mutex, _sqlite3_db_readonly, 
                       _sqlite3_db_release_memory, _sqlite3_db_status, 
                       _sqlite3_declare_vtab, _sqlite3_enable_shared_cache, 
                       _sqlite3_errcode, _sqlite3_errmsg, _sqlite3_errmsg16, 
                       _sqlite3_errstr, _sqlite3_exec, _sqlite3_expired, 
                       _sqlite3_extended_errcode, _sqlite3_extended_result_codes, 
                       _sqlite3_file_control, _sqlite3_finalize, _sqlite3_free, 
                       _sqlite3_free_table, _sqlite3_get_autocommit, _sqlite3_get_auxdata, 
                       _sqlite3_get_table, _sqlite3_global_recover, _sqlite3_initialize, 
                       _sqlite3_intarray_bind, _sqlite3_intarray_create, 
                       _sqlite3_interrupt, _sqlite3_last_insert_rowid, 
                       _sqlite3_libversion, _sqlite3_libversion_number, 
                       _sqlite3_limit, _sqlite3_log, _sqlite3_malloc, _sqlite3_malloc64, 
                       _sqlite3_memory_alarm, _sqlite3_memory_highwater, 
                       _sqlite3_memory_used, _sqlite3_mprintf, _sqlite3_msize, 
                       _sqlite3_mutex_alloc, _sqlite3_mutex_enter, _sqlite3_mutex_free, 
                       _sqlite3_mutex_leave, _sqlite3_mutex_try, _sqlite3_next_stmt, 
                       _sqlite3_open, _sqlite3_open16, _sqlite3_open_v2, 
                       _sqlite3_os_end, _sqlite3_os_init, _sqlite3_overload_function, 
                       _sqlite3_prepare, _sqlite3_prepare16, _sqlite3_prepare16_v2, 
                       _sqlite3_prepare_v2, _sqlite3_profile, _sqlite3_progress_handler, 
                       _sqlite3_randomness, _sqlite3_realloc, _sqlite3_realloc64, 
                       _sqlite3_release_memory, _sqlite3_reset, _sqlite3_reset_auto_extension, 
                       _sqlite3_result_blob, _sqlite3_result_blob64, _sqlite3_result_double, 
                       _sqlite3_result_error, _sqlite3_result_error16, 
                       _sqlite3_result_error_code, _sqlite3_result_error_nomem, 
                       _sqlite3_result_error_toobig, _sqlite3_result_int, 
                       _sqlite3_result_int64, _sqlite3_result_null, _sqlite3_result_text, 
                       _sqlite3_result_text16, _sqlite3_result_text16be, 
                       _sqlite3_result_text16le, _sqlite3_result_text64, 
                       _sqlite3_result_value, _sqlite3_result_zeroblob, 
                       _sqlite3_rollback_hook, _sqlite3_rtree_geometry_callback, 
                       _sqlite3_rtree_query_callback, _sqlite3_set_authorizer, 
                       _sqlite3_set_auxdata, _sqlite3_shutdown, _sqlite3_sleep, 
                       _sqlite3_snprintf, _sqlite3_soft_heap_limit, _sqlite3_soft_heap_limit64, 
                       _sqlite3_sourceid, _sqlite3_sql, _sqlite3_status, 
                       _sqlite3_status64, _sqlite3_step, _sqlite3_stmt_busy, 
                       _sqlite3_stmt_readonly, _sqlite3_stmt_status, _sqlite3_strglob, 
                       _sqlite3_stricmp, _sqlite3_strnicmp, _sqlite3_table_column_metadata, 
                       _sqlite3_temp_directory, _sqlite3_test_control, 
                       _sqlite3_thread_cleanup, _sqlite3_threadsafe, _sqlite3_total_changes, 
                       _sqlite3_trace, _sqlite3_transfer_bindings, _sqlite3_update_hook, 
                       _sqlite3_uri_boolean, _sqlite3_uri_int64, _sqlite3_uri_parameter, 
                       _sqlite3_user_data, _sqlite3_value_blob, _sqlite3_value_bytes, 
                       _sqlite3_value_bytes16, _sqlite3_value_double, _sqlite3_value_int, 
                       _sqlite3_value_int64, _sqlite3_value_numeric_type, 
                       _sqlite3_value_text, _sqlite3_value_text16, _sqlite3_value_text16be, 
                       _sqlite3_value_text16le, _sqlite3_value_type, _sqlite3_version, 
                       _sqlite3_vfs_find, _sqlite3_vfs_register, _sqlite3_vfs_unregister, 
                       _sqlite3_vmprintf, _sqlite3_vsnprintf, _sqlite3_vtab_config, 
                       _sqlite3_vtab_on_conflict, _sqlite3_wal_autocheckpoint, 
                       _sqlite3_wal_checkpoint, _sqlite3_wal_checkpoint_v2, 
                       _sqlite3_wal_hook ]
...

I found this and other .tbd files in

Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/

You can also see a .tbd file if you go to the General tab of your Xcode project and then add a library under Linked Frameworks and Libraries. The .tbd file will be copied to your project.

So it appears that the .dylib file is the actual library of binary code that your project is using and is located in the /usr/lib/ directory on the user's device. The .tbd file, on the other hand, is just a text file that is included in your project and serves as a link to the required .dylib binary. Since this text file is much smaller than the binary library, it makes the SDK's download size smaller.

At this point I am only surmising from the information given, so please correct me if I am wrong.

Adna answered 20/8, 2015 at 10:22 Comment(9)
The TBD file format is actually just a YAML file. The linker just looks for certain tags.Hot
Why does it make the app size smaller? Doesn't it just link to the real dylib anyway at compile/link time? Not saying you're wrong, just trying to understandWaterish
It reduces the size of the SDK you download with Xcode, not the size of the app you're building.Schacker
Thank, @Joky. I corrected the error in my answer. Do you know at what point the binaries get added to the app if they are not in the SDK? And where do they come from? Are they downloaded as needed depending on what .tbd files are used?Adna
The dylibs in the SDK are present on the device when the OS is installed. So they were useless in the SDK, but to allow for the linker to do its job when you link the app (dynamic libraries are not copied into the app and stay separated). So the change with tbd files is to strip the dylib keeping only the minimum amount of information that was used by the linker, and updating the linker to understand this new format.Schacker
My understand from reading this page, is that it has got nothing to do with reducing my app or framework size, its about Apple SDKs reducing its size by depending on a OS provided .dylib. Or maybe I don't know what they mean by SDK here.Cranky
under the the install-name key for example '/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib' this file does not exist on my computer. Does it need to exist there for this system to work?Delarosa
@BrianWiley, It's been a while since I've worked on this and I'm not doing much with iOS any more. Feel free to edit the answer if you find the answer.Adna
@Schacker why didn't Apple turn all their dylibs into tbds? Wouldn't that help save for every dylib?Angkor
A
23

.dylib is the compiled binary that contains the machine code. .tbd is a smaller text file, similar to a cross-platform module map.

Apron answered 28/9, 2015 at 12:21 Comment(5)
Where did you learn this? Do you have any links that I could research more about this?Adna
just look at the content of a .tdsApron
Is a .tds file the same as a .tdb file? Where would I find such a file in order to look at its contents?Adna
It's TBD, not TDS or TDB. It stands for text-based dylib definition.Flagrant
What do you mean by cross-platform? Why is a normal .modulemap less cross platform than .tbd?Cranky
B
7

Text Based dylib stubs(.tbd)

It is a kind of optimization that means you do not have to copy a .dylib file (which exists on a target) into your bundle (e.g. application). This file does not contain the binary code which has a major impact on the file size.

It is applicable only for:

  1. Dynamic libraries because they are runtime-linked
  2. File should have a relevant path on the target. As a result it is the best place for standard system libraries.

For iOS development you can find .tbd files which you can use here

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib

For example libiconv.tbd looks like

enter image description here

This file contains some meta information like:

  • .dylib location
  • symbols(class's properties, methods)
  • architecture
  • platform
Biforate answered 7/4, 2019 at 14:47 Comment(1)
it doesn't contain method declarations. Only the names of the classes and the names of free functions exported from the library.Shed
A
1

A symbol is made of a body, name. If you remove the body of your functions, you save space.

Since the operating OS already has the compiled library for its own Apple libraries, then you don't need to include the body during compilation yourself. Upon installation the OS (simulator or real device) will link it nicely to the actual dylib.

They're much like a symlink/shortcut, but to a library.

So we have dynamic libraries, and those are Mach-O files that expose code and data fragments for executables to use.

Those are distributed as part of the system. That's what our frameworks are. And a number of you also use your own frameworks.

There are also TBD files, or text-based dylib stubs. So what are those? Well, when we made the SDKs for iOS and macOS, we had all these dylibs with all these great functions like MapKit and WebKit that you may want to use. But we don't want to ship the entire copy of those with the SDK because it would be large. And the compiler and linker don't need. It's only needed to run the program. So instead we create what's called a stub dylib where we delete the bodies of all of the symbols and we just have the names.

And then once we did that, we've made a textual representation of them that are easier for us to use. Currently, they are only used for distributing the SDKs to reduce size.

So you may see them in your project, but you don't have to worry about them. And they only contain symbols.

From Behind the Scenes of the Xcode Build Process - 48:38

Angkor answered 27/2, 2023 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.