Setting Dynamic Library Path Parameters in Makefile

Table of Contents

  • 1. Makefile Dynamic Library Related

    • 1.1 Libs Variable

    • 1.2 LDFLAGS Variable

    • 1.3 Differences Between the Two

  • 2. Configuration Methods

    • 2.1 Specifying Library Path During Compilation

    • 2.2 Specifying Library Path During Runtime

  • 3. Testing

1. Makefile Dynamic Library Related

1.1 Libs Variable

In a Makefile, Libs is typically a variable used to store the list of library files and their related options that the linker needs when generating executable or library files. These library files may include static libraries (.a files) and dynamic libraries (.so files, on Unix-like systems). The specific use and definition of the Libs variable may vary by project, but generally, it contains the following information: 1. Library file paths: If the library files are not in standard library search paths (like /usr/lib or /usr/local/lib), the -L option needs to be used to specify the path to the library files. This path will be added to the linker’s search path list. 2. Library file names: The -l option is used to specify the library files that the linker needs to link. The linker will prepend the lib prefix and the appropriate file extension (like .so or .a) to this specified name and then search for this file in the library search paths. 3. Other linking options: Sometimes, the linker needs additional options to properly link the library files, such as specifying a specific linker script or handling specific library dependencies. An example of defining the Libs variable in a Makefile is as follows: Library file names: The -l option is used to specify the library files that the linker needs to link. The linker will prepend the lib prefix and the appropriate file extension (like .so or .a) to this specified name and then search for this file in the library search paths. Other linking options: Sometimes, the linker needs additional options to properly link the library files, such as specifying a specific linker script or handling specific library dependencies.

# Define library paths and names
Libs = -L/path/to/libs -lmylibrary -anotherlibrary

# ... other Makefile content ...

# Link target files and library files to generate executable file
myexecutable: myobjectfile.o
    $(CC) $(LDFLAGS) myobjectfile.o $(Libs) -o myexecutable

In this example, the Libs variable contains -L/path/to/libs (specifying the library file path) and -lmylibrary -anotherlibrary (specifying the library file names). When linking the target file myobjectfile.o to generate the executable file myexecutable, these options will be passed to the linker. It is important to note that the name of the Libs variable is not a standard part of the Makefile; its naming and usage completely depend on the conventions of the project or developer. Some projects may use different variable names (like LDLIBS) to store linker options. Therefore, when reviewing or writing a Makefile, it is best to first understand the conventions and naming habits of the project.

1.2 LDFLAGS Variable

In a Makefile, the LDFLAGS variable can also be used, which contains -L/path/to/lib and -lmylib, with the former specifying the library path and the latter specifying the library name.

# Compiler and flags
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -L/path/to/lib -lmylib

# Source and object files
SRC = main.c
OBJ = $(SRC:.c=.o)

# Executable name
EXEC = myprogram

# Default target
all: $(EXEC)

# Rule to make the executable
$(EXEC): $(OBJ)
	$(CC) $(OBJ) -o $(EXEC) $(LDFLAGS)

# Rule to make the object file
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# Clean up
clean:
	rm -f $(OBJ) $(EXEC)

1.3 Differences Between the Two

In a Makefile, both Libs and LDFLAGS are used to control the linking process, but their functions and usage differ. The Role of Libs The Libs variable is typically used to specify the list of library files that the linker needs to link. These library files may include static libraries (.a files) and dynamic libraries (.so files). The value of the Libs variable usually contains the -l option to specify the library file names (excluding the lib prefix and file extension). Additionally, if the library files are not in standard library search paths, the -L option needs to be used to specify the library file paths, but this path is usually not directly placed in the Libs variable; instead, it is placed in the LDFLAGS variable (though this is not mandatory and depends on project conventions).

The Role of LDFLAGS The LDFLAGS variable is used to specify linker options that affect the behavior of the linking process. LDFLAGS can include various types of options, including but not limited to:

  • -L option: Specifies the library file search path.

  • -l option: Although typically placed in the Libs variable, it can sometimes also be placed in the LDFLAGS (depending on project conventions).

  • -Wl, option: Passes subsequent options to the linker. For example, -Wl,-rpath,/path/to/lib will add /path/to/lib to the runtime library search path of the executable file.

  • Other linker-specific options: These options may vary depending on the linker and are used to control various aspects of the linking process. Differences 1. Different purposes: Libs is primarily used to specify the library files that need to be linked, while LDFLAGS is used to specify linker options that may include library file search paths, runtime library search paths, and other linker-specific behaviors. 2. Different contents: Libs typically only contains -l options (and possibly -L options, but this is not standard practice), while LDFLAGS can contain various types of linker options. 3. Different flexibility: Since LDFLAGS can include various types of options, it is more flexible and powerful than Libs. Through LDFLAGS, many aspects of the linking process can be controlled, while Libs primarily focuses on linking library files.

When writing a Makefile, it is common to place the library file names in the Libs variable, while placing the library file search paths and other linker options in the LDFLAGS variable. However, this is not absolute and depends on project conventions and linker requirements. In some cases, you may see -L options placed in the Libs variable or -l options placed in the LDFLAGS, depending on the specific implementation of the project and the behavior of the linker. Therefore, when reviewing or writing a Makefile, it is best to first understand the project conventions and linker requirements.

2. Configuration Methods

2.1 Specifying Library Path During Compilation

During compilation, the -L option should be used to specify the library search path, and the -l option should be used to specify the library name (excluding the lib prefix and file extensions .so or .a).

# Compiler and flags
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -L/path/to/lib -lmylib

# Source and object files
SRC = main.c
OBJ = $(SRC:.c=.o)

# Executable name
EXEC = myprogram

# Default target
all: $(EXEC)

# Rule to make the executable
$(EXEC): $(OBJ)
	$(CC) $(OBJ) -o $(EXEC) $(LDFLAGS)

# Rule to make the object file
%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

# Clean up
clean:
	rm -f $(OBJ) $(EXEC)

In this Makefile, the LDFLAGS variable contains -L/path/to/lib and -lmylib, with the former specifying the library path and the latter specifying the library name.

2.2 Specifying Library Path During Runtime

At runtime, the system needs to know where to find these dynamic libraries. This can be achieved by setting the LD_LIBRARY_PATH environment variable. Command line manual setting:

export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH
./myprogram

A target can also be added in the Makefile to set this environment variable and run the program:

# Run the executable with LD_LIBRARY_PATH set
run: $(EXEC)
	LD_LIBRARY_PATH=/path/to/lib:$$LD_LIBRARY_PATH ./$(EXEC)

You can compile and run the program by running make run while ensuring that LD_LIBRARY_PATH is set correctly.

3. Testing

Taking the snap7 dynamic library as an example, place the dynamic library in the /home/user/Desktop/snap7 directory. The project structure is as follows: Setting Dynamic Library Path Parameters in MakefileThe Makefile is as follows:

##
## LINUX barebone makefile for c examples : good for all platforms
##
## Simply run make or make clean
##
## Intend this makefile only as a "batch examples updater" after library modification.
##
LDFLAGS  := -L/home/user/Desktop/snap7
Libs     := -lsnap7 

CXX      := arm-linux-g++
CC       := arm-linux-gcc
#CXXFLAGS :=-O3
CFLAGS   :=

.PHONY: all clean

all: 
	$(CC) $(CFLAGS) -o client ./client.c $(LDFLAGS) $(Libs) 

clean:
	$(RM) client

Run the command make Setting Dynamic Library Path Parameters in Makefile to see that the dynamic library is correctly linked and compiled. The executable file client is generated. Setting Dynamic Library Path Parameters in Makefile Initially, there was a problem during compilation, indicating:

/usr/bin/ld: skipping incompatible......

Setting Dynamic Library Path Parameters in MakefileThis issue is essentially related to the mismatch between the library file version and the platform version during the linking of the library files. The solution is:

objdump -p libsnap7.so

Check whether the version of this library is 32-bit or 64-bit, or ARM version, etc. Setting Dynamic Library Path Parameters in MakefileSetting Dynamic Library Path Parameters in MakefileUse the arm-linux toolchain for compilation.

Reference Setting and distinguishing the PATH / LD_LIBRARY_PATH / LIBRARY_PATH environment variables in Linux

Leave a Comment