Author: Andreas Tille <tille@debian.org>
Last-Update: 2026-01-08
Forwarded: https://codeberg.org/tenacityteam/libmad/issues/21
Description: Build static library in addition to shared library

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,6 @@
 cmake_minimum_required(VERSION 3.1.0)
 project(mad VERSION 0.16.4)
 
-option(BUILD_SHARED_LIBS "Build dynamic library" ON)
-
 # The library SOVERSION. This is set to 0 for backward compatibility.
 # The general policy is that minor versions of the library (e.g., 0.16.1,
 # 0.16.2) don't constitute a major ABI breakage. Major versions (e.g., 0.17,
@@ -16,7 +14,7 @@ include(CheckTypeSize)
 # Build
 #
 
-add_library(mad
+set(MAD_SOURCES
     bit.c
     decoder.c
     fixed.c
@@ -29,15 +27,23 @@ add_library(mad
     timer.c
     version.c
 )
-target_include_directories(mad PUBLIC
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
-)
 
-if(WIN32 AND BUILD_SHARED_LIBS)
-    set_target_properties(mad PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
-endif()
+# Define both targets explicitly
+add_library(mad SHARED ${MAD_SOURCES})
+add_library(mad-static STATIC ${MAD_SOURCES})
+
+# Ensure the static library is named libmad.a
+set_target_properties(mad-static PROPERTIES OUTPUT_NAME mad)
+
+set(ALL_MAD_TARGETS mad mad-static)
+
+foreach(t ${ALL_MAD_TARGETS})
+    target_include_directories(${t} PUBLIC
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
+        $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+        $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+    )
+endforeach()
 
 set_target_properties(mad PROPERTIES
   VERSION ${CMAKE_PROJECT_VERSION}
@@ -51,10 +57,10 @@ set_target_properties(mad PROPERTIES
 option(OPTIMIZE "Optimize for SPEED (default) or ACCURACY" SPEED)
 if(OPTIMIZE STREQUAL "SPEED")
   message(STATUS "Optimizing for speed over accuracy.")
-  target_compile_definitions(mad PRIVATE OPT_SPEED)
+  set(OPT_DEF OPT_SPEED)
 else()
   message(STATUS "Optimizing for accuracy over speed.")
-  target_compile_definitions(mad PRIVATE OPT_ACCURACY)
+  set(OPT_DEF OPT_ACCURACY)
 endif()
 
 option(ASO "Enable CPU Architecture Specific Optimizations (x86, ARM, and MIPS only)" ON)
@@ -65,21 +71,22 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "
   message(STATUS "Using x86 fixed point math")
   option (FPM_INTEL "x86 fixed point math" ON)
   if(ASO)
-    target_compile_definitions(mad PRIVATE ASO_ZEROCHECK)
+    list(APPEND MAD_CONFIG_DEFS ASO_ZEROCHECK)
   endif()
 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES ".*(arm|ARM).*")
   message(STATUS "Using ARM fixed point math")
   option (FPM_ARM "ARM fixed point math" ON)
   if(ASO)
     enable_language(ASM)
-    target_compile_definitions(mad PRIVATE ASO_INTERLEAVE1 ASO_IMDCT)
+    list(APPEND MAD_CONFIG_DEFS ASO_INTERLEAVE1 ASO_IMDCT)
     target_sources(mad PRIVATE imdct_l_arm.S)
+    target_sources(mad-static PRIVATE imdct_l_arm.S)
   endif()
 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES ".*(mips|MIPS).*")
   message(STATUS "Using MIPS fixed point math")
   option(FPM_MIPS "MIPS fixed point math" ON)
   if(ASO)
-    target_compile_definitions(mad PRIVATE ASO_INTERLEAVE2 ASO_ZEROCHECK)
+    list(APPEND MAD_CONFIG_DEFS ASO_INTERLEAVE2 ASO_ZEROCHECK)
   endif()
 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES ".*(sparc|SPARC).*")
   message(STATUS "Using SPARC fixed point math")
@@ -92,82 +99,57 @@ else()
   option(FPM_DEFAULT "Generic fixed-point math" ON)
 endif()
 
+# Initialize definition list with optimization choice
+list(APPEND MAD_CONFIG_DEFS ${OPT_DEF})
 
 check_type_size(int SIZEOF_INT BUILTIN_TYPES_ONLY LANGUAGE C)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/mad.h.in ${CMAKE_CURRENT_BINARY_DIR}/mad.h @ONLY)
 
 include(CheckIncludeFile)
-check_include_file(sys/types.h HAVE_SYS_TYPES_H)
-if(HAVE_SYS_TYPES_H)
-  target_compile_definitions(mad PRIVATE HAVE_SYS_TYPES_H)
-endif()
-
-check_include_file(sys/wait.h HAVE_SYS_WAIT_H)
-if(HAVE_SYS_WAIT_H)
-  target_compile_definitions(mad PRIVATE HAVE_SYS_WAIT_H)
-endif()
-
-check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
-if(HAVE_SYS_MMAN_H)
-  target_compile_definitions(mad PRIVATE HAVE_SYS_MMAN_H)
-endif()
-
-check_include_file(sys/stat.h HAVE_SYS_STAT_H)
-if(HAVE_SYS_STAT_H)
-  target_compile_definitions(mad PRIVATE HAVE_SYS_STAT_H)
-endif()
-
-check_include_file(unistd.h HAVE_UNISTD_H)
-if(HAVE_UNISTD_H)
-  target_compile_definitions(mad PRIVATE HAVE_UNISTD_H)
-endif()
-
-check_include_file(assert.h HAVE_ASSERT_H)
-if(HAVE_ASSERT_H)
-  target_compile_definitions(mad PRIVATE HAVE_ASSERT_H)
-endif()
+macro(mad_check_include file var)
+  check_include_file(${file} ${var})
+  if(${var})
+    list(APPEND MAD_CONFIG_DEFS ${var})
+  endif()
+endmacro()
 
-check_include_file(fcntl.h HAVE_FCNTL_H)
-if(HAVE_FCNTL_H)
-  target_compile_definitions(mad PRIVATE HAVE_FCNTL_H)
-endif()
-
-check_include_file(limits.h HAVE_LIMITS_H)
-if(HAVE_LIMITS_H)
-  target_compile_definitions(mad PRIVATE HAVE_LIMITS_H)
-endif()
+mad_check_include(sys/types.h HAVE_SYS_TYPES_H)
+mad_check_include(sys/wait.h HAVE_SYS_WAIT_H)
+mad_check_include(sys/mman.h HAVE_SYS_MMAN_H)
+mad_check_include(sys/stat.h HAVE_SYS_STAT_H)
+mad_check_include(unistd.h HAVE_UNISTD_H)
+mad_check_include(assert.h HAVE_ASSERT_H)
+mad_check_include(fcntl.h HAVE_FCNTL_H)
+mad_check_include(limits.h HAVE_LIMITS_H)
 
 include(CheckFunctionExists)
-check_function_exists(ftruncate HAVE_FTRUNCATE)
-if(HAVE_FTRUNCATE)
-  target_compile_definitions(mad PRIVATE HAVE_FTRUNCATE)
-endif()
-
-check_function_exists(pipe HAVE_PIPE)
-if(HAVE_PIPE)
-  target_compile_definitions(mad PRIVATE HAVE_PIPE)
-endif()
-
-check_function_exists(fork HAVE_FORK)
-if(HAVE_FORK)
-  target_compile_definitions(mad PRIVATE HAVE_FORK)
-endif()
+macro(mad_check_function func var)
+  check_function_exists(${func} ${var})
+  if(${var})
+    list(APPEND MAD_CONFIG_DEFS ${var})
+  endif()
+endmacro()
 
-check_function_exists(waitpid HAVE_WAITPID)
-if(HAVE_WAITPID)
-  target_compile_definitions(mad PRIVATE HAVE_WAITPID)
-endif()
+mad_check_function(ftruncate HAVE_FTRUNCATE)
+mad_check_function(pipe HAVE_PIPE)
+mad_check_function(fork HAVE_FORK)
+mad_check_function(waitpid HAVE_WAITPID)
 
 option(MADD_ASM "Enable if your MIPS CPU supports a 2-operand MADD instruction." OFF)
 if(MADD_ASM)
-  target_compile_definitions(mad PRIVATE HAVE_MADD_ASM)
+  list(APPEND MAD_CONFIG_DEFS HAVE_MADD_ASM)
 endif()
 
 option(MADD16_ASM "Enable if your MIPS CPU supports a 2-operand MADD16 instruction." OFF)
 if(MADD16_ASM)
-  target_compile_definitions(mad PRIVATE HAVE_MADD_ASM)
+  list(APPEND MAD_CONFIG_DEFS HAVE_MADD_ASM)
 endif()
 
+# Apply all collected definitions to both targets
+foreach(t ${ALL_MAD_TARGETS})
+  target_compile_definitions(${t} PRIVATE ${MAD_CONFIG_DEFS})
+endforeach()
+
 #
 # Example application
 #
@@ -186,7 +168,7 @@ endif()
 include(CMakePackageConfigHelpers)
 
 # Library files
-install(TARGETS mad
+install(TARGETS mad mad-static
   EXPORT madTargets
   ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
   LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
