SUBMIT A FILE TYPE CONTACT US SUPPORT ABOUT US

What Is an LA File? The Libtool Text File That Libtool Reads as Shell Code

LA files are libtool archives, and libtool reads them as shell code with no warning. Jump to your question below, or work through it in order.

38 min read Updated October 2026 Checked against sources and tests

What Is an LA File? A libtool archive, and the ending is shared with a lossless audio type

Short answer

An LA file is a libtool archive, a small text file that describes one library. It names the library files, the version numbers, the folder the library installs to and the libraries it needs. A second kind of LA file stores lossless audio, and the two share only the ending.

We read 151 installed LA files, made 11 of our own and damaged one LA file in 50 ways. Six readers handled the 50 copies in different ways, and no copy got the same answer from all six. The libtool linker refused 25 copies and linked 23 with no message.

To read an LA file, go to the opening steps. To check one, go to the six steps. If an LA file causes an error, begin with the eight causes.

An LA file is a libtool archive. It is a short text file of shell style assignments that shows libtool where one library lives and what it needs. Any text editor opens it, and libtool reads it when you link a program.

Open the folder /usr/lib/x86_64-linux-gnu/ImageMagick-6.9.12/modules-Q16/coders on Ubuntu and you find pcx.la beside pcx.so. The SO file contains code. The LA file is a note of 41 lines that names that code, its version and its folder.

FileInfo lists two types for the .la ending. It files the Libtool Archive under data files, made by GNU, and says it records the destination folder and the dependency on the math library. The other type is a lossless audio file made by a program called La.

The libtool manual calls the .la ending the control file of a library, as opposed to .a for a standard static library. It says libtool installs the LA file beside the library so it can handle uninstalling, linking and dlopening later.

The manual adds a rule for building. When the output name ends in .la, libtool builds a libtool library from .lo objects and needs the -rpath option. Wikipedia on GNU Libtool says the program first came out in 1997 under the GPLv2 license.

Where our LA files come from

We read every installed LA file on one Ubuntu 24.04 machine, 151 in all. Ubuntu packages supplied 126, with 117 from ImageMagick and 9 from the aspell spell checker. The other 25 came from libraries in the Nix package store.

We also built six libraries of our own with libtool 2.4.7 in five kinds. Every library gave one LA file in the build folder and another after install, which makes 11 files. Then we damaged one installed LA file in 50 ways, one change at a time.

Six readers handled the files. They are the file command 5.45, the dash shell 0.5.12, libtool 2.4.7 as a linker, the libltdl loader 2.4.7, ImageMagick 6.9.12 and our 48 line script. For ImageMagick we used the same 50 changes on its own pcx.la.

We tested on Linux only. We used no Windows, Cygwin, MinGW or macOS machine. We linked with libtool 2.4.7 only. We list the limits in the format part.

LA file facts at a glance

Quick facts about LA files
Property Value
Meaning Libtool archive, the control file of one library. FileInfo files it under data files, made by GNU.
Other meaning Lossless audio. FileInfo lists a second type for .la, with the La program and plugins for Winamp and foobar2000.
Format Text with shell style assignments. Installed LA files have 14 fields in fixed order, and all 151 of ours have 41 lines.
Start A comment like # libfoo.la - a libtool library file. The file command names the type from it.
Made by Libtool, when a library is built and again when it is installed.
MIME type None found at IANA. Ubuntu maps *.la to application/x-shared-library-la, and file -i reports a text type.
Opens with Any text editor. Libtool reads it to link, and libltdl reads it to load a module.
Size in our set From 944 to 1,023 bytes, with a median of 956.
Our tests 151 installed files, 11 built files, 50 damaged copies and six readers, on Linux.

Wrong page? Look at the ELF file for the SO library an LA file names, the DEB file for the package that ships it or the DAT file for unknown data.

What Is Inside an LA File? Fourteen fields in a fixed order

Every installed LA file has the same 14 fields in one fixed order, below four comment lines. The fields cover names, dependencies, version, state, loading and place. The build folder copy of the same file differs in one line.

The figure shows libfoo.la, a library we built from two small C files. The colors group the fields by job. Read it from the top. Libtool checks the header first, and then it reads the fields as shell assignments.

The 14 fields of one libtool archive, libfoo.la, grouped into six parts. Names: dlname libfoo.so.2, library_names with three file names and old_library libfoo.a. Dependencies: inherited_linker_flags and weak_library_names are empty, and dependency_libs is -lm. Version: current 3, age 1 and revision 2. State: installed is yes and shouldnotlink is no. Loading: dlopen and dlpreopen are empty. Place: libdir is /opt/lademo/lib. The same file in the build tree says installed=no.
Every installed LA file has the same 14 fields in the same order. Colors group them by job, and the values are from libfoo.la.

The full file has 41 lines, because every field gets a comment above it. Your own LA files differ in values and not in shape. All 151 files we read have the same 41 lines.

libfoo.la as libtool 2.4.7 writes it
# libfoo.la - a libtool library file
# Generated by libtool (GNU libtool) 2.4.7 Debian-2.4.7-7build1
#
# Please DO NOT delete this file!
# It is necessary for linking the library.

# The name that we can dlopen(3).
dlname='libfoo.so.2'

# Names of this library.
library_names='libfoo.so.2.1.2 libfoo.so.2 libfoo.so'

# The name of the static archive.
old_library='libfoo.a'

# Linker flags that cannot go in dependency_libs.
inherited_linker_flags=''

# Libraries that this one depends upon.
dependency_libs=' -lm'

# Names of additional weak libraries provided by this library
weak_library_names=''

# Version information for libfoo.
current=3
age=1
revision=2

# Is this an already installed library?
installed=yes

# Should we warn about portability when linking against -modules?
shouldnotlink=no

# Files to dlopen/dlpreopen
dlopen=''
dlpreopen=''

# Directory that this library needs to be installed in:
libdir='/opt/lademo/lib'

Names, and why a library has three

The dlname field stores the one name that programs open with dlopen. The library_names field lists every name of the library. In our build it lists libfoo.so.2.1.2 libfoo.so.2 libfoo.so, an LA file and two links to it. The old_library field names the static archive.

A library built for modules only has all three names the same. Our plugin.la lists plugin.so three times. A static only library leaves dlname and library_names empty, as we show in the next part.

Version numbers and file names

We built libfoo with the option -version-info 3:2:1. The LA file records current=3, revision=2 and age=1. The libtool versioning page says a library implements every interface from current minus age up to current. Here that is 2 to 3.

On Linux the library file name follows from those numbers. Current minus age is 2, so our file is libfoo.so.2.1.2, which is the major number, then age, then revision. We saw this in libtool 2.4.7 only, and the manual page does not state the mapping.

Dependencies and flags

The dependency_libs field lists libraries that this one needs. Ours lists -lm. When libtool links a program against libfoo.la it adds those libraries for you, which is why libbar.la in our build lists the path of libfoo.la in the same field.

The inherited_linker_flags field stores flags that cannot go in dependency_libs. In our 151 files it lists -pthread -fopenmp in 117 files and -pthread in 3. The remaining 31 leave it empty.

State and place

The installed field says yes for a copy in the install folder and no for a copy in the build folder. The shouldnotlink field says yes for loadable modules. The libdir field names the folder the library installs to, and installed LA files must point at a folder that exists.

The build folder copy of libfoo.la differs in one line, installed=no. Our libbar.la differs in two places. Its build copy lists the path of the build copy of libfoo.la, and it has a 15th field named relink_command, which libtool removes at install.

The ending names the type and the first lines prove it. Libtool wants the words Generated by and libtool in the first four lines. In our tests, libtool refused copies that lost the line or changed it to Generated by autogen. The file command also needs the first comment line to name the type.

What Do LA Files Store? Five kinds, and the fields that separate them

LA files come in five kinds, and the same 14 fields separate them. A shared library fills the names and the folder. A module adds shouldnotlink yes. A static only library has no names, and a convenience library is never installed.

We built one library of every kind with libtool 2.4.7 and read the installed LA file. The figure shows which fields are filled. Dark cells are filled and pale cells are empty.

Five kinds of libtool archive made with libtool 2.4.7 and the fields they fill. A shared library fills dlname, library_names, old_library and libdir. A loadable module adds shouldnotlink yes. A static only library leaves dlname and library_names empty. A convenience library is never installed, so installed is no and libdir is empty. A library built with a release name puts the release in the file name.
Dark cells are filled and pale cells are empty. The five files come from one small project built with libtool 2.4.7.

How to name the kinds

Our script (see how to check an LA file) prints a kind for every file. It calls an LA file a loadable module when shouldnotlink says yes. It calls an LA file a shared library when dlname is filled, and a static library when only old_library is filled.

The script on three of our LA files
python3 la_peek.py libfoo.la
libfoo.la: shared library, installed
  dlname           libfoo.so.2
  library_names    libfoo.so.2.1.2 libfoo.so.2 libfoo.so
  old_library      libfoo.a
  dependency_libs  -lm
  libdir           /opt/lademo/lib

python3 la_peek.py plugin.la
plugin.la: loadable module, installed
  dlname           plugin.so
  library_names    plugin.so plugin.so plugin.so
  old_library      plugin.a
  dependency_libs  -
  libdir           /opt/lademo/lib/demo

python3 la_peek.py libstat.la
libstat.la: static library, installed
  dlname           -
  library_names    -
  old_library      libstat.a
  dependency_libs  -
  libdir           /opt/lademo/lib

A fourth kind never reaches an install folder. A convenience library is an archive that other libtool libraries absorb, and the manual on convenience libraries says it is not installed. Our script prints dashes for its empty fields.

A convenience library in the build folder
python3 la_peek.py libconv.la
libconv.la: static library, not installed
  dlname           -
  library_names    -
  old_library      libconv.a
  dependency_libs  -
  libdir           -

A release name changes the LA file name

Our fifth file, librel.la, was built with a release option. It names librel-1.2.3.so, and the version fields all read zero. The library is meant to be linked by one exact name, so no major number appears.

What our 151 files are

Of the 151 installed files, 126 are loadable modules and 25 are shared libraries. None is a static only or a convenience library. The ImageMagick files are image format modules, the aspell files are spell checker filters and the Nix files are libraries.

The kind is in the fields No ending separates shared libraries from modules. The shouldnotlink field does that job.
Modules dominate Of 151 installed files, 126 describe modules that programs load when they start.
Build copies are different A build folder copy says installed=no, and a convenience library never gets installed.
Versions follow a rule Current minus age gives the major number in the LA file name on Linux.

Not sure the LA file is an LA file at all? Check it with our script.

What Did We Find in 151 Installed LA Files? One shape, two package systems and one false alarm

All 151 installed LA files we read share one shape. They have 41 lines, the same 14 fields and a libdir that exists. Libtool linked against every one of 162 healthy files, and our script flagged one of them by mistake.

We found the 151 files on one machine, in two package systems. This study shows what those systems write and not what every project writes. The figure shows which traits the files share and which differ.

151 installed LA files read
162 healthy files libtool linked
128 gave the module warning
1 false alarm from our script
What 151 installed libtool archives share. 117 come from ImageMagick, 9 from aspell and 25 from the Nix store. All 151 have 41 lines, install flag yes, an empty dependency_libs, an empty old_library and a libdir that exists. 126 are loadable modules, 117 have the flags -pthread -fopenmp, 136 name libtool 2.4.7 and 15 name 2.5.4.
Bars show how many of the 151 files share every trait. Nothing differs between the two package systems except a few flags and the libtool version.

The readers we used on healthy files

We used four readers on all 162 healthy files, the 151 installed ones and our 11 built ones. The file command printed libtool library file, ASCII text for every one. The dash shell read every file with the dot command and executed no added code.

Libtool linked a small test program against every file, and all 162 links worked. Our 48 line script is the program in the script section. It reads the LA file as text, and it changes nothing.

Where the files agree

Every installed file has 41 lines of ASCII text with LF line ends. All 151 say installed=yes and have an empty dependency_libs field, an empty old_library field and three names for the library. The dlopen, dlpreopen and weak_library_names fields are empty in all of them.

Every libdir exists on our machine, and every library file it names is there. File sizes range from 944 to 1,023 bytes, with a median of 956. Debian Policy explains the empty dependency_libs fields, and we cover that in the safety part.

Where the files differ

Libtool 2.4.7 wrote 136 files and libtool 2.5.4 wrote the other 15, all from Nix. The 15 newer files mark the empty dependency_libs field with a note, #pruned. The inherited_linker_flags field stores -pthread -fopenmp in 117 files, -pthread in 3 and nothing in 31.

All 126 modules read 0:0:0, because nobody links against a module. The 25 libraries have version numbers that mean something, and the highest is 43:29:1. The false alarm was our own libconv.la, copied alone without the folder that stores the archive it names.

The shape is fixed All 151 files have 41 lines and the same fields in the same order.
Linking works Libtool linked a test program against all 162 healthy files.
Modules warn Libtool printed a portability warning for 128 files with shouldnotlink set to yes.
Debian empties dependencies All 126 Ubuntu files have an empty dependency_libs field.

Read the study with care. It shows 151 files from one Ubuntu machine and one Nix store. We read no LA file from Windows, Cygwin, MinGW or macOS. We used libtool 2.4.7 for every link.

What Do Readers Do With a Damaged LA File? 50 broken copies, six readers and 19 silent links

We damaged one LA file in 50 ways and handled every copy with six readers. No copy got the same answer from all six. Libtool refused 25 copies, libltdl refused 18 and dash refused 3. Libtool linked 19 copies that our script flagged, with no message.

The base file is libfoo.la, with 935 bytes and 41 lines. We changed one thing at a time and sorted the 50 copies into six groups. They cover cuts, removed fields, the header, wrong values, encoding and bytes or syntax.

A grid of 50 damaged copies of one libtool archive and six readers. No copy got the same answer from all six readers. libtool refused 25 copies, libltdl refused 18 and dash refused 3. libtool linked 23 copies with no message. Our script flagged 46 copies, and 11 copies passed the five tools unchanged.
Rows are damaged copies of libfoo.la. Green means the same answer as the healthy file, amber means another answer with no warning, and red means a warning or a refusal.

Green means the reader gave the same answer as for the healthy file. Amber means another answer with no warning, and red means warnings or refusals. For libtool, same means the same program and the same library path. Copy numbers match the rows of the figure.

Libtool forgives missing fields

Libtool linked 13 of the 14 copies with a field removed, and it gave the same program as for the healthy file in 12 of them. In copy 11 it linked the static archive libfoo.a instead, because library_names was gone. Only copy 23, with no libdir, made it fail.

Libtool refused every cut copy, from the empty file to a cut inside a quote. It also refused copies with a changed header, a libdir that points nowhere and an installed value of no or maybe. For those two it looked for the library in a .libs folder next to the LA file.

Our script sees what linking forgives

Nineteen copies linked with no message and still have a problem. They are copies 10 to 22, 33, 36, 37, 42, 44 and 49. Linking passed them, so a person learns of the problems only by reading the LA file.

Our script flagged 46 copies. It missed four. Copy 27 lost its first line but kept the Generated by line. Copy 32 has an empty dlname, which is valid for a static library. Copy 41 has an odd byte in a comment, and copy 47 uses double quotes, which shells accept.

The readers disagree about format

Dash gave the same field values on 20 copies, other values on 27 and refused 3. Libltdl refused 18 copies and ImageMagick refused the same 18 on its own pcx.la. The two agree because ImageMagick links libltdl to load its modules.

Eight copies are refused by libtool and read by libltdl. They are 24, 25, 26, 31, 34, 35, 38 and 43. Copy 47 is the reverse. Libtool and dash accepted double quotes, and libltdl and ImageMagick refused them, so an LA file can link and still fail to load.

What the groups show

Results by group of damaged LA files
Group What we found
A. Cut short (1 to 9) Libtool, libltdl and ImageMagick refused all nine copies. The file command still named copies 3 to 9 libtool libraries, because the first line survived. Dash refused copies 4 and 9, which cut inside a quote.
B. Fields removed (10 to 23) Libtool and libltdl accepted 13 copies with a field removed. Both refused copy 23, with no libdir. Copy 11 made libtool link the static archive. Our script flagged all 14.
C. Header (24 to 27) Libtool refused copies 24 to 26, which lost the Generated by line or changed it, or lost every comment. It accepted copy 27. The file command lost its label on copies 26 and 27. Libltdl ignored the header.
D. Wrong values (28 to 37) Libtool refused six copies. Libltdl refused only the three with a bad libdir, copies 28 to 30. Copies 32, 33, 36 and 37 passed libtool and libltdl, and our script flagged all but 32.
E. Encoding (38 to 42) Windows line ends (38) stopped libtool and not libltdl. A byte order mark (39) made libtool print an error and still link. UTF-16 text (40) stopped libtool, libltdl and ImageMagick. An odd comment byte (41) and 512 NUL bytes (42) stopped no one.
F. Bytes and syntax (43 to 50) A flipped header letter (43), a NUL byte in libdir (46) and a doubled libdir (50) stopped libtool. A misspelled field name (45) made libtool print an error and link. An open quote (48) stopped dash, libtool and libltdl. Copy 49 added a command.

One copy executed a command

Copy 49 adds the line echo LA_RAN > "$LA_MARK" at the end. Dash and libtool both executed it and wrote the marker file, and nothing printed a warning. We then tested libltdl and ImageMagick with a marker file of their own, and neither executed the line.

Read the grid with care. Green cells mean only that a reader gave the same answer as for the healthy file. We linked on Linux with libtool 2.4.7, and we used ImageMagick 6.9.12 and its own pcx.la for the last column. Every test changed one thing in one file.

What Does Our Expert Say About LA Files? A note from Neeraj Singh on reading before linking

Read an LA file before you link against it. Libtool and dash executed a command that we added to one copy, and neither printed a warning. Reading it in an editor takes seconds and shows if the LA file contains anything beyond its fields.

Neeraj Singh

Expert insight

LA files look like harmless notes, but libtool reads them as shell code. In our tests, one added line executed when dash and libtool read the LA file, and nothing warned. Open an LA file in a text editor before you link against it, and take LA files only from packages you trust.

Neeraj Singh Manager, Tech Support & Operations 19+ years fixing Windows and system errors

Why a link that works proves little

A link that works shows that libtool found the library. It does not show that the LA file is the one you meant. In our tests, 19 copies with a problem linked with no message at all.

Two readers that agree on one file can both miss a stray line. Neither dash nor libtool says whether the LA file contains a command. The script from the check part lists the kind, the names and the folder. It also names every line that is not a comment or a field.

Keep the original. Copy an LA file before you edit it, and write down its SHA256 hash. The hash shows which file you received, and it shows if a transfer changed it later.

How Do You Open an LA File? A text editor shows it, and libtool reads it when you link

Open an LA file in any text editor. It is ASCII text with 41 lines in all 151 of our LA files, and no special program is needed. You never execute an LA file yourself. Libtool reads it when you link programs, and libltdl reads it when programs load modules.

The easy case is a text editor. Any editor on any system shows the 14 fields and the comments above them. The cat command prints them in a terminal. We found no program that edits LA files for you, and libtool writes new ones when you build a library.

We did not test Windows, Cygwin, MinGW or macOS. FileInfo lists only Libtool on Linux as software for the libtool type. The sections below cover editors, the command line, linking and loading.

In a text editor

  1. Open the .la file in any text editor. Use a code editor if you have one.
  2. Read the first four lines. They contain the words Generated by and the name and version of libtool.
  3. Read the fields. Every field has a comment above it that says what it stores.
  4. Close the LA file without saving, unless you mean to change it.

If you save an LA file, keep UTF-8 text without a byte order mark and keep LF line ends. In our tests, Windows line ends made libtool refuse the LA file, and a byte order mark made libtool print an error on the first line.

On the command line

The five commands below print the LA file, show its first four lines, name its type, hash it and use our script. The first four work on any Linux or macOS computer. Our 48 line script is the fifth command.

Five commands to read an LA file
cat libfoo.la
head -4 libfoo.la
file libfoo.la
sha256sum libfoo.la
python3 la_peek.py libfoo.la

The file command prints libtool library file, ASCII text for a healthy file. It reads the type from the first comment line, so copies that lost the line printed only ASCII text.

The manual section on linking says that linking against an LA file lets libtool supply the library paths and the dependencies for you. We tried it. Libtool linked a test program against libfoo.la, and the program worked with no help from us.

Link against libfoo.la and read the result
libtool --mode=link gcc -o prog main.o /opt/lademo/lib/libfoo.la
readelf -d prog | grep -E "NEEDED|RUNPATH"

The program asked for libfoo.so.2 and recorded /opt/lademo/lib as its library search path. Both values came from the dlname and libdir fields of the LA file. The LA file named the library and the folder, and libtool did the rest.

Load a module with libltdl

The libltdl page of the manual says lt_dlopenext appends the .la ending first and a native ending next. That lets one program load both libtool modules and native libraries by one name.

We wrote a short C program that calls lt_dlopen. It opened libfoo.la by its full name and found a symbol. It refused 18 of our 50 damaged copies, and the damaged copies part shows which.

LA files that store lossless audio

FileInfo lists a second type for the .la ending, a lossless audio file. It names the La program and plugins for Winamp and foobar2000 as software. We tested none of them and found no audio LA file to test.

The file command 5.45 names two header versions of that audio type. When we wrote the bytes LA03 and LA04 at the start of two test files, it printed Lossless audio version 0.3 and version 0.4. Those were files we made ourselves, and they contain no audio.

If file says libtool library file or the first lines say Generated by, you have the libtool type, and this page applies. If the LA file starts with LA and then binary bytes, it is the audio type, and you need an audio tool.

How the readers did on our 50 damaged copies

How every reader did on our 50 damaged LA files
Reader Result
file 5.45 The same label on 41 copies, another label on 4 and no libtool label on 5.
dash 0.5.12 The same field values on 20 copies, other values on 27 and a refusal on 3. It executed the added line in copy 49.
Our script Flagged 46 copies and gave the same answer for 4. It reads the layout, so it sees edits that linking forgives.
libtool 2.4.7 The same program on 22 copies, another program on 1, a printed error with a link on 2 and a refusal on 25.
libltdl 2.4.7 Loaded the same module on 32 copies and refused 18. It is the strictest about quotes.
ImageMagick 6.9.12 Gave the same answer on 32 copies of its own pcx.la and refused 18, the same copies as libltdl.

How Do You Check an LA File? Six steps, and a 48 line script

Check an LA file in six steps. Hash the LA file and read its first four lines. Test its type with the file command and read the fields. Use a script that checks the folder and the named files, and compare with a second reader. No reader proves the fields are the ones you meant.

The six steps

  1. Copy the LA file, write down its SHA256 hash and work on the copy.
  2. Read the first four lines with head -4 file.la. They must contain Generated by and the word libtool.
  3. Name the type with file file.la. You want libtool library file, ASCII text. Labels that show CRLF or UTF-8 (with BOM) point to an encoding problem.
  4. List the fields with grep -E "^[a-z_]+=" file.la. An installed file prints 14 lines.
  5. Use the script below. It reads the kind, the names and the folder. It also flags lines that are not comments or fields.
  6. Link a small test program in a scratch folder, or open the LA file in a second reader, and compare the answers.

A 48 line script that reads the LA file

The Python script below does steps 3 to 5 in under a second. It reads the LA file as text, checks the header and the quotes and tests the folder and the named files. It prints a kind and the main fields, and then a line for every problem. It changes no file.

la_peek.py
#!/usr/bin/env python3
"""la_peek.py FILE.la  reads a libtool archive and executes none of it."""
import os, re, sys
QUOTED = 'dlname library_names old_library inherited_linker_flags dependency_libs weak_library_names dlopen dlpreopen libdir'.split()
BARE = 'current age revision installed shouldnotlink'.split()

def peek(path):
    raw, bad, v = open(path, 'rb').read(), [], {}
    if not raw: return ['empty file'], v
    if raw[:3] == b'\xef\xbb\xbf': bad.append('byte order mark at the start')
    if raw[:2] in (b'\xff\xfe', b'\xfe\xff'): bad.append('UTF-16 text')
    if b'\0' in raw: bad.append('NUL byte')
    if b'\r\n' in raw: bad.append('CRLF line endings')
    text = raw.decode('latin-1')
    if not re.search(r'^# Generated by .*libtool', '\n'.join(text.split('\n')[:4]), re.M):
        bad.append('no "Generated by libtool" line in the first 4 lines')
    for f in QUOTED + BARE:
        got = re.findall(r'^%s=(.*?)\r?$' % f, text, re.M)
        if not got: bad.append('missing field ' + f); continue
        if len(got) > 1: bad.append('%s is set %d times, the last one wins' % (f, len(got)))
        val = re.sub(r"(['\"])[ \t]+#.*$", r'\1', got[-1])  # some Nix files add #pruned
        if f in QUOTED:
            if len(val) < 2 or val[0] != val[-1] or val[0] not in '\'"': bad.append(f + ' has bad quotes'); continue
            val = val[1:-1]
        v[f] = val
    for i, line in enumerate(text.split('\n'), 1):
        if line.strip() and not re.match(r'(#|[a-z_]+=)', line) or re.search(r'\$\(|`', line): bad.append('line %d is not a comment or an assignment, or it has a command' % i)
    if v.get('installed') not in (None, 'yes', 'no'): bad.append('installed is not yes or no')
    for f in ('current', 'age', 'revision'):
        if v.get(f, '') and not v[f].isdigit(): bad.append(f + ' is not a number')
    ld, here = v.get('libdir'), os.path.dirname(os.path.abspath(path))
    if v.get('installed') == 'yes':
        if not ld or not os.path.isabs(ld) or not os.path.isdir(ld): bad.append('libdir is empty, relative or missing: %r' % ld)
    dirs = [d for d in (ld, here, here + '/.libs') if d and os.path.isdir(d)]
    for n in sorted(set(v.get('library_names', '').split() + v.get('old_library', '').split())):
        if not any(os.path.exists(os.path.join(d, n)) for d in dirs): bad.append('file not found: ' + n)
    bad += ['dependency not found: ' + x for x in v.get('dependency_libs', '').split() if x.endswith('.la') and not os.path.exists(x)]
    return bad, v

if __name__ == '__main__':
    bad, v = peek(sys.argv[1])
    if v:
        kind = ('loadable module' if v.get('shouldnotlink') == 'yes' else 'shared library' if v.get('dlname')
                else 'static library' if v.get('old_library') else 'empty shell')
        print('%s: %s, %s' % (os.path.basename(sys.argv[1]), kind, 'installed' if v.get('installed') == 'yes' else 'not installed'))
        for f in ('dlname', 'library_names', 'old_library', 'dependency_libs', 'libdir'): print('  %-16s %s' % (f, v.get(f, '?').strip() or '-'))
    for b in bad: print('  PROBLEM', b)
    sys.exit(1 if bad else 0)

On healthy files it prints the kind and the fields. On damaged copies it names the problem. It flags copy 5, with half the LA file cut, for ten missing fields and four missing library files. It names the folder problem in copy 28 and the encoding in copy 38.

The script on two healthy files
python3 la_peek.py libfoo.la
libfoo.la: shared library, installed
  dlname           libfoo.so.2
  library_names    libfoo.so.2.1.2 libfoo.so.2 libfoo.so
  old_library      libfoo.a
  dependency_libs  -lm
  libdir           /opt/lademo/lib

python3 la_peek.py libbar.la
libbar.la: shared library, installed
  dlname           libbar.so.1
  library_names    libbar.so.1.0.0 libbar.so.1 libbar.so
  old_library      libbar.a
  dependency_libs  /opt/lademo/lib/libfoo.la -lm
  libdir           /opt/lademo/lib
The script on five damaged copies, shortened
python3 la_peek.py copy25.la
libfoo.la: shared library, installed
  dlname           libfoo.so.2
  library_names    libfoo.so.2.1.2 libfoo.so.2 libfoo.so
  old_library      libfoo.a
  dependency_libs  -lm
  libdir           /opt/lademo/lib
  PROBLEM no "Generated by libtool" line in the first 4 lines

python3 la_peek.py copy28.la
libfoo.la: shared library, installed
  dlname           libfoo.so.2
  library_names    libfoo.so.2.1.2 libfoo.so.2 libfoo.so
  old_library      libfoo.a
  dependency_libs  -lm
  libdir           /nonexistent/lib
  PROBLEM libdir is empty, relative or missing: '/nonexistent/lib'
  PROBLEM file not found: libfoo.a
  PROBLEM file not found: libfoo.so
  PROBLEM file not found: libfoo.so.2
  PROBLEM file not found: libfoo.so.2.1.2

python3 la_peek.py copy34.la
  libdir           /opt/lademo/lib
  PROBLEM installed is not yes or no

python3 la_peek.py copy38.la
  PROBLEM CRLF line endings

python3 la_peek.py copy49.la
  PROBLEM line 42 is not a comment or an assignment, or it has a command

What the script cannot see

The script reads structure and cannot say if the values are the ones you meant. It gave the same answer as for the healthy file on copies 27, 32, 41 and 47. Those copies lost the first line, emptied dlname, added an odd comment byte and switched to double quotes.

Flags are reasons to look closer and not verdicts. It flagged a healthy libconv.la that we copied without its archive folder. The script also looks only at the shape of lines, so commands hidden inside values are flagged only when they use $( or a backtick.

The script never executes the LA file. It does not decide whether a library is safe to link either, and it does not check that a named library file is the right one.

Want the causes of an error? Go to the causes.

Is an LA File Safe to Open? Reading is low risk, and linking executes the file

LA files are safe to read and worth a check before you link against them. Libtool and dash read an LA file as shell code, and one added line executed in our test with no warning. Debian also treats LA files as clutter that can add needless dependencies.

Reading an LA file in an editor is not the risk. The risk comes from tools that treat the LA file as code. In copy 40, libtool printed an error from its own script at the line that reads the LA file with the shell dot command. That shows how libtool reads it.

We scanned no LA file for malware, and we cannot say what packages you downloaded contain. What we can say is what an LA file can store and how our readers treated the added line.

What can ride inside an LA file

A command Copy 49 adds echo LA_RAN > "$LA_MARK" at the end. Dash and libtool both executed it, and nothing warned.
Another folder Copy 50 sets libdir twice. Libtool followed the second value and looked for the library in a folder we invented.
Build machine paths Our build folder copy of libbar.la lists the path of another LA file on the build machine.
Edited values Copies 10 to 22 linked with no message after we removed fields, so edits can pass linking.

Who executed the added line

Dash and libtool executed the added line in copy 49. Libltdl and ImageMagick loaded the same file and did not, as our marker file showed. So linking a program is the step to treat with care, and loading a module through libltdl is not.

The reason is how every reader works. Libtool reads the LA file by sourcing it into a shell script, which executes every line. Libltdl has its own parser that looks for field names. We saw libtool 2.4.7 do this, and other versions or tools can differ.

Our script flags any line that is not a comment or a field, and any line that contains $( or a backtick. That catches the added line in copy 49 and a command hidden in a value. Read the LA file with your own eyes too.

What Debian says about LA files

Debian Policy, in section 10.2, says LA files for public shared libraries normally should not be in the package. Debian does not need them to link, and they can add needless dependencies to other programs. If an LA file is required, its dependency_libs field should normally be empty.

The same section says these rules do not apply to loadable modules. Debian's lintian tag marks a non empty dependency_libs field as an error. It says a filled field blocks the Multi-Arch conversion.

Our LA files agree. All 126 Ubuntu files have an empty dependency_libs field, and all 126 are modules. The 25 Nix files also have it empty, and 15 of them add the note #pruned.

Check before you link

  1. Hash the LA file and compare the hash with the package or the source, if the source lists one.
  2. Open the LA file in a text editor. The first four lines name libtool, and every other line is a comment or a field.
  3. Search for commands with grep -vE "^(#|[a-z_]+=|$)" file.la. A healthy file prints nothing. Commands hidden in field values pass this test, so read the values too.
  4. Use our script and read its last lines, the problems it lists.
  5. Link only when the libdir and the library names look like the package you expected.

If you ship an LA file of your own, read the policy of your distribution first. Debian wants most of them gone. If you keep one, follow Debian Policy and leave dependency_libs empty. Then check the file with our script.

Use a copy. Work on copies of LA files, and write down their SHA256 hashes. The hash shows which file you received, and it shows if a transfer changed it later. Keep the original read only.

Why Does Your LA File Cause an Error? Eight causes, and what to do about every one

LA files cause errors for eight reasons. The LA file can be empty or cut, or its header can be gone. The libdir can point nowhere, or the LA file can name a missing library. A build copy can be in the wrong place. Line ends, quotes or a letter can be wrong.

The table lists what our readers did with every kind of damage and what to do about it. Messages come from libtool 2.4.7 on Linux, and other versions can word them differently.

Eight causes of LA file errors
Cause What we saw and what to do
The LA file is empty or cut An empty file (copy 1) and an LA file cut to 10 bytes (copy 2) made libtool print is not a valid libtool archive. Every cut copy from 1 to 9 was refused by libtool, libltdl and ImageMagick. Fix: Reinstall the package or build the library again, and compare the LA file size with a good copy.
The header is gone or changed Copies that lost the Generated by line, changed it to Generated by autogen or lost every comment (24 to 26) got the same message from libtool. Libltdl read all three. Fix: Restore the first four lines of a good file, including Generated by and the word libtool.
The libdir points nowhere A missing folder, a relative path or an empty value (28 to 30) made the linker fail with cannot find and the path. Copy 50 sets libdir twice, and libtool followed the second value. Fix: Set libdir to the folder that contains the library, once, and as a full path.
The LA file names a missing library Copy 31 names libgone.so, and the linker failed with cannot find /opt/lademo/lib/libgone.so. Fix: List the folder from libdir with ls and check that every name in library_names and old_library is there. Reinstall the package if it is not.
A build folder copy is in the wrong place Copies with installed set to no or maybe (34 and 35) made libtool look for the library in a .libs folder beside the LA file. Fix: Use the copy that says installed=yes. Do not move build folder copies into an install folder.
Line ends or encoding are wrong Windows line ends (38) made libtool print command not found for a carriage return and refuse the LA file. A byte order mark (39) made it print an error on line 1 and still link. UTF-16 (40) stopped libtool, libltdl and ImageMagick. Fix: Save as UTF-8 with LF line ends and no byte order mark.
The quotes are broken A quote left open (48) stopped dash, libtool and libltdl. Double quotes (47) passed dash and libtool and stopped libltdl and ImageMagick. Fix: Put single quotes around every value, as libtool writes them, and close every quote.
A name or a letter is wrong A flipped letter in the header (43) made libtool refuse the LA file. A misspelled field name (45) printed command not found and linked anyway, so the field was lost. Fix: Compare the LA file with a good LA file of the same kind, or reinstall the package.

Fix an LA file in seven steps

  1. Copy the LA file, write down its SHA256 hash and work on the copy.
  2. Read the full error message. Note the LA file name and the first words, like is not a valid libtool archive or cannot find.
  3. Read the first four lines with head -4 file.la, and name the type with file file.la.
  4. Read the LA file with the check script. Its problem lines name the point where the LA file stops making sense.
  5. List the folder from libdir and check that every library file the LA file names is there.
  6. On Debian or Ubuntu, dpkg -S file.la names the package that owns the LA file. Reinstall that package and do not edit the LA file by hand.
  7. If it still fails, get a fresh copy from the source and compare the hashes.

We did not test repairs on files from other people. A file that passes our script can still fail in a build, and an LA file that fails in one tool can work in another. For example, libtool refused eight copies that libltdl loaded without a problem.

What to send when you ask for help

If a maintainer or a forum asks about an LA file, send these lines. They show what was read and where it stopped, and they save rounds of questions.

A message that gets an answer
Subject: LA file causes an error
File: name, size in bytes and SHA256 hash
First lines: the output of head -4 file.la
Type: the output of file file.la
Script: the output of la_peek.py
Error: the full text of the message and the command that printed it
Source: the package or project the LA file came from

Not an error, but a question about similar files? Go to the versus part.

How Do You Make or Remove an LA File? What libtool writes, and what Debian says to keep

You do not write LA files by hand. Libtool makes them when it builds a library whose name ends in .la, and again when it installs the library. We found no true converter for LA files, and many distributions remove them from packages.

Making an LA file differs from opening one. Libtool writes it, and no other program we found does. We built six libraries with Automake and libtool 2.4.7 to see what libtool writes. The 11 files we read came from the build folder and the install folder.

How libtool makes an LA file

  1. Compile every source file with libtool --mode=compile. It writes a .lo object file beside the object.
  2. Link the objects with libtool --mode=link and an output name that ends in .la. The link mode section says the build needs .lo objects and the -rpath option.
  3. Install the result with libtool --mode=install. The manual says the LA file records the install folder.
The three steps that made libfoo.la
libtool --mode=compile gcc -c foo.c
libtool --mode=link gcc -o libfoo.la -rpath /opt/lademo/lib foo.lo -version-info 3:2:1
libtool --mode=install install -c libfoo.la /opt/lademo/lib/libfoo.la

We used these three steps by hand and also let Automake do the same work. Both gave an LA file in the build folder and an installed one. The install step set installed=yes and wrote our libdir.

The six LA files we built

The six libraries we built and their LA files
File What it shows
libfoo.la A shared library built with -version-info 3:2:1. It needs the math library. The build copy says installed no and the installed copy says yes.
libbar.la A shared library that needs libfoo.la. The build copy lists the build path of libfoo.la and adds a relink_command field. The installed copy lists the install path.
plugin.la A loadable module built with -module and -avoid-version. It sets shouldnotlink=yes and lists plugin.so three times.
libstat.la A static only library built with -static. It leaves dlname and library_names empty and names only libstat.a.
libconv.la A convenience library that Automake marks as not installed. It says installed no and leaves libdir and the version numbers empty.
librel.la A shared library built with -release 1.2.3. It names librel-1.2.3.so, and the version numbers all read zero.

Five of the six files are installed, and every one has a build copy as well. The convenience library is the exception, because it stays in the build folder.

Keep or remove LA files

Debian wants most LA files gone. the Debian section on libraries says a required file belongs in the development package, or in the runtime package when libltdl loads the library. It adds that an LA file that must stay should have an empty dependency_libs field.

We deleted no LA file to see what breaks, so we cannot say what a program does without one. If a program loads modules through libltdl, like ImageMagick, ask your distribution or the maintainer before you delete any of its LA files.

Convert an LA file to another format

Common conversions and what you get
To Result
Text An LA file is already text. Save it with LF line ends and no byte order mark.
SO library No conversion exists. The LA file names the library, and libtool builds the library from objects. See what an ELF file is.
DEB package Packages ship the LA file when libtool or a module needs it. See what a DEB file is.
Lossless audio The audio type has nothing to do with libtool. FileInfo names the La program and two player plugins for it. We tested none.

How Does an LA File Differ From A, SO and LO Files? One text note and three look alike types

An LA file describes a library, and A, SO and LO files contain the pieces. The A file is a static archive and the SO file is a shared library. The LO file is a text note about one object. Only the LA and LO files are text.

People mix these four types up, and their endings are one letter apart. The LA file is the note about the entire library. The LO file is the note about one object file that goes into it. Libtool writes both, and both start with a comment that names the type.

LA files next to the files they describe
Type What it is Starts with
LA A libtool archive, a text note about one library A comment that names the type
LO A libtool object, a text note about one source file A comment that names the type
A A static library, a binary archive of objects The text !<arch>
SO A shared library the system loads, in the ELF format 7F 45 4C 46

The LA file starts with # libfoo.la - a libtool library file, and the LO file starts with # foo.lo - a libtool object file.

We read the first bytes of libfoo.a and libfoo.so.2.1.2 from our build. The A file starts with the bytes 21 3C 61 72 63 68 3E 0A, the signature of an ar archive. The SO file starts with the four bytes 7F 45 4C 46, the ELF signature.

The file command read the LO file as libtool object file, ASCII text.

Similar names do not make the files interchangeable. The LA file has no code in it. It names the A and SO files and the folder they live in, and libtool or libltdl does the loading. Name a missing library and the LA file still reads fine, but the link fails, as copy 31 shows.

Our ELF file guide covers the SO format and the DEB file guide covers the package that ships the files. The CXX file guide covers one kind of source file that libtool builds.

What Is the LA File Format Made Of? The facts we could check, and where they came from

The LA file format is a short text file of 14 shell style fields in fixed order. The facts below come from FileInfo, Debian, the GNU libtool manual, Wikipedia and our checks of 151 installed files, 11 built files and 50 damaged copies. All of it is from Linux.

Facts about the LA file format
Part What we checked
Name Libtool archive. Files end in .la. FileInfo files the type under data files, made by GNU. (FileInfo)
Container Text with shell style assignments. Libtool reads it with the shell, and libltdl has its own parser. (our tests)
Header A comment that names the LA file and a Generated by line with the libtool version. Libtool wants it in the first four lines. (our tests)
Fields Fourteen in this order, dlname, library_names, old_library, inherited_linker_flags, dependency_libs, weak_library_names, current, age, revision, installed, shouldnotlink, dlopen, dlpreopen and libdir. (our LA files)
Quoting Fields except current, age, revision, installed and shouldnotlink use single quotes. Those five are bare. (our LA files)
Versions A library implements every interface from current minus age up to current. (GNU libtool manual)
Build copy Says installed=no and can add a relink_command field. (our LA files)
Convenience library An archive that is not installed. It leaves libdir empty. (GNU libtool manual, our LA files)
Loading The lt_dlopenext function appends the .la ending first and a native ending next. (GNU libtool manual)
MIME type None found at IANA. Ubuntu maps *.la to application/x-shared-library-la. (IANA, our machine)
Debian rule Policy 10.2 says LA files for public shared libraries should normally stay out of packages. (Debian Policy)
First release Libtool came out in 1997. (Wikipedia)
Our counts 151 installed files, 11 built files, 50 damaged copies and six readers.

About the values we list

Facts about libtool come from the sources named in the rows. Counts were checked against our own files. FileInfo is a directory, so we use it for the name and the program list only.

The mapping from version numbers to file names is our own observation of libtool 2.4.7 on Linux. We found no page that states it, so we do not claim it applies to other systems.

What we left out

We tested on one Ubuntu 24.04 machine. We used no Windows, Cygwin, MinGW or macOS system. We linked with libtool 2.4.7 only. The 15 files written by libtool 2.5.4 were read and never linked.

We found no distribution to compare beyond Ubuntu packages and the Nix store. We did not test Fedora, Arch, Gentoo or Alpine. Readers that fail on our damaged copies can work on yours, and the reverse is true as well.

We read no audio file of the La type, and we used no encoder or player for it. The file command was tested on two test files with the audio headers we wrote ourselves.

We did not delete LA files to see what breaks. We did not read the full libtool manual page on lt_dlopen for the exact rules about the .la ending, and we report only what our program did.

Sources checked

For the extension and its two types, see the FileInfo page on LA files. For the role of the LA file, versions, linking and convenience libraries, see the GNU libtool manual, its page on versioning and its page on the libltdl interface.

For the Debian rules, see Debian Policy chapter 10 and the lintian tag for a filled dependency_libs field. For the age of the program, see the Wikipedia article on libtool. For media types, see the IANA list.

The Ubuntu shared mime database is named as text only. We found no SysTools or Freeviewer tool for LA files, so this page links to none. Every count came from the files and scripts in our research folder.

Frequently Asked Questions About LA Files

What is an LA file?

An LA file is a libtool archive, a small text file that describes one library. It names the library files, the version numbers, the install folder and the libraries the library needs. FileInfo files it under data files, made by GNU. All 151 installed LA files we read have 41 lines of text.

How do I open an LA file?

Open it in any text editor, or print it with the cat command. Libtool reads it when you link a program, and libltdl reads it when a program loads a module. We tested only Linux, and FileInfo lists only Libtool on Linux as software for the type.

Why does my LA file cause an error?

Eight causes cover what we found. The LA file can be empty or cut, or its header can be gone. The libdir can point nowhere, or the LA file can name a missing library. A build copy can be in the wrong place. Line ends, quotes or a letter can be wrong.

Is an LA file a script?

It is text that libtool reads with the shell, so it behaves like one. In our test, dash and libtool both executed a command that we added at the end of a copy, and nothing warned. Libltdl and ImageMagick loaded the same copy and did not.

Is an LA file safe to open?

Reading it in an editor is low risk. Linking against it is the step to treat with care, because libtool executes the LA file. We scanned no LA file for malware. Check an LA file from a stranger before you link against it, and use a script that flags lines that are not fields.

What is the difference between LA, A, SO and LO files?

An LA file is a text note about an entire library. An LO file is a text note about one object. An A file is a static library that starts with the text `!<arch>`, and an SO file is a shared library that starts with the ELF signature. Only LA and LO files are text.

Can I delete LA files?

Debian Policy says LA files for public shared libraries should normally stay out of packages, so many systems remove them. We deleted none to see what breaks. Programs that load modules through libltdl can need theirs, so ask your distribution before you delete any.

What does dependency_libs do and why is it empty?

It lists libraries that the library needs, and libtool adds them when you link against the LA file. Debian Policy says it should normally be empty, and a lintian tag marks a filled field as an error. All 151 installed LA files we read have it empty.

What does installed=no mean?

The copy lives in the build folder, and the library has not been installed. Our build copies say no and our installed copies say yes. When we set a copy to no or maybe, libtool looked for the library in a .libs folder beside the LA file and failed to link.

How do I make an LA file?

Libtool makes it. Link objects with a name that ends in .la and the rpath option, then install the result. Automake does the same with its LTLIBRARIES variables. We built six libraries both ways. We found no true converter, and no program that edits an LA file for you.

Is an LA file the same as a lossless audio file?

No, but they share the ending. FileInfo lists a second type for .la, a lossless audio file made by a program called La. The file command 5.45 knows two header versions of it. The audio type has nothing to do with libtool, and we tested no audio file.

What is the MIME type of an LA file?

We found none registered at IANA. Ubuntu maps *.la to application/x-shared-library-la in its shared mime database, and the file command with the i option reports a text type. The old guess application/lib is not in the IANA list we read.

Still Stuck With an LA File? Two routes out, and where to look next

Your LA file causes an error

Read the first lines and follow the seven steps. The cause table lists what to try in order.

You want to link safely

Read what can ride inside an LA file, and then the checks before you link.

Is it the library itself? An SO file is an ELF file. Our page on ELF files covers the format, and the versus part shows how it relates to the LA file.

Is it part of a package? Our page on DEB packages covers how Debian ships libraries, and the Debian part covers what Policy says about LA files.

Do you have the source code? Libtool builds from C and C++ files. Our page on CXX files covers one kind of source file.

Is it an unknown file type? Browse the file extension resource library, or send it on the submit an LA file type page.