No good picture, the cover of the little sister picture

Building C/C++ projects and dynamic libraries with Cmake, portal. One problem with cmake is that you can’t change the directory of the.so file you need, and if the.so file directory changes, you can’t run the program, which you can’t.

why

Later I looked it up. In Linux, there is a sequence of.so files required to load and run a program

  1. The environment variable LD_LIBRARY_PATH specifies the path
  2. The runtime library path specified at compile time of GCC -rpath
  3. Ldconfig Indicates the path specified by the configuration file ld.so.conf
  4. System default library location /lib, /usr/lib

If you do not specify the location of so, GCC automatically treats the current so directory as the connection directory for SO. If we know why, we can solve the problem

The solution

Take a look at the current cmakelists.txt file

cmake_minimum_required(VERSION 3.13.3)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.h library.c)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

add_executable(project1 main.c)

target_link_libraries(project1 shared)
Copy the code

I have experimented with two options, one is to put the. So files in /lib or /usr/lib, which is also the practice when installing many software, when using the package manager to install software, most of the. So files are installed in these two directories. One way is to specify a directory for rpath at compile time, using relative directories, so that when copying files, you can copy.so together.

The easiest way to do this is to put the so directory in the system directory



The current directory structure is as follows, depending on the programlibshared.solibIn the directory, nowlibshared.soCopied to the/libDirectory. Now, there’s a little bit of a caveat here, you do it after you copy itldconfigCommand, regenerate the cache, or the program still can not find the corresponding. So file command is as follows

  1. sudo mv lib/libshared.so /lib
  2. sudo ldconfig

Project1 will not report an error when running at this time

Specify the rpath directory at compile time

There are two ways to set rPAHT

Method 1

set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH $ORIGIN)
Copy the code

Modify the compiled install path to have the program load the. So file at run time from the program’s relative directory, where the $ORIGIN variable is the program’s current directory

Way 2

set_target_properties(project1 PROPERTIES LINK_FLAGS "-Wl,-rpath,./")
Copy the code

Rpaht is the current directory in GCC

Modify the cmakelists. TXT file

cmake_minimum_required(VERSION 3.13.3)
project(project1 C)

set(CMAKE_C_STANDARD 99)

add_library(shared SHARED library.h library.c)

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

Way # 1
set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH $ORIGIN)

add_executable(project1 main.c)

Way # 2
#set_target_properties(project1 PROPERTIES LINK_FLAGS "-Wl,-rpath,./")
target_link_libraries(project1 shared)
Copy the code

Rebuild the MakeFile, then compile

The compiled libshared.so is still in the lib directory and moved to the same directory as the executable



The final directory is shown in figure, now no matter how to copy files, as long as the executable and dynamic library in the same directory, will run

conclusion

There are many ways to solve the problem that dynamically compiled programs cannot find dynamic libraries under Linux, and this time I used two

  1. Put the required.so files in/libor/usr/libPress, and then execute ldconfigThe command
  2. Specify rpath to determine the directory to load so