summary refs log tree commit diff
path: root/pkgs/os-specific/linux/alsa-lib
diff options
context:
space:
mode:
authorNathaniel Baxter <nathaniel.baxter@gmail.com>2014-09-11 13:01:08 +1000
committerAristid Breitkreuz <aristidb@gmail.com>2014-10-04 14:48:58 +0200
commitab8ef63ff49dd6276f765cce10d88b3e5b86b837 (patch)
tree4fc7e1782324d7969a7e027e794b0caf2250ce3c /pkgs/os-specific/linux/alsa-lib
parent02c89b52d917431f3863d204d678442d3c90db7d (diff)
downloadnixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.tar
nixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.tar.gz
nixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.tar.bz2
nixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.tar.lz
nixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.tar.xz
nixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.tar.zst
nixpkgs-ab8ef63ff49dd6276f765cce10d88b3e5b86b837.zip
alsa: Add multilib plugin support via "libs" entry in asound config.
alsa: Remove unused $ALSA_PLUGIN_DIRS support.
Diffstat (limited to 'pkgs/os-specific/linux/alsa-lib')
-rw-r--r--pkgs/os-specific/linux/alsa-lib/alsa-plugin-conf-multilib.patch232
-rw-r--r--pkgs/os-specific/linux/alsa-lib/alsa-plugin-dirs.patch110
-rw-r--r--pkgs/os-specific/linux/alsa-lib/default.nix7
3 files changed, 233 insertions, 116 deletions
diff --git a/pkgs/os-specific/linux/alsa-lib/alsa-plugin-conf-multilib.patch b/pkgs/os-specific/linux/alsa-lib/alsa-plugin-conf-multilib.patch
new file mode 100644
index 00000000000..b17df9a492e
--- /dev/null
+++ b/pkgs/os-specific/linux/alsa-lib/alsa-plugin-conf-multilib.patch
@@ -0,0 +1,232 @@
+diff --git a/src/control/control.c b/src/control/control.c
+index d66ed75..42cecad 100644
+--- a/src/control/control.c
++++ b/src/control/control.c
+@@ -838,6 +838,10 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ #ifndef PIC
+ 	extern void *snd_control_open_symbols(void);
+ #endif
++
++	snd_config_t *libs = NULL;
++	const char *libs_lib = NULL;
++
+ 	if (snd_config_get_type(ctl_conf) != SND_CONFIG_TYPE_COMPOUND) {
+ 		if (name)
+ 			SNDERR("Invalid type for CTL %s definition", name);
+@@ -879,6 +883,19 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 					SNDERR("Invalid type for %s", id);
+ 					goto _err;
+ 				}
++
++				continue;
++			}
++			// Handle an array of extra libs.
++			if (strcmp(id, "libs") == 0) {
++				if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
++					SNDERR("Invalid type for libs definition in CTL %s definition",
++						str);
++					goto _err;
++				}
++
++				libs = n;
++
+ 				continue;
+ 			}
+ 			if (strcmp(id, "open") == 0) {
+@@ -903,7 +920,62 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 		open_name = buf;
+ 		sprintf(buf, "_snd_ctl_%s_open", str);
+ 	}
+-	if (!lib) {
++
++#ifndef PIC
++	snd_control_open_symbols();
++#endif
++
++	// Normal alsa behaviour when there is no libs array.
++	if (!libs) {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
++		}
++	}
++	// Handle libs array.
++	// Suppresses error messages if any function is loaded successfully.
++	else {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
++		}
++
++		if (!open_func) {
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				err = snd_config_get_string(n, &libs_lib);
++				if (err < 0) {
++					SNDERR("Invalid entry in CTL %s libs definition", str);
++					goto _err;
++				}
++
++				if (!open_func) {
++					open_func = snd_dlobj_cache_get(libs_lib, open_name,
++						SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 0);
++				}
++			}
++		}
++
++		// Print error messages.
++		if (!open_func) {
++			if (lib) {
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					lib, open_name);
++			}
++
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				snd_config_get_string(n, &libs_lib);
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					libs_lib, open_name);
++			}
++		}
++	}
++
++	// Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
++	if (!lib && (!libs || !libs_lib)) {
+ 		const char *const *build_in = build_in_ctls;
+ 		while (*build_in) {
+ 			if (!strcmp(*build_in, str))
+@@ -919,12 +991,11 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
+ 			lib = buf1;
+ 			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
+ 		}
+-	}
+-#ifndef PIC
+-	snd_control_open_symbols();
+-#endif
+-	open_func = snd_dlobj_cache_get(lib, open_name,
++
++		open_func = snd_dlobj_cache_get(lib, open_name,
+ 			SND_DLSYM_VERSION(SND_CONTROL_DLSYM_VERSION), 1);
++	}
++
+ 	if (open_func) {
+ 		err = open_func(ctlp, name, ctl_root, ctl_conf, mode);
+ 		if (err >= 0) {
+diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
+index 2e24338..7f489f4 100644
+--- a/src/pcm/pcm.c
++++ b/src/pcm/pcm.c
+@@ -2116,6 +2116,10 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ #ifndef PIC
+ 	extern void *snd_pcm_open_symbols(void);
+ #endif
++
++	snd_config_t *libs = NULL;
++	const char *libs_lib = NULL;
++
+ 	if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
+ 		char *val;
+ 		id = NULL;
+@@ -2160,6 +2164,19 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 					SNDERR("Invalid type for %s", id);
+ 					goto _err;
+ 				}
++
++				continue;
++			}
++			// Handle an array of extra libs.
++			if (strcmp(id, "libs") == 0) {
++				if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
++					SNDERR("Invalid type for libs definition in PCM %s definition",
++						str);
++					goto _err;
++				}
++
++				libs = n;
++
+ 				continue;
+ 			}
+ 			if (strcmp(id, "open") == 0) {
+@@ -2184,7 +2201,62 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 		open_name = buf;
+ 		sprintf(buf, "_snd_pcm_%s_open", str);
+ 	}
+-	if (!lib) {
++
++#ifndef PIC
++	snd_pcm_open_symbols();	/* this call is for static linking only */
++#endif
++
++	// Normal alsa behaviour when there is no libs array.
++	if (!libs) {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
++		}
++	}
++	// Handle libs array.
++	// Suppresses error messages if any function is loaded successfully.
++	else {
++		if (lib) {
++			open_func = snd_dlobj_cache_get(lib, open_name,
++				SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
++		}
++
++		if (!open_func) {
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				err = snd_config_get_string(n, &libs_lib);
++				if (err < 0) {
++					SNDERR("Invalid entry in PCM %s libs definition", str);
++					goto _err;
++				}
++
++				if (!open_func) {
++					open_func = snd_dlobj_cache_get(libs_lib, open_name,
++						SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 0);
++				}
++			}
++		}
++
++		// Print error messages.
++		if (!open_func) {
++			if (lib) {
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					lib, open_name);
++			}
++
++			snd_config_for_each(i, next, libs) {
++				snd_config_t *n = snd_config_iterator_entry(i);
++
++				snd_config_get_string(n, &libs_lib);
++				SNDERR("Either %s cannot be opened or %s was not defined inside",
++					libs_lib, open_name);
++			}
++		}
++	}
++
++	// Look in ALSA_PLUGIN_DIR iff we found nowhere else to look.
++	if (!lib && (!libs || !libs_lib)) {
+ 		const char *const *build_in = build_in_pcms;
+ 		while (*build_in) {
+ 			if (!strcmp(*build_in, str))
+@@ -2200,12 +2272,11 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
+ 			lib = buf1;
+ 			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
+ 		}
+-	}
+-#ifndef PIC
+-	snd_pcm_open_symbols();	/* this call is for static linking only */
+-#endif
+-	open_func = snd_dlobj_cache_get(lib, open_name,
++
++		open_func = snd_dlobj_cache_get(lib, open_name,
+ 			SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
++	}
++
+ 	if (open_func) {
+ 		err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
+ 		if (err >= 0) {
diff --git a/pkgs/os-specific/linux/alsa-lib/alsa-plugin-dirs.patch b/pkgs/os-specific/linux/alsa-lib/alsa-plugin-dirs.patch
deleted file mode 100644
index 3cee02aa0cd..00000000000
--- a/pkgs/os-specific/linux/alsa-lib/alsa-plugin-dirs.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
-index 74d1d1a..17ffb12 100644
---- a/src/pcm/pcm.c
-+++ b/src/pcm/pcm.c
-@@ -2042,6 +2042,19 @@ static const char *const build_in_pcms[] = {
- 	NULL
- };
- 
-+
-+// helper funcion used below
-+int file_exists(const char * filename)
-+{
-+	FILE * file;
-+	if (file = fopen(filename, "r"))
-+	{
-+		fclose(file);
-+		return 1;
-+	}
-+	return 0;
-+}
-+
- static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
- 			     snd_config_t *pcm_root, snd_config_t *pcm_conf,
- 			     snd_pcm_stream_t stream, int mode)
-@@ -2141,8 +2154,38 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
- 				err = -ENOMEM;
- 				goto _err;
- 			}
--			lib = buf1;
- 			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
-+			if (!file_exists(buf1)){
-+				// try to locate plugin in one of ALSA_PLUGIN_DIRS which is colon separated list of paths
-+				char * pdirs = getenv("ALSA_PLUGIN_DIRS");
-+
-+				if (pdirs){ // env var set?
-+					char * saveptr;
-+					while (1) {
-+						char * dir_tok = strtok_r(pdirs, "::::", &saveptr); // "::::" to work around bug in glibc and -O2 ? ":" seems to cause a segfault
-+						if (dir_tok == NULL)
-+                            break;
-+						char * so_file = malloc(strlen(str) + strlen(dir_tok) + 32);
-+						if (so_file == NULL) {
-+							err = -ENOMEM;
-+							goto _err;
-+						}
-+
-+						sprintf(so_file, "%s/libasound_module_pcm_%s.so", dir_tok, str);
-+
-+						if (file_exists(so_file)){
-+
-+							free(buf1);
-+							buf1 = so_file;
-+							break;
-+						} else {
-+							free (so_file);
-+						}
-+						pdirs = NULL;
-+					}
-+				}
-+			}
-+			lib = buf1;
- 		}
- 	}
- #ifndef PIC
-
-
-diff --git a/src/control/control.c b/src/control/control.c
-index c090797..137fe57 100644
---- a/src/control/control.c
-+++ b/src/control/control.c
-@@ -854,8 +854,38 @@ static int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
- 				err = -ENOMEM;
- 				goto _err;
- 			}
-+			sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
-+			if (!file_exists(buf1)){
-+				// try to locate plugin in one of ALSA_PLUGIN_DIRS which is colon separated list of paths
-+				char * pdirs = getenv("ALSA_PLUGIN_DIRS");
-+
-+				if (pdirs){ // env var set?
-+					char * saveptr;
-+					while (1) {
-+						char * dir_tok = strtok_r(pdirs, "::::", &saveptr); // "::::" to work around bug in glibc and -O2 ? ":" seems to cause a segfault
-+						if (dir_tok == NULL)
-+                            break;
-+						char * so_file = malloc(strlen(str) + strlen(dir_tok) + 32);
-+						if (so_file == NULL) {
-+							err = -ENOMEM;
-+							goto _err;
-+						}
-+
-+						sprintf(so_file, "%s/libasound_module_ctl_%s.so", dir_tok, str);
-+
-+						if (file_exists(so_file)){
-+
-+							free(buf1);
-+							buf1 = so_file;
-+							break;
-+						} else {
-+							free (so_file);
-+						}
-+						pdirs = NULL;
-+					}
-+				}
-+			}
- 			lib = buf1;
--			sprintf(buf1, "%s/libasound_module_ctl_%s.so", ALSA_PLUGIN_DIR, str);
- 		}
- 	}
- #ifndef PIC
diff --git a/pkgs/os-specific/linux/alsa-lib/default.nix b/pkgs/os-specific/linux/alsa-lib/default.nix
index f46e54448b9..41abf488673 100644
--- a/pkgs/os-specific/linux/alsa-lib/default.nix
+++ b/pkgs/os-specific/linux/alsa-lib/default.nix
@@ -12,12 +12,7 @@ stdenv.mkDerivation rec {
   };
 
   patches = [
-    /* allow specifying alternatives alsa plugin locations using
-       export ALSA_PLUGIN_DIRS=$(nix-build -A alsaPlugins)/lib/alsa-lib
-       This patch should be improved:
-       See http://thread.gmane.org/gmane.linux.distributions.nixos/3435
-    */
-    ./alsa-plugin-dirs.patch
+    ./alsa-plugin-conf-multilib.patch
   ];
 
   # Fix pcm.h file in order to prevent some compilation bugs