Adding missing shared libraries automatically

Updated: May 06, 2022

You can use the mkifs autoso attribute to add to your IFS any shared libraries required by binaries in your IFS but missing from the buildfile.

The autoso attribute in your buildfile causes mkifs to scan the specified ELF binaries recursively for shared libraries needed by these binaries; that is, it scans the binaries, then all shared libraries needed by the binaries, all shared libraries needed by the previous ones, and so on. Any needed shared library not already in the image will be either listed or added to the IFS, according to the autoso option specified for the original binary.

Thus, you can use the autoso attribute to simply list all shared libraries that are needed by your build but not specified in the buildfile, so that you can then manually update your buildfile, or to have mkifs automatically add the needed but missing shared libraries to your IFS.

By default, mkifs will apply those global attributes that are in effect at the end of the buildfile to any shared libraries it automatically adds to the IFS. Hence, you can explicitly specify attributes at the end of your buildfile to have mkifs apply them to any library automatically added. (An attribute placed on a line by itself modifies all subsequent files; for an explanation, see the mkifs entry in the Utilities Reference.)

If mkifs is running in verbose mode (i.e., the -v option is specified), any library added automatically will be preceded by an “[A]” in the file list.

If two binaries in the buildfile need the same shared library, but one binary uses the autoso attribute's l[ist] option while the other binary uses the a[dd] option, then the a[dd] option takes precedence; that is, mkifs will add the shared object file to the IFS, but not print it in the list of missing shared libraries.

The default prefix for the location where files are added in the IFS is proc/boot. You can use the prefix attribute to have mkifs add a different prefix to the path in the IFS image where it adds a needed shared library file. For example:

[autoso=add]
foo
...

where foo is an executable will result in files being added to proc/boot as follows:

foo=C:/tmp/foo
[A] libaoi.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libaoi.so.1

But

[autoso=add]
foo
[prefix=lib]
...

will result in automatically added files being added to lib/, which mkifs will list as follows:

foo=C:/tmp/foo
[A] lib/libaoi.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libaoi.so.1

See Example 3: Add missing libraries and symbolic links; use “lib/” prefix below for an example using the prefix attribute.

Note:

When generating secondary IFSs, use only the l[ist] option, and add any required binaries manually by updating your buildfile. If you use the a[dd] option, libraries already present in the primary IFS might also get added to the secondary IFS.

The autoso attribute only looks for needed but missing shared libraries (usually, with a version number in their name). If you also need (unnumbered) symbolic links to the shared libraries, make sure that the [+autolink] attribute is set at the end of your buildfile.

Note that autoso doesn't list which binaries need a missing library; it only lists or adds the missing library, as required. If you need that other information, you must investigate for yourself.

For more details, see the mkifs autoso attribute in the Utilities Reference.

Recursive scans

The following illustrates what mkifs does when the autoso attribute is specified with different options. To simplify the illustration, we assume that we only need the qdb binary.

Specifying [autoso=list] or [autoso=add] in the buildfile will cause mkifs to scan the ELF binaries in the IFS recursively for missing shared library files. In this example, scanning the qdb binary initially reveals that this binary needs six shared libraries that aren't in the IFS:

# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/sbin/qdb | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libsqlite3.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libz.so.2]
0x0000000000000001 (NEEDED)             Shared library: [libstrm.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libpps.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libaoi.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]

Each of these files is in turn scanned for shared libraries, revealing that one of them needs shared libraries not present in the IFS:

# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libsqlite3.so.1 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libicui18n.so.58]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.3]
0x0000000000000001 (NEEDED)             Shared library: [libz.so.2]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libz.so.2 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libstrm.so.1 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/lib/libpps.so.1 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libaoi.so.1 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/lib/libc.so.4 | grep NEEDED

These additional binaries are scanned to reveal that yet more shared libraries are needed but missing:

# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicui18n.so.58 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libicuuc.so.58]
0x0000000000000001 (NEEDED)             Shared library: [libicudata.so.58]
0x0000000000000001 (NEEDED)             Shared library: [libc++.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.3]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/lib/libm.so.3 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]

The process is repeated on the needed but missing shared libraries until no new needed libaries are identified:

# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicuuc.so.58 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libicudata.so.58]
0x0000000000000001 (NEEDED)             Shared library: [libc++.so.1]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.3]
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicudata.so.58 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
# readelf -d /opt/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libc++.so.1 | grep NEEDED
0x0000000000000001 (NEEDED)             Shared library: [libc.so.4]
0x0000000000000001 (NEEDED)             Shared library: [libm.so.3]

Notice that every file marked as “[NEEDED]” in this last scan was already identified in a previous scan, so we're done, and we have a list of shared libraries needed by qdb but not present in the IFS:

libsqlite3.so.1
libz.so.2
libstrm.so.1
libpps.so.1
libaoi.so.1
libc.so.4
libicui18n.so.58
libm.so.3
libicuuc.so.58
libicudata.so.58
libc++.so.1

Example 1: List missing libraries

The following shows how the autoso attribute configured to list missing shared libraries causes mkifs to behave if all the shared libraries needed by a binary are missing. The configuration in the buildfile is:

# cat tst1a.bld
[-autolink autoso=list]
qdb
# mkifs -v tst1a.bld tst1a.ifs

The default search paths are (line breaks are for legibility in the documentation, and shouldn't be used in the buildfile):

${QNX_TARGET}/${PROCESSOR}/sbin;${QNX_TARGET}/${PROCESSOR}/usr/sbin;
${QNX_TARGET}/${PROCESSOR}/boot/sys;${QNX_TARGET}/${PROCESSOR_BASE}/boot/sys;
${QNX_TARGET}/${PROCESSOR}/bin;${QNX_TARGET}/${PROCESSOR}/usr/bin;
${QNX_TARGET}/${PROCESSOR}/lib;${QNX_TARGET}/${PROCESSOR}/lib/dll;
${QNX_TARGET}/${PROCESSOR}/usr/lib

Output from mkifs is:

Offset     Size    Entry   Ramoff     Target=Host
     0       5c     ----    ----     Image-header
    5c       44     ----    ----     Image-directory
  ----     ----     ----    ----     Root-dirent
  1000    2f6cf     68e0    ----     qdb=C:/my_qnx_sdp/target/qnx7/x86_64/usr/sbin/qdb
  306d0       4     ----    ----     Image-trailer
Missing shared libraries:
libsqlite3.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libsqlite3.so.1
libz.so.2=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libz.so.2
libstrm.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libstrm.so.1
libpps.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libpps.so.1
libaoi.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libaoi.so.1
libc.so.4=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libc.so.4
libicui18n.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicui18n.so.58
libm.so.3=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libm.so.3
libicuuc.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicuuc.so.58
libicudata.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicudata.so.58
libc++.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libc++.so.1
Note: To add the missing shared libraries to your build, simply copy the output from mkifs autoso=list and paste it into your buildfile.

Example 2: Add missing libraries

The following shows how the autoso attribute configured to add missing shared libraries causes mkifs to behave if some shared libraries needed by a binary are missing. The configuration in the buildfile is:

# cat tst2b.bld
[-autolink autoso=add]
qdb
libsqlite3.so.1
libz.so.2
libstrm.so.1
libpps.so.1
# mkifs -v tst2b.bld tst2b.ifs

The default search paths are (line breaks are for legibility in the documentation, and shouldn't be used in the buildfile):

${QNX_TARGET}/${PROCESSOR}/sbin;${QNX_TARGET}/${PROCESSOR}/usr/sbin;
${QNX_TARGET}/${PROCESSOR}/boot/sys;${QNX_TARGET}/${PROCESSOR_BASE}/boot/sys;
${QNX_TARGET}/${PROCESSOR}/bin;${QNX_TARGET}/${PROCESSOR}/usr/bin;
${QNX_TARGET}/${PROCESSOR}/lib;${QNX_TARGET}/${PROCESSOR}/lib/dll;
${QNX_TARGET}/${PROCESSOR}/usr/lib

Output from mkifs is:

Offset     Size    Entry     Ramoff     Target=Host
     0       5c     ----     ----     Image-header
    5c      244     ----     ----     Image-directory
  ----     ----     ----     ----     Root-dirent
  1000    2f6cf     68e0     ----     qdb=C:/my_qnx_sdp/target/qnx7/x86_64/usr/sbin/qdb
 31000    e3e58     c620     ----     libsqlite3.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libsqlite3.so.1
115000    1b260     2000     ----     libz.so.2=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libz.so.2
131000     427a      e00     ----     libstrm.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libstrm.so.1
136000     8252     1cb0     ----     libpps.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libpps.so.1
13f000     b2d4     1f20     ---- [A] libaoi.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libaoi.so.1
14b000    b40a4    50b60     ---- [A] libc.so.4=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libc.so.4
200000   2a34af    d90f0     ---- [A] libicui18n.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicui18n.so.58
4a4000    3652d     49d0     ---- [A] libm.so.3=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libm.so.3
4db000   1c22ee    690a0     ---- [A] libicuuc.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicuuc.so.58
69e000  1901238      5c0     ---- [A] libicudata.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicudata.so.58
1fa0000   e1170    40180     ---- [A] libc++.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libc++.so.1
2081170       4     ----     ----     Image-trailer
Note: Notice that mkifs uses “[A]” to identify all shared libraries that it has automatically added.

Example 3: Add missing libraries and symbolic links; use “lib/” prefix

The following shows how the autoso attribute configured to add missing shared libraries causes mkifs to behave if some shared libraries and some symbolic links needed by a binary are missing. The configuration in the buildfile is:

# cat tst4b.bld
[autoso=add]
qdb
[prefix=lib]
libsqlite3.so.1
libz.so.2
libstrm.so.1
libpps.so.1
# mkifs -v tst4b.bld tst4b.ifs

The default search paths are (line breaks are for legibility in the documentation, and shouldn't be used in the buildfile):

${QNX_TARGET}/${PROCESSOR}/sbin;${QNX_TARGET}/${PROCESSOR}/usr/sbin;
${QNX_TARGET}/${PROCESSOR}/boot/sys;${QNX_TARGET}/${PROCESSOR_BASE}/boot/sys;
${QNX_TARGET}/${PROCESSOR}/bin;${QNX_TARGET}/${PROCESSOR}/usr/bin;
${QNX_TARGET}/${PROCESSOR}/lib;${QNX_TARGET}/${PROCESSOR}/lib/dll;
${QNX_TARGET}/${PROCESSOR}/usr/lib

Output from mkifs is:

 Offset     Size    Entry   Ramoff     Target=Host
      0       5c     ----     ----     Image-header
     5c      4e8     ----     ----     Image-directory
   ----     ----     ----     ----     Root-dirent
   1000    2f6cf     68e0     ----     qdb=C:/my_qnx_sdp/target/qnx7/x86_64/usr/sbin/qdb
  31000    e3e58     c620     ----     lib/libsqlite3.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libsqlite3.so.1
   ----     ----     ----     ----     lib/libsqlite3.so -> libsqlite3.so.1
 115000    1b260     2000     ----     lib/libz.so.2=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libz.so.2
   ----     ----     ----     ----     lib/libz.so -> libz.so.2
 131000     427a      e00     ----     lib/libstrm.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libstrm.so.1
   ----     ----     ----     ----     lib/libstrm.so -> libstrm.so.1
 136000     8252     1cb0     ----     lib/libpps.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libpps.so.1
   ----     ----     ----     ----     lib/libpps.so -> libpps.so.1
 13f000     b2d4     1f20     ---- [A] lib/libaoi.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libaoi.so.1
   ----     ----     ----     ---- [A] lib/libaoi.so -> libaoi.so.1
 14b000    b40a4    50b60     ---- [A] lib/libc.so.4=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libc.so.4
   ----     ----     ----     ---- [A] lib/libc.so -> libc.so.4
 200000   2a34af    d90f0     ---- [A] lib/libicui18n.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicui18n.so.58
   ----     ----     ----     ---- [A] lib/libicui18n.so -> libicui18n.so.58
 4a4000    3652d     49d0     ---- [A] lib/libm.so.3=C:/my_qnx_sdp/target/qnx7/x86_64/lib/libm.so.3
    ---     ----     ----     ---- [A] lib/libm.so -> libm.so.3
 4db000   1c22ee    690a0     ---- [A] lib/libicuuc.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicuuc.so.58
   ----     ----     ----     ---- [A] lib/libicuuc.so -> libicuuc.so.58
 69e000  1901238      5c0     ---- [A] lib/libicudata.so.58=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libicudata.so.58
   ----     ----     ----     ---- [A] lib/libicudata.so -> libicudata.so.58
1fa0000    e1170    40180     ---- [A] lib/libc++.so.1=C:/my_qnx_sdp/target/qnx7/x86_64/usr/lib/libc++.so.1
   ----     ----     ----     ---- [A] lib/libc++.so -> libc++.so.1
2082000        4     ----     ----     Image-trailer