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
- The environment variable LD_LIBRARY_PATH specifies the path
- The runtime library path specified at compile time of GCC -rpath
- Ldconfig Indicates the path specified by the configuration file ld.so.conf
- 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.so 在 libIn the directory, nowlibshared.soCopied to the/libDirectory. Now, there’s a little bit of a caveat here, you do it after you copy itldconfig
Command, regenerate the cache, or the program still can not find the corresponding. So file command is as follows
sudo mv lib/libshared.so /lib
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
- Put the required.so files in/libor/usr/libPress, and then execute
ldconfig
The command - Specify rpath to determine the directory to load so