diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 8041aee3..3defd93f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -69,7 +69,6 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - submodules: true - name: Configure shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d540293..b5a0b0ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,7 +8,6 @@ jobs: - uses: actions/checkout@v3 with: fetch-depth: 0 - submodules: true - name: Source release shell: bash diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e6f975c4..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "libMXF"] - path = deps/libMXF - url = ../libMXF.git -[submodule "libMXFpp"] - path = deps/libMXFpp - url = ../libMXFpp.git diff --git a/README.md b/README.md index 95c4426f..258d1289 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ bmx is a library and set of utilities to read and write the [SMPTE ST 377-1 MXF bmx is used to support standardisation efforts in the broadcast industry. It provides utilities for creating standard compliant sample files. It serves as an example implementation for MXF file format standards. +bmx includes the [libMXF](./deps/libMXF) low-level MXF C library and the [libMXF++](./deps/libMXFpp) C++ wrapper library. + bmx provides a set of commandline applications: * **raw2bmx**: create MXF files from raw essence files @@ -19,7 +21,7 @@ bmx provides a set of file format text dumper and essence extraction tools: * **movdump**: text dump Quicktime / MP4 files * **rdd36dump**: text dump SMPTE RDD 36 (Apple ProRes) bitstream files * **vc2dump**: text dump SMPTE ST 2042 VC-2 bitstream files -* **MXFDump**: text dumper for MXF files from the [AAF SDK](https://sourceforge.net/projects/aaf/). This utility is made available and built as part of [libMXF](https://github.com/bbc/libMXF). +* **MXFDump**: text dumper for MXF files from the [AAF SDK](https://sourceforge.net/projects/aaf/). This utility is made available and built as part of [libMXF](./deps/libMXF). The following input and output wrapper formats and flavours are supported: @@ -73,13 +75,7 @@ The build process has been tested on Ubuntu, Debian, MacOS and Windows (Microsof ### Dependencies -The [libMXF](https://github.com/bbc/libMXF) and [libMXF++](https://github.com/bbc/libMXFpp) libraries are required. They are included as git submodules in the `deps/` directory. Run - -```bash -git submodule update --init -``` - -to ensure the submodules are available and up-to-date in the working tree. +The [libMXF](./deps/libMXF/) and [libMXF++](./deps/libMXFpp/) libraries are required. The [uriparser](https://github.com/uriparser/uriparser) and [expat](https://github.com/libexpat/libexpat) libraries are required. These libraries are typically provided as software packages on Unix-like systems; the Ubuntu / Debian package names are `liburiparser-dev` and `libexpat1-dev`. The libraries are built from the GitHub source when building on Windows using Microsoft Visual Studio C++. @@ -89,7 +85,7 @@ The [libcurl](https://curl.haxx.se/libcurl/) (Ubuntu / Debian package name `libc ### Commands -A basic commandline process is described here for platforms that default to the Unix Makefiles or Visual Studio cmake generators. See [./docs/build.md](./docs/build.md) for more detailed build options. +A basic commandline process is described here for platforms that default to the Unix Makefiles or Visual Studio cmake generators. See [build.md](./docs/build.md) for more detailed build options. Replace `` in the commandlines below with `Debug` or `Release`. Note that the Visual Studio generator supports multiple build types for a configuration, which is why the build type is selected _after_ configuration. @@ -167,7 +163,7 @@ add_executable(example example.cpp) target_link_libraries(example bmx) ``` -The `BMX_BUILD_LIB_ONLY` cmake option can be set to `ON` to avoid building the apps and examples in bmx, libMXF and libMXF++. Setting the option to `ON` will disable the bmx tests because they requires the apps. Add this line to the cmake +The `BMX_BUILD_LIB_ONLY` cmake option can be set to `ON` to avoid building the apps and examples in bmx, [libMXF](./deps/libMXF) and [libMXF++](./deps/libMXFpp). Setting the option to `ON` will disable the bmx tests because they requires the apps. Add this line to the cmake ```text set(BMX_BUILD_LIB_ONLY ON CACHE BOOL "Build bmx, MXF and MXF++ libraries only") @@ -191,19 +187,13 @@ See [Docker Run](#docker-run) for more details on the script. ### Docker Build -The [Dockerfile](./Dockerfile) is used for building a Docker image containing a set of tools from bmx, libMXF and AAF SDK. +The [Dockerfile](./Dockerfile) is used for building a Docker image containing a set of tools from bmx, [libMXF](./deps/libMXF) and [AAF SDK](https://sourceforge.net/projects/aaf/). The Dockerfile contains a **build** and **runtime** layer: -* **build**: builds and checks the libMXF, libMXF++ and bmx code. +* **build**: builds and checks the [libMXF](./deps/libMXF), [libMXF++](./deps/libMXFpp) and bmx code. * **runtime**: provides the commandline tool executables built in the `build` layer. -Ensure that the libMXF and libMXFpp git submodules are available and up-to-date in the `deps/` directory by running, - -```bash -git submodule update --init -``` - The runtime Docker image can be built in the top-level directory using docker build, ```bash diff --git a/cmake/libmxf.cmake b/cmake/libmxf.cmake index 4c0a457e..51f396ff 100644 --- a/cmake/libmxf.cmake +++ b/cmake/libmxf.cmake @@ -13,8 +13,7 @@ if(BMX_BUILD_LIBMXF_LIB) else() if(NOT EXISTS ${PROJECT_SOURCE_DIR}/deps/libMXF/CMakeLists.txt) message(FATAL_ERROR - "libMXF submodule source code does not exist at 'deps/libMXF'\n" - "Run 'git submodule update --init' to fetch the source" + "libMXF source code does not exist at 'deps/libMXF'" ) endif() diff --git a/cmake/libmxfpp.cmake b/cmake/libmxfpp.cmake index 8e4a3383..a8093a1e 100644 --- a/cmake/libmxfpp.cmake +++ b/cmake/libmxfpp.cmake @@ -13,8 +13,7 @@ if(BMX_BUILD_LIBMXFPP_LIB) else() if(NOT EXISTS ${PROJECT_SOURCE_DIR}/deps/libMXFpp/CMakeLists.txt) message(FATAL_ERROR - "libMXF submodule source code does not exist at 'deps/libMXFpp'\n" - "Run 'git submodule update --init' to fetch the source" + "libMXF++ source code does not exist at 'deps/libMXFpp'" ) endif() diff --git a/deps/libMXF b/deps/libMXF deleted file mode 160000 index 8df9ccca..00000000 --- a/deps/libMXF +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8df9ccca93256476386064154fe4f4d4df9f4b0d diff --git a/deps/libMXF/.gitignore b/deps/libMXF/.gitignore new file mode 100644 index 00000000..6fb0d664 --- /dev/null +++ b/deps/libMXF/.gitignore @@ -0,0 +1,14 @@ +*~ +build/ +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps +out/ diff --git a/deps/libMXF/CMakeLists.txt b/deps/libMXF/CMakeLists.txt new file mode 100644 index 00000000..db810fa4 --- /dev/null +++ b/deps/libMXF/CMakeLists.txt @@ -0,0 +1,88 @@ +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15.0) + # Set policy CMP0091 to new to allow use of CMAKE_MSVC_RUNTIME_LIBRARY + cmake_policy(SET CMP0091 NEW) +endif() + +project(libMXF + VERSION 1.1 + DESCRIPTION "Low-level C library for reading and writing the SMPTE ST 377-1 MXF file format" + HOMEPAGE_URL https://github.com/bbc/libMXF + LANGUAGES C CXX +) + +include("${CMAKE_CURRENT_LIST_DIR}/cmake/options.cmake") + +if(MSVC AND LIBMXF_SET_MSVC_RUNTIME AND CMAKE_VERSION VERSION_GREATER_EQUAL 3.15.0) + # cmake version >= 3.15: Use MultiThreadedDLL runtime + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") +endif() + +if(BUILD_SHARED_LIBS) + # Ensure that static library code can be linked into the dynamic libraries (-fPIC compile option) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() +set(CMAKE_CXX_STANDARD 11) + +# Set the test samples output directory +if(LIBMXF_TEST_SAMPLES_DIR STREQUAL "") + set(new_samples_dir ${CMAKE_CURRENT_BINARY_DIR}/test_samples) +else() + get_filename_component(new_samples_dir + ${LIBMXF_TEST_SAMPLES_DIR} + REALPATH + BASE_DIR ${CMAKE_CURRENT_BINARY_DIR} + ) +endif() +if(NOT new_samples_dir STREQUAL ${LIBMXF_TEST_SAMPLES_DIR}) + set(LIBMXF_TEST_SAMPLES_DIR ${new_samples_dir}) + message("-- Test samples output directory: ${LIBMXF_TEST_SAMPLES_DIR}") +endif() + +if(MSVC) + add_compile_options(/W3) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + + if(LIBMXF_SET_MSVC_RUNTIME AND CMAKE_VERSION VERSION_LESS 3.15.0) + # cmake version < 3.15: Update compiler flags to use the MultiThreadedDLL runtime + macro(update_msvc_runtime_flags flags) + string(REGEX REPLACE "/MT" "/MD" ${flags} "${${flags}}") + endmacro() + + update_msvc_runtime_flags(CMAKE_C_FLAGS) + update_msvc_runtime_flags(CMAKE_CXX_FLAGS) + foreach(suffix _DEBUG _RELEASE _MINSIZEREL _RELWITHDEBINFO) + update_msvc_runtime_flags(CMAKE_C_FLAGS${suffix}) + update_msvc_runtime_flags(CMAKE_CXX_FLAGS${suffix}) + endforeach() + endif() +else() + add_compile_options(-W -Wall -O2) + + # Enable large file support on 32-bit systems. + add_definitions( + -D_FILE_OFFSET_BITS=64 + -D_LARGEFILE_SOURCE + -D_LARGEFILE64_SOURCE + ) +endif() + +if(LIBMXF_BUILD_TESTING AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING)) + enable_testing() +endif() +add_custom_target(libMXF_test_samples) +add_custom_target(libMXF_test_data) + +include("${PROJECT_SOURCE_DIR}/cmake/ext_uuid.cmake") + +configure_file(config.h.in config.h) + +add_subdirectory(mxf) +if(LIBMXF_BUILD_TESTING AND (NOT DEFINED BUILD_TESTING OR BUILD_TESTING)) + add_subdirectory(test) +endif() +if(NOT LIBMXF_BUILD_LIB_ONLY) + add_subdirectory(examples) + add_subdirectory(tools) +endif() diff --git a/deps/libMXF/COPYING b/deps/libMXF/COPYING new file mode 100644 index 00000000..1d5f1833 --- /dev/null +++ b/deps/libMXF/COPYING @@ -0,0 +1,26 @@ +Copyright (C) 2014, British Broadcasting Corporation +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the British Broadcasting Corporation nor the names + of its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/deps/libMXF/README.md b/deps/libMXF/README.md new file mode 100644 index 00000000..40efb08b --- /dev/null +++ b/deps/libMXF/README.md @@ -0,0 +1,78 @@ +# libMXF + +libMXF is a low-level C library for reading and writing the [SMPTE ST 377-1 MXF file format](https://ieeexplore.ieee.org/document/7292073). + +libMXF was originally developed as part of the [Ingex Project](http://ingex.sourceforge.net/) where it supported MXF transfer, playback and storage applications. libMXF was also used in the [BBC Archive Preservation Project](https://www.bbc.co.uk/rd/publications/whitepaper275) to migrate BBC archive content from video tapes to files. + +The [MXFDump](./tools/MXFDump) MXF text dumper utility from the [AAF SDK](https://sourceforge.net/projects/aaf/) is provided in this project for convenience. + +## Examples + +A number of applications and library code can be found in the [examples](./examples) directory. These are not part of the core library and are not required to build [libMXF++](../libMXFpp) or [bmx](../../). + +* [archive](./examples/archive): library code and utilities used in the [BBC Archive Preservation Project](https://www.bbc.co.uk/rd/publications/whitepaper275). +* [avidmxfinfo](./examples/avidmxfinfo): library and utility for extracting metadata about Avid MXF OP-Atom files. This utility has been superseded by +`mxf2raw` in the [bmx](../../) project. +* [reader](./examples/reader): library code used by the [Ingex Player](http://ingex.sourceforge.net/) for reading MXF files. +* [transfertop2](./examples/transfertop2): utilities used in the [TransferToP2](http://ingex.sourceforge.net/TransferToP2.html) application to allow edited sequences to be transferred from an editing system to a P2 card. +* [vlc](./examples/vlc): legacy code that was written to test how easy it would be to support MXF in [VLC](https://www.videolan.org/vlc/). +* [writeaviddv50](./examples/writeaviddv50): example utility for writing DV 50 MBit/s video in Avid MXF OP-Atom files. +* [writeavidmxf](./examples/writeavidmxf): library code and utility for writing Avid MXF OP-Atom files. This utility has been superseded by `raw2bmx` in the [bmx](../../) project. + +## Build, Test and Install + +libMXF is developed on Ubuntu Linux but is supported on other Unix-like systems and Windows. + +The [cmake](https://cmake.org/) build system is used, with minimum version **3.12**. The build requires the `git` tool along with the C/C++ compilers. + +The build process has been tested on Ubuntu, Debian, MacOS and Windows (Microsoft Visual C++ 2017 v15.9.51 and later versions). + +### Dependencies + +The uuid library (Ubuntu / Debian package name `uuid-dev`) is required for non-Apple Unix-like systems. + +### Commands + +A basic commandline process is described here for platforms that default to the Unix Makefiles or Visual Studio cmake generators. See [build.md](./docs/build.md) for more detailed build options. + +Replace `` in the commandlines below with `Debug` or `Release`. Note that the Visual Studio generator supports multiple build types for a configuration, which is why the build type is selected _after_ configuration. + +The default generator can be overridden using the cmake `-G` option. The list of available generators is shown at the end of the output of `cmake --help`. + +Start by creating a build directory and change into it. The commandlines below use a `out/build` build directory in the working tree, which follows the approach taken by Microsoft Visual Studio C++. + +#### Unix-like (Unix Makefiles) + +```bash +mkdir -p out/build +cd out/build +cmake ../../ -DCMAKE_BUILD_TYPE= +cmake --build . +make test +sudo make install +``` + +Run `ldconfig` to update the runtime linker cache. This avoids library link errors similar to "error while loading shared libraries". + +```bash +sudo /sbin/ldconfig +``` + +#### Windows (Visual Studio) + +```console +mkdir out\build +cd out\build +cmake ..\..\ +cmake --build . --config +ctest -C +cmake --build . --config --target install +``` + +## Source and Binary Distributions + +Source distributions, including dependencies for the Windows build, and Windows binaries are made available as in [bmx](../../). + +## License + +The libMXF library is provided under the BSD 3-clause license. See the [COPYING](./COPYING) file provided with this library for more details. diff --git a/deps/libMXF/cmake/ext_uuid.cmake b/deps/libMXF/cmake/ext_uuid.cmake new file mode 100644 index 00000000..ee34277d --- /dev/null +++ b/deps/libMXF/cmake/ext_uuid.cmake @@ -0,0 +1,28 @@ +if(uuid_link_lib) + return() +endif() + + +if(UNIX AND NOT APPLE) + find_library(uuid_lib + NAMES uuid + ) + find_path(uuid_include_dir + NAMES uuid/uuid.h + ) + + if(NOT uuid_lib OR NOT uuid_include_dir) + message(FATAL_ERROR "uuid dependency not found") + endif() + + add_library(libuuid UNKNOWN IMPORTED) + set_target_properties(libuuid PROPERTIES + IMPORTED_LOCATION ${uuid_lib} + INTERFACE_INCLUDE_DIRECTORIES ${uuid_include_dir} + ) + set(uuid_link_lib libuuid) +else() + # MSVC: "ole" will already be linked in + # APPLE: doesn't require uuid library + set(uuid_link_lib) +endif() diff --git a/deps/libMXF/cmake/git_version.cmake b/deps/libMXF/cmake/git_version.cmake new file mode 100644 index 00000000..e1171568 --- /dev/null +++ b/deps/libMXF/cmake/git_version.cmake @@ -0,0 +1,39 @@ +if(TARGET libmxf_git_version) + return() +endif() + + +# Ensure the cmake targets and code symbols are libMXF specific +set(GIT_VERSION_PROJECT_PREFIX "libmxf_") + +# Set the git release tag pattern to describe relative to +set(GIT_DESCRIBE_TAG_PATTERN "v${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") +set(GIT_WORKING_DIR ${PROJECT_SOURCE_DIR}) + +# Set to ignore git_version errors if there is no .git directory +set(GIT_FAIL_IF_NONZERO_EXIT FALSE) + +include(FetchContent) + +set(git_version_deps_source "${PROJECT_SOURCE_DIR}/deps/cmake-git-version-tracking") + +if(EXISTS ${git_version_deps_source}) + FetchContent_Declare(libmxf_git_version + SOURCE_DIR ${git_version_deps_source} + ) + message("-- Build using git version source: ${git_version_deps_source}") +else() + FetchContent_Declare(libmxf_git_version + GIT_REPOSITORY "https://github.com/andrew-hardin/cmake-git-version-tracking.git" + GIT_TAG "904dbda1336ba4b9a1415a68d5f203f576b696bb" + PATCH_COMMAND git clean -fdx + COMMAND git reset --hard + COMMAND git apply --ignore-whitespace "${CMAKE_CURRENT_LIST_DIR}/git_version_904dbda.patch" + ) +endif() + +FetchContent_GetProperties(libmxf_git_version) +if(NOT libmxf_git_version_POPULATED) + FetchContent_Populate(libmxf_git_version) + add_subdirectory(${libmxf_git_version_SOURCE_DIR} ${libmxf_git_version_BINARY_DIR}) +endif() diff --git a/deps/libMXF/cmake/git_version_904dbda.patch b/deps/libMXF/cmake/git_version_904dbda.patch new file mode 100644 index 00000000..9380a2c5 --- /dev/null +++ b/deps/libMXF/cmake/git_version_904dbda.patch @@ -0,0 +1,299 @@ +From f771b6e67b3086f02ae3d5b173b97d4f76c9f801 Mon Sep 17 00:00:00 2001 +From: Philip de Nier +Date: Wed, 15 Feb 2023 10:12:09 +0000 +Subject: [PATCH] Updates for bmx + +--- + CMakeLists.txt | 12 +++++++---- + git.c.in | 23 +++++++++++---------- + git.h => git.h.in | 51 +++++++++++++++++++++++++++-------------------- + git_watcher.cmake | 20 ++++++++++++++++++- + 4 files changed, 69 insertions(+), 37 deletions(-) + rename git.h => git.h.in (61%) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 55e6d07..e1ce4a0 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -1,7 +1,11 @@ + cmake_minimum_required(VERSION 3.2) +-project(cmake_git_version_tracking ++ ++project(${GIT_VERSION_PROJECT_PREFIX}git_version + LANGUAGES C) + ++# Apply the GIT_VERSION_PROJECT_PREFIX to the function names ++configure_file(git.h.in git.h) ++ + # Define the two required variables before including + # the source code for watching a git repository. + set(PRE_CONFIGURE_FILE "git.c.in") +@@ -13,9 +17,9 @@ include(git_watcher.cmake) + # Note that the include is a system include. This was done + # so downstream projects don't suffer from warnings on a + # 3rdparty library. +-add_library(${PROJECT_NAME} STATIC ${POST_CONFIGURE_FILE}) +-target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +-add_dependencies(${PROJECT_NAME} check_git) ++add_library(${PROJECT_NAME} OBJECT ${POST_CONFIGURE_FILE}) ++target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) ++add_dependencies(${PROJECT_NAME} ${GIT_VERSION_PROJECT_PREFIX}check_git) + + # The C99 standard is only required because we're using . + # This could be removed if it's a problem for users, but would require the +diff --git a/git.c.in b/git.c.in +index a26d27c..319b33f 100644 +--- a/git.c.in ++++ b/git.c.in +@@ -1,32 +1,35 @@ + #include "git.h" + +-bool git_IsPopulated() { ++bool @GIT_VERSION_PROJECT_PREFIX@git_IsPopulated() { + return @GIT_RETRIEVED_STATE@; + } +-bool git_AnyUncommittedChanges() { ++bool @GIT_VERSION_PROJECT_PREFIX@git_AnyUncommittedChanges() { + return @GIT_IS_DIRTY@; + } +-const char* git_AuthorName() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_AuthorName() { + return "@GIT_AUTHOR_NAME@"; + } +-const char* git_AuthorEmail() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_AuthorEmail() { + return "@GIT_AUTHOR_EMAIL@"; + } +-const char* git_CommitSHA1() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitSHA1() { + return "@GIT_HEAD_SHA1@"; + } +-const char* git_CommitDate() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitDate() { + return "@GIT_COMMIT_DATE_ISO8601@"; + } +-const char* git_CommitSubject() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitSubject() { + return "@GIT_COMMIT_SUBJECT@"; + } +-const char* git_CommitBody() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitBody() { + return "@GIT_COMMIT_BODY@"; + } +-const char* git_Describe() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_Describe() { + return "@GIT_DESCRIBE@"; + } +-const char* git_Branch() { ++const char* @GIT_VERSION_PROJECT_PREFIX@git_Branch() { + return "@GIT_BRANCH@"; + } ++const char* @GIT_VERSION_PROJECT_PREFIX@git_DescribeTag() { ++ return "@GIT_DESCRIBE_TAG@"; ++} +diff --git a/git.h b/git.h.in +similarity index 61% +rename from git.h +rename to git.h.in +index fee780e..739bd34 100644 +--- a/git.h ++++ b/git.h.in +@@ -22,35 +22,38 @@ GIT_VERSION_TRACKING_EXTERN_C_BEGIN + // + /// We may not have metadata if there wasn't a .git directory + /// (e.g. downloaded source code without revision history). +-bool git_IsPopulated(); ++bool @GIT_VERSION_PROJECT_PREFIX@git_IsPopulated(); + + /// Were there any uncommitted changes that won't be reflected + /// in the CommitID? +-bool git_AnyUncommittedChanges(); ++bool @GIT_VERSION_PROJECT_PREFIX@git_AnyUncommittedChanges(); + + /// The commit author's name. +-const char* git_AuthorName(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_AuthorName(); + + /// The commit author's email. +-const char* git_AuthorEmail(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_AuthorEmail(); + + /// The commit SHA1. +-const char* git_CommitSHA1(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitSHA1(); + + /// The ISO8601 commit date. +-const char* git_CommitDate(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitDate(); + + /// The commit subject. +-const char* git_CommitSubject(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitSubject(); + + /// The commit body. +-const char* git_CommitBody(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_CommitBody(); + + /// The commit describe. +-const char* git_Describe(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_Describe(); + + /// The symbolic reference tied to HEAD. +-const char* git_Branch(); ++const char* @GIT_VERSION_PROJECT_PREFIX@git_Branch(); ++ ++/// The commit describe relative to matching tag. ++const char* @GIT_VERSION_PROJECT_PREFIX@git_DescribeTag(); + + GIT_VERSION_TRACKING_EXTERN_C_END + #undef GIT_VERSION_TRACKING_EXTERN_C_BEGIN +@@ -84,7 +87,7 @@ GIT_VERSION_TRACKING_EXTERN_C_END + #include + #endif + +-namespace git { ++namespace @GIT_VERSION_PROJECT_PREFIX@git { + + #if GIT_VERSION_USE_STRING_VIEW + using StringOrView = std::string_view; +@@ -106,45 +109,49 @@ const StringOrView InitString(const char* from_c_interface) { + } // namespace internal + + inline bool IsPopulated() { +- return git_IsPopulated(); ++ return @GIT_VERSION_PROJECT_PREFIX@git_IsPopulated(); + } + inline bool AnyUncommittedChanges() { +- return git_AnyUncommittedChanges(); ++ return @GIT_VERSION_PROJECT_PREFIX@git_AnyUncommittedChanges(); + } + inline const StringOrView& AuthorName() { +- static const StringOrView kValue = internal::InitString(git_AuthorName()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_AuthorName()); + return kValue; + } + inline const StringOrView AuthorEmail() { +- static const StringOrView kValue = internal::InitString(git_AuthorEmail()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_AuthorEmail()); + return kValue; + } + inline const StringOrView CommitSHA1() { +- static const StringOrView kValue = internal::InitString(git_CommitSHA1()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_CommitSHA1()); + return kValue; + } + inline const StringOrView CommitDate() { +- static const StringOrView kValue = internal::InitString(git_CommitDate()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_CommitDate()); + return kValue; + } + inline const StringOrView CommitSubject() { +- static const StringOrView kValue = internal::InitString(git_CommitSubject()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_CommitSubject()); + return kValue; + } + inline const StringOrView CommitBody() { +- static const StringOrView kValue = internal::InitString(git_CommitBody()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_CommitBody()); + return kValue; + } + inline const StringOrView Describe() { +- static const StringOrView kValue = internal::InitString(git_Describe()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_Describe()); + return kValue; + } + inline const StringOrView Branch() { +- static const StringOrView kValue = internal::InitString(git_Branch()); ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_Branch()); ++ return kValue; ++} ++inline const StringOrView DescribeTag() { ++ static const StringOrView kValue = internal::InitString(@GIT_VERSION_PROJECT_PREFIX@git_DescribeTag()); + return kValue; + } + +-} // namespace git ++} // namespace @GIT_VERSION_PROJECT_PREFIX@git + + + // Cleanup our defines to avoid polluting. +diff --git a/git_watcher.cmake b/git_watcher.cmake +index 32313a3..b45b106 100644 +--- a/git_watcher.cmake ++++ b/git_watcher.cmake +@@ -15,6 +15,9 @@ + # POST_CONFIGURE_FILE (REQUIRED) + # -- The path to the configured PRE_CONFIGURE_FILE. + # ++# GIT_VERSION_PROJECT_PREFIX (OPTIONAL) ++# -- Name prefix for source code functions. ++# + # GIT_STATE_FILE (OPTIONAL) + # -- The path to the file used to store the previous build's git state. + # Defaults to the current binary directory. +@@ -36,6 +39,9 @@ + # -- Ignore the presence of untracked files when detecting if the + # working tree is dirty. This is set to FALSE by default. + # ++# GIT_DESCRIBE_TAG_PATTERN (OPTIONAL) ++# -- Git tag pattern to match against to produce the GIT_DESCRIBE_TAG variable. ++# + # DESIGN + # - This script was designed similar to a Python application + # with a Main() function. I wanted to keep it compact to +@@ -81,6 +87,7 @@ endmacro() + + CHECK_REQUIRED_VARIABLE(PRE_CONFIGURE_FILE) + CHECK_REQUIRED_VARIABLE(POST_CONFIGURE_FILE) ++CHECK_OPTIONAL_VARIABLE_NOPATH(GIT_VERSION_PROJECT_PREFIX "") + CHECK_OPTIONAL_VARIABLE(GIT_STATE_FILE "${CMAKE_CURRENT_BINARY_DIR}/git-state-hash") + CHECK_OPTIONAL_VARIABLE(GIT_WORKING_DIR "${CMAKE_SOURCE_DIR}") + CHECK_OPTIONAL_VARIABLE_NOPATH(GIT_FAIL_IF_NONZERO_EXIT TRUE) +@@ -105,6 +112,7 @@ set(_state_variable_names + GIT_COMMIT_BODY + GIT_DESCRIBE + GIT_BRANCH ++ GIT_DESCRIBE_TAG + # >>> + # 1. Add the name of the additional git variable you're interested in monitoring + # to this list. +@@ -242,6 +250,14 @@ function(GetGitState _working_dir) + set(ENV{GIT_BRANCH} "${output}") + endif() + ++ # Get output of git describe relative to the matching tag ++ RunGitCommand(describe --match ${GIT_DESCRIBE_TAG_PATTERN} ${object}) ++ if(NOT exit_code EQUAL 0) ++ set(ENV{GIT_DESCRIBE_TAG} "unknown") ++ else() ++ set(ENV{GIT_DESCRIBE_TAG} "${output}") ++ endif() ++ + # >>> + # 2. Additional git properties can be added here via the + # "execute_process()" command. Be sure to set them in +@@ -324,7 +340,7 @@ endfunction() + # check the state of git before every build. If the state has + # changed, then a file is configured. + function(SetupGitMonitoring) +- add_custom_target(check_git ++ add_custom_target(${GIT_VERSION_PROJECT_PREFIX}check_git + ALL + DEPENDS ${PRE_CONFIGURE_FILE} + BYPRODUCTS +@@ -337,10 +353,12 @@ function(SetupGitMonitoring) + -DGIT_WORKING_DIR=${GIT_WORKING_DIR} + -DGIT_EXECUTABLE=${GIT_EXECUTABLE} + -DGIT_STATE_FILE=${GIT_STATE_FILE} ++ -DGIT_VERSION_PROJECT_PREFIX=${GIT_VERSION_PROJECT_PREFIX} + -DPRE_CONFIGURE_FILE=${PRE_CONFIGURE_FILE} + -DPOST_CONFIGURE_FILE=${POST_CONFIGURE_FILE} + -DGIT_FAIL_IF_NONZERO_EXIT=${GIT_FAIL_IF_NONZERO_EXIT} + -DGIT_IGNORE_UNTRACKED=${GIT_IGNORE_UNTRACKED} ++ -DGIT_DESCRIBE_TAG_PATTERN=${GIT_DESCRIBE_TAG_PATTERN} + -P "${CMAKE_CURRENT_LIST_FILE}") + endfunction() + +-- +2.25.1 + diff --git a/deps/libMXF/cmake/options.cmake b/deps/libMXF/cmake/options.cmake new file mode 100644 index 00000000..39a50255 --- /dev/null +++ b/deps/libMXF/cmake/options.cmake @@ -0,0 +1,50 @@ +# Option to only build the library +option(LIBMXF_BUILD_LIB_ONLY "Build MXF library only" OFF) + +# Option to build testing +# This option is ignored if BUILD_TESTING is defined and falsy +option(LIBMXF_BUILD_TESTING "Build libMXF testing" ON) + +# Option to build all the examples +option(LIBMXF_BUILD_EXAMPLES "Build all the examples" OFF) + +# Option to build the archive example +option(LIBMXF_BUILD_ARCHIVE "Build the archive example" OFF) + +# Option to build the avidmxfinfo example +option(LIBMXF_BUILD_AVIDMXFINFO "Build the avidmxfinfo example" OFF) + +# Option to build the reader example +option(LIBMXF_BUILD_READER "Build the reader example" OFF) + +# Option to build the transfertop2 example +option(LIBMXF_BUILD_TRANSFERTOP2 "Build the transfertop2 example" OFF) + +# Option to build the writeaviddv50 example +option(LIBMXF_BUILD_WRITEAVIDDV50 "Build the writeaviddv50 example" OFF) + +# Option to build the writeavidmxf example +option(LIBMXF_BUILD_WRITEAVIDMXF "Build the writeavidmxf example" OFF) + +# Option to build all the tools +option(LIBMXF_BUILD_TOOLS "Build all the tools" OFF) + +# Option to build the MXFDump tool +option(LIBMXF_BUILD_MXFDUMP "Build the MXFDump tool" ON) + +# Option to change the directory where test sample files are written +set(LIBMXF_TEST_SAMPLES_DIR "test_samples" CACHE STRING "Directory for writing test sample files") + +if(UNIX) + # Option to build a shared object library + option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + + # Run tests with valgrind + option(LIBMXF_TEST_WITH_VALGRIND "Run tests with valgrind" OFF) +elseif(MSVC) + # Shared library currently not supported + set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build using shared libraries") + + # Option to set to use the MultiThreadedDLL runtime + option(LIBMXF_SET_MSVC_RUNTIME "Enable setting MSVC runtime to MultiThreadedDLL" ON) +endif() diff --git a/deps/libMXF/cmake/source_filename.cmake b/deps/libMXF/cmake/source_filename.cmake new file mode 100644 index 00000000..7237ede3 --- /dev/null +++ b/deps/libMXF/cmake/source_filename.cmake @@ -0,0 +1,11 @@ +# Adds the __FILENAME__=filename compile definition. +# Based on https://stackoverflow.com/a/27990434, but changed to define __FILENAME__ to be a relative project path +function(set_source_filename target sources_base_dir project_dirname) + get_target_property(source_files "${target}" SOURCES) + foreach(source_file ${source_files}) + file(RELATIVE_PATH rel_path ${PROJECT_SOURCE_DIR} "${sources_base_dir}/${source_file}") + set_property( + SOURCE "${source_file}" APPEND + PROPERTY COMPILE_DEFINITIONS "__FILENAME__=\"${project_dirname}/${rel_path}\"") + endforeach() +endfunction() diff --git a/deps/libMXF/cmake/test_with_checksum.cmake b/deps/libMXF/cmake/test_with_checksum.cmake new file mode 100644 index 00000000..48cf1023 --- /dev/null +++ b/deps/libMXF/cmake/test_with_checksum.cmake @@ -0,0 +1,43 @@ +# Run the test command to produce the output MXF file. +# Generate an MD5 checksum from the output MXF file and compare it to the expected value. + +# Get the arguments after -- which will be passed to the command ${TEST_COMMAND} +set(command_args) +set(start_of_args FALSE) +foreach(index RANGE ${CMAKE_ARGC}-1) + if(start_of_args) + list(APPEND command_args "${CMAKE_ARGV${index}}") + elseif(CMAKE_ARGV${index} STREQUAL "--") + set(start_of_args TRUE) + endif() +endforeach() + + +if(TEST_MODE STREQUAL "check" AND LIBMXF_TEST_WITH_VALGRIND) + set(prefix_command valgrind --leak-check=full -q) +else() + set(prefix_command) +endif() + +execute_process(COMMAND ${prefix_command} ${TEST_COMMAND} + ${command_args} + RESULT_VARIABLE ret) +if(NOT ret EQUAL 0) + message(FATAL_ERROR "Command failed: ${ret}") +endif() + +if(TEST_MODE STREQUAL "check" OR TEST_MODE STREQUAL "data") + file(MD5 ${OUTPUT_FILE} checksum) + + if(TEST_MODE STREQUAL "check") + file(READ ${CHECKSUM_FILE} expected_checksum) + if(NOT checksum STREQUAL expected_checksum) + message(FATAL_ERROR "File checksum ${checksum} != expected ${expected_checksum}") + endif() + else() + file(WRITE ${CHECKSUM_FILE} "${checksum}") + endif() +else() + file(MAKE_DIRECTORY ${TEST_SAMPLES_DIR}) + file(RENAME ${OUTPUT_FILE} ${TEST_SAMPLES_DIR}/${SAMPLE_OUTPUT_FILE}) +endif() diff --git a/deps/libMXF/config.h.in b/deps/libMXF/config.h.in new file mode 100644 index 00000000..a5276a53 --- /dev/null +++ b/deps/libMXF/config.h.in @@ -0,0 +1,16 @@ +/* library names */ +#define LIBMXF_LIBRARY_NAME "@PROJECT_NAME@" +#define LIBMXF_LIBRARY_WNAME L"@PROJECT_NAME@" + +/* Library versions */ +#define LIBMXF_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define LIBMXF_VERSION_MINOR @PROJECT_VERSION_MINOR@ + +/* Define printf size_t format specifier */ +#if defined(_WIN64) +#define PRIszt "I64u" +#elif defined(_WIN32) +#define PRIszt "u" +#else +#define PRIszt "zu" +#endif diff --git a/deps/libMXF/docs/build.md b/deps/libMXF/docs/build.md new file mode 100644 index 00000000..4b181529 --- /dev/null +++ b/deps/libMXF/docs/build.md @@ -0,0 +1,62 @@ +# Building libMXF + +## Configure Options + +The libMXF cmake configure options can be found in [cmake/options.cmake](../cmake/options.cmake). + +Most options are booleans and can be set to `ON` or `OFF` using the `cmake` commandline option `-D