看起来有几个问题,我会尽力逐步回答这些问题:
为什么SDL网站建议尽可能动态链接?
将应用程序动态链接到库的一个原因是将应用程序与库(在此情况下称为共享库/.so
)解耦。您可以更新库而无需重新编译应用程序代码。例如,在完成项目并且客户端正在运行您的应用程序时,我想您不太可能希望重新编译应用程序代码,一旦您正在使用的底层库进行了错误修复。
另一方面,通过将应用程序链接静态链接
,您将应用程序与该库(以.lib
或.a
形式)绑定在一起。这意味着库中的任何更改都会导致您重新编译代码。有时候这是必要的,例如,你必须向客户提供应用程序的保证,通常需要确保库不会导致应用程序崩溃。
我有一个简短的示例代码,以更好地理解:
CMakeLists.txt:
cmake_minimum_required (VERSION 3.0)
project(linkageLibrary)
set(STATIC_LIB lib_static)
set(SHARE_LIB lib_share)
set(STATIC_OTHER_LIB lib_otherstatic)
set(SHARE_OTHER_LIB lib_othershare)
add_library(${STATIC_LIB} STATIC ${STATIC_LIB}.cpp)
add_library(${SHARE_LIB} SHARED ${SHARE_LIB}.cpp)
add_library(${STATIC_OTHER_LIB} STATIC ${STATIC_OTHER_LIB}.cpp)
add_library(${SHARE_OTHER_LIB} SHARED ${SHARE_OTHER_LIB}.cpp)
add_executable(${CMAKE_PROJECT_NAME} main.cpp)
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${${CMAKE_PROJECT_NAME}_SOURCE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} ${STATIC_LIB} ${SHARE_LIB})
file(WRITE ${CMAKE_BINARY_DIR}/exchangeShareLibrary.sh "
echo \"before exchange the static library\"
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME} &&
mv ${CMAKE_BINARY_DIR}/lib${SHARE_LIB}.so ${CMAKE_BINARY_DIR}/lib${SHARE_LIB}.so.bk &&
cp ${CMAKE_BINARY_DIR}/lib${SHARE_OTHER_LIB}.so ${CMAKE_BINARY_DIR}/lib${SHARE_LIB}.so &&
echo \"after the shared library has been changed\" &&
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}")
file(WRITE ${CMAKE_BINARY_DIR}/exchangeStaticLibrary.sh "
echo \"before exchange the static library\"
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME} &&
mv ${CMAKE_BINARY_DIR}/lib${STATIC_LIB}.a ${CMAKE_BINARY_DIR}/lib${STATIC_LIB}a.bk &&
cp ${CMAKE_BINARY_DIR}/lib${STATIC_OTHER_LIB}.a ${CMAKE_BINARY_DIR}/lib${STATIC_LIB}.a &&
echo \"after the static library has been changed\" &&
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}")
main.cpp:
#include <iostream>
#include "lib.hpp"
using namespace std;
int main() {
printStaticLib();
printShareLib();
return 0;
}
lib.hpp:
#pragma ONCE
void printStaticLib();
void printShareLib();
lib_static.cpp:
#include <iostream>
#include "lib.hpp"
using namespace std;
void printStaticLib() {
cout << "linkage of lib_static" << endl;
}
lib_share.cpp:
#include <iostream>
#include "lib.hpp"
using namespace std;
void printShareLib() {
cout << "linkage of lib_share" << endl;
}
lib_otherstatic.cpp:
#include <iostream>
#include "lib.hpp"
using namespace std;
void printStaticLib() {
cout << "linkage of the other lib_static with other text" << endl;
}
lib_othershare.cpp:
#include <iostream>
#include "lib.hpp"
using namespace std;
void printShareLib() {
cout << "linkage of the other lib_share with other text" << endl;
}
如果运行生成的脚本,您会发现
printShareLib()
在
.so
被交换后输出不同,但是
printStaticLib()
没有变化。(尝试不进行清理再次
make
,如果现在执行
./linkageLibrary
,您也会得到其他输出
printStaticLib()
。你能猜出为什么吗?)
对于您的第二个问题:
2-动态链接似乎自动查找内在依赖项(SDL2和SDL2_image)。静态链接不会。为什么会这样?
在不知道您的系统设置的情况下,我猜测您的构建系统无法找到
.a
静态库。尝试找到它在哪里,并最终将
find_library(SDL2_IMAGE_LIBRARY NAMES SDL2_image HINTS ${_YOUR_SDL2_INSTALLATION_PATH})
链接
现在回到您的问题,为什么建议动态链接SDL2,因为这是库开发人员的决定,您可以在他的
README中阅读到。
还请参考此
博客,了解如何在CMake中使用SDL2。