我是一名.NET开发者,最近开始学习C++。目前,我已经掌握了C++的基础语法和入门知识,并对FFmpeg产生了浓厚的兴趣。接下来,我计划自学与FFmpeg相关的技术内容,并记录自己的学习过程。欢迎大家提出宝贵意见,我会虚心接受并采纳大家的建议。谢谢!我是一名.NET开发者,最近开始学习C++。目前,我已经掌握了C++的基础语法和入门知识,并对FFmpeg产生了浓厚的兴趣。接下来,我计划自学与FFmpeg相关的技术内容,并记录自己的学习过程。欢迎大家提出宝贵意见,我会虚心接受并采纳大家的建议。谢谢!
- linux下构建自己的个性化的FFmpeg库
- linux下搭建属于自己风格的FFmpeg开发项目框架
目录结构设计
- project_name/
- ├── .vscode
- │ └── settings.json
- │ └── tasks.json
- ├── bin/ # 可执行文件
- ├── build/ # 编译中间文件(*.o, *.d)
- ├── lib/ # 库文件
- ├── include/ # 公共头文件(按模块/项目名组织)
- │ └── project_name/
- ├── src/ # 源文件(按模块组织)
- │ └── app/
- │ └── main.cpp
- │ └── project_name/
- │ └── xxx.cpp
- ├── test/ # 单元测试代码
- ├── thirdparty/ # 第三方库(或external/3rdparty)
- │ └── thirdpartylibname(例如:ffmpeg)
- │ └── include
- │ └── lib
- ├── CMakeLists.txt # 构建配置
- ├── build.sh #cmake 构建执行脚本
- └── README.md # 项目说明
复制代码学习了2中构建方式:
- Make构建
- task.json构建
CMake构建记录
- # 设置 CMake 最低版本要求
- cmake_minimum_required(VERSION 3.10)
- # 设置项目名称
- project(cpp-journey # 项目名称
- VERSION 1.0 # 项目版本(可选)
- LANGUAGES CXX # 指定语言(CXX为C++)
- )
- # 设置 C++ 标准
- set(CMAKE_CXX_STANDARD 17) # 设置 C++ 标准为 C++17
- set(CMAKE_CXX_STANDARD_REQUIRED ON) # 要求使用 C++17 标准
- set(CMAKE_BUILD_TYPE Release) # 默认构建类型(Debug/Release)
- # 设置可执行文件输出目录
- set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
- # 设置库文件输出目录
- set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
- # 添加头文件搜索路径
- include_directories(${PROJECT_SOURCE_DIR}/include)
- # 自动查找 src 目录下的所有源文件
- file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/*.cpp")
- # 生成静态库
- add_library(${PROJECT_NAME}_static STATIC ${SOURCES})
- set_target_properties(${PROJECT_NAME}_static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
- # 生成动态库
- add_library(${PROJECT_NAME}_shared SHARED ${SOURCES})
- set_target_properties(${PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
- # 添加可执行文件
- add_executable(${PROJECT_NAME}_${PROJECT_VERSION} ${SOURCES})
- # 链接库到可执行文件
- target_link_libraries(${PROJECT_NAME}_${PROJECT_VERSION} PRIVATE ${PROJECT_NAME}_shared)
- # find_package(FFmpeg REQUIRED)
- # target_link_libraries(cpp-journey_1.0 PRIVATE ${FFmpeg_LIBRARIES})
- # include_directories("/path/to/your/ffmpeg/include")
- # link_directories("/path/to/your/ffmpeg/lib/*")
- # 处理第三方库
- if(EXISTS "${PROJECT_SOURCE_DIR}/thirdparty")
- # 获取 thirdparty 目录下的所有子目录
- file(GLOB THIRDPARTY_DIRS "${PROJECT_SOURCE_DIR}/thirdparty/*")
- foreach(THIRDPARTY_DIR ${THIRDPARTY_DIRS})
- if(IS_DIRECTORY ${THIRDPARTY_DIR})
- # 获取第三方库名称
- get_filename_component(THIRDPARTY_NAME ${THIRDPARTY_DIR} NAME)
- # 添加第三方库的头文件搜索路径
- set(THIRDPARTY_INCLUDE_DIR "${THIRDPARTY_DIR}/include")
- if(EXISTS ${THIRDPARTY_INCLUDE_DIR})
- include_directories(${THIRDPARTY_INCLUDE_DIR})
- # target_include_directories(${PROJECT_NAME}_${PROJECT_VERSION} PRIVATE ${THIRDPARTY_INCLUDE_DIR})
- endif()
- # 查找 lib 目录下所有库文件
- file(GLOB THIRDPARTY_LIBS "${THIRDPARTY_DIR}/lib/*${CMAKE_SHARED_LIBRARY_SUFFIX}" "${THIRDPARTY_DIR}/lib/*${CMAKE_SHARED_LIBRARY_SUFFIX}*")
- if(THIRDPARTY_LIBS)
- # message(WARNING "---> 在 ${THIRDPARTY_DIR}/lib 中找到以下第三方库:")
- foreach(LIB ${THIRDPARTY_LIBS})
- # message(WARNING "---> ${PROJECT_NAME}_${PROJECT_VERSION} --->${LIB}")
- # 将找到的第三方库链接到可执行文件
- target_link_libraries(${PROJECT_NAME}_${PROJECT_VERSION} PRIVATE ${LIB})
- endforeach()
- else()
- message(WARNING "在 ${THIRDPARTY_DIR}/lib 中未找到任何第三方库")
- endif()
- endif()
- endforeach()
- endif()
- # 处理单元测试
- if(BUILD_TESTS)
- enable_testing()
- add_subdirectory(test)
- endif()
复制代码- #!/bin/bash
- # This script will build the project and run the tests.
- # 定义项目根目录
- PROJECT_ROOT=$(realpath "$(dirname "$0")")
- # 定义构建目录
- BUILD_DIR="$PROJECT_ROOT/build"
- # 定义是否启用测试,默认未启动 OFF
- ENABLE_TEST=${ENABLE_TEST:-OFF}
- # 创建并进入构建目录
- mkdir -p "$BUILD_DIR"
- cd "$BUILD_DIR" || { echo "无法进入构建目录 $BUILD_DIR,退出..."; exit 1; }
- # 运行 cmake 配置
- cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=$ENABLE_TEST
- # 检查 CMake 是否成功执行
- if [ $? -ne 0 ]; then
- echo "CMake configuration failed. Exiting..."
- exit 1
- fi
- # 编译项目
- make -j$(nproc) VERBOSE=1
- # 检查编译是否成功
- if [ $? -ne 0 ]; then
- echo "Build failed. Exiting..."
- exit 1
- fi
- echo "项目构建成功,可执行文件位于 $PROJECT_ROOT/bin 目录下。"
- # 检查是否启用测试
- if [ "$ENABLE_TEST" = "ON" ]; then
- # 运行测试
- ctest --output-on-failure
- fi
复制代码 task.json构建记录
- {
- // See https://go.microsoft.com/fwlink/?LinkId=733558
- // for the documentation about the tasks.json format
- "version": "2.0.0",
- "tasks": [
- // 清理旧文件
- {
- "label": "Clean",
- "type": "shell",
- "command": "rm -rf ${workspaceFolder}/build/",
- "group": "build"
- },
- // 编译所有 .cpp 为 .o 文件(增量编译)
- {
- "label": "Compile Objects",
- "type": "shell",
- "command": "bash",
- "args": [
- "-c",
- "mkdir -p build/obj build/bin && find src -name "*.cpp" | while read cpp_file; do obj_name="$(basename "$cpp_file" .cpp).o" ; g++ -c -std=c++17 -Iinclude -Ithirdparty/ffmpeg/include -o "build/obj/$obj_name" "$cpp_file"; done"
- ],
- "group": "build"
- },
- // 链接生成可执行文件
- {
- "label": "Link Executable",
- "type": "shell",
- "command": "g++",
- "args": [
- "${workspaceFolder}/build/obj/*.o",
- //"$(find ${workspaceFolder}/build/obj -name '*.o')",
- //链接选项 -l 应直接指定库名称(如 -lavcodec),而库的实际路径需通过 -L 参数指定
- "-L${workspaceFolder}/thirdparty/ffmpeg/lib",
- //GCC 的 -l 默认会自动添加前缀 lib 和后缀(如 .so)
- //FFmpeg 库有严格的依赖顺序,错误的顺序会导致链接失败。
- //-l: 语法强制指定文件名,绕过默认的 lib<name>.so 规则
- "-l:libavformat.so.62", "-l:libavcodec.so.62", "-l:libswresample.so.6", "-l:libswscale.so.9", "-l:libavfilter.so.11", "-l:libavutil.so.60", "-l:libavdevice.so.62",
- "-o",
- "${workspaceFolder}/build/bin/app"
- ],
- "dependsOn": ["Compile Objects"],
- "group": "build"
- },
- ]
- }
复制代码 请教过C++大神,推荐我开始学习的时候采用task.json方式进行构建,如果以后有幸最大项目开发,可以采用cmake方案。但是,经过2个方案的简单学习,我个人比较喜欢cmake方式,目前学习项目采用的构建方式都是通过cmake方式实现进行的,日后遇到坑在自己慢慢填吧!
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |