mirror of
https://gitlab.freedesktop.org/pkg-config/pkg-config.git
synced 2026-04-21 07:40:53 +02:00
Merge branch 'cflags-private' into 'master'
Add Cflags.private field — required for linking on Windows Closes #38 See merge request pkg-config/pkg-config!13
This commit is contained in:
commit
55e41a9e4a
10 changed files with 185 additions and 59 deletions
|
|
@ -2,6 +2,7 @@ TESTS_ENVIRONMENT = PKG_CONFIG='$(TESTS_PKG_CONFIG)' $(TESTS_SHELL)
|
|||
|
||||
TESTS = \
|
||||
check-cflags \
|
||||
check-cflags-private \
|
||||
check-libs \
|
||||
check-mixed-flags \
|
||||
check-non-l-flags \
|
||||
|
|
@ -40,6 +41,7 @@ EXTRA_DIST = \
|
|||
requires-test.pc \
|
||||
public-dep.pc \
|
||||
private-dep.pc \
|
||||
private-cflags.pc \
|
||||
includedir.pc \
|
||||
missing-requires-private.pc \
|
||||
missing-requires.pc \
|
||||
|
|
|
|||
11
check/check-cflags-private
Executable file
11
check/check-cflags-private
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
. ${srcdir}/common
|
||||
|
||||
RESULT="-I/dummy/include"
|
||||
run_test --cflags private-cflags
|
||||
|
||||
RESULT="-DDUMMY_STATIC=1 $RESULT"
|
||||
run_test --static --cflags private-cflags
|
||||
7
check/private-cflags.pc
Normal file
7
check/private-cflags.pc
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
Name: Requires test package
|
||||
Description: Dummy pkgconfig test package for testing Cflags/Cflags.private
|
||||
Version: 1.0.0
|
||||
Libs: -L/dummy/lib -ldummy
|
||||
Cflags: -I/dummy/include
|
||||
Cflags.private: -DDUMMY_STATIC=1
|
||||
|
||||
10
main.c
10
main.c
|
|
@ -615,9 +615,15 @@ main (int argc, char **argv)
|
|||
debug_spew ("Error printing disabled\n");
|
||||
|
||||
if (want_static_lib_list)
|
||||
enable_private_libs();
|
||||
{
|
||||
enable_libs_private();
|
||||
enable_cflags_private();
|
||||
}
|
||||
else
|
||||
disable_private_libs();
|
||||
{
|
||||
disable_libs_private();
|
||||
disable_cflags_private();
|
||||
}
|
||||
|
||||
/* honor Requires.private if any Cflags are requested or any static
|
||||
* libs are requested */
|
||||
|
|
|
|||
145
parse.c
145
parse.c
|
|
@ -798,40 +798,9 @@ parse_libs_private (Package *pkg, const char *str, const char *path)
|
|||
}
|
||||
|
||||
static void
|
||||
parse_cflags (Package *pkg, const char *str, const char *path)
|
||||
_do_parse_cflags (Package *pkg, int argc, char **argv)
|
||||
{
|
||||
/* Strip out -I flags, put them in a separate list. */
|
||||
|
||||
char *trimmed;
|
||||
char **argv = NULL;
|
||||
int argc = 0;
|
||||
GError *error = NULL;
|
||||
int i;
|
||||
|
||||
if (pkg->cflags)
|
||||
{
|
||||
verbose_error ("Cflags field occurs twice in '%s'\n", path);
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
trimmed = trim_and_sub (pkg, str, path);
|
||||
|
||||
if (trimmed && *trimmed &&
|
||||
!g_shell_parse_argv (trimmed, &argc, &argv, &error))
|
||||
{
|
||||
verbose_error ("Couldn't parse Cflags field into an argument vector: %s\n",
|
||||
error ? error->message : "unknown");
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
{
|
||||
g_free (trimmed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < argc)
|
||||
|
|
@ -881,14 +850,103 @@ parse_cflags (Package *pkg, const char *str, const char *path)
|
|||
g_free (flag);
|
||||
|
||||
g_free (arg);
|
||||
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_cflags (Package *pkg, const char *str, const char *path)
|
||||
{
|
||||
/* Strip out -I flags, put them in a separate list. */
|
||||
|
||||
char *trimmed;
|
||||
char **argv = NULL;
|
||||
int argc = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
if (pkg->cflags)
|
||||
{
|
||||
verbose_error ("Cflags field occurs twice in '%s'\n", path);
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
trimmed = trim_and_sub (pkg, str, path);
|
||||
|
||||
if (trimmed && *trimmed &&
|
||||
!g_shell_parse_argv (trimmed, &argc, &argv, &error))
|
||||
{
|
||||
verbose_error ("Couldn't parse Cflags field into an argument vector: %s\n",
|
||||
error ? error->message : "unknown");
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
{
|
||||
g_free (trimmed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_do_parse_cflags(pkg, argc, argv);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_free (trimmed);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_cflags_private (Package *pkg, const char *str, const char *path)
|
||||
{
|
||||
/*
|
||||
List of private Cflags. Private Cflags are flags which
|
||||
are needed in the case of static linking. This can be required for
|
||||
example on platforms which require special attributes to be set
|
||||
for variables or functions which are defined in a shared library,
|
||||
as is the case for Microsoft Windows. Affected libraries will need
|
||||
to have ifdefs in their public headers to change the attributes
|
||||
depending on whether they are being linked to staticly or dynamicly.
|
||||
*/
|
||||
|
||||
char *trimmed;
|
||||
char **argv = NULL;
|
||||
int argc = 0;
|
||||
GError *error = NULL;
|
||||
|
||||
if (pkg->cflags_private_num)
|
||||
{
|
||||
verbose_error ("Cflags.private field occurs twice in '%s'\n", path);
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
trimmed = trim_and_sub (pkg, str, path);
|
||||
|
||||
if (trimmed && *trimmed &&
|
||||
!g_shell_parse_argv (trimmed, &argc, &argv, &error))
|
||||
{
|
||||
verbose_error ("Couldn't parse Cflags.private field into an argument vector: %s\n",
|
||||
error ? error->message : "unknown");
|
||||
if (parse_strict)
|
||||
exit (1);
|
||||
else
|
||||
{
|
||||
g_free (trimmed);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_do_parse_cflags(pkg, argc, argv);
|
||||
|
||||
g_strfreev (argv);
|
||||
g_free (trimmed);
|
||||
pkg->cflags_private_num++;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
parse_url (Package *pkg, const char *str, const char *path)
|
||||
{
|
||||
|
|
@ -906,8 +964,8 @@ parse_url (Package *pkg, const char *str, const char *path)
|
|||
|
||||
static void
|
||||
parse_line (Package *pkg, const char *untrimmed, const char *path,
|
||||
gboolean ignore_requires, gboolean ignore_private_libs,
|
||||
gboolean ignore_requires_private)
|
||||
gboolean ignore_requires, gboolean ignore_libs_private,
|
||||
gboolean ignore_requires_private, gboolean ignore_cflags_private)
|
||||
{
|
||||
char *str;
|
||||
char *p;
|
||||
|
|
@ -964,7 +1022,7 @@ parse_line (Package *pkg, const char *untrimmed, const char *path,
|
|||
}
|
||||
else if (strcmp (tag, "Libs.private") == 0)
|
||||
{
|
||||
if (!ignore_private_libs)
|
||||
if (!ignore_libs_private)
|
||||
parse_libs_private (pkg, p, path);
|
||||
}
|
||||
else if (strcmp (tag, "Libs") == 0)
|
||||
|
|
@ -972,6 +1030,12 @@ parse_line (Package *pkg, const char *untrimmed, const char *path,
|
|||
else if (strcmp (tag, "Cflags") == 0 ||
|
||||
strcmp (tag, "CFlags") == 0)
|
||||
parse_cflags (pkg, p, path);
|
||||
else if (strcmp (tag, "Cflags.private") == 0 ||
|
||||
strcmp (tag, "CFlags.private") == 0)
|
||||
{
|
||||
if (!ignore_cflags_private)
|
||||
parse_cflags_private (pkg, p, path);
|
||||
}
|
||||
else if (strcmp (tag, "Conflicts") == 0)
|
||||
parse_conflicts (pkg, p, path);
|
||||
else if (strcmp (tag, "URL") == 0)
|
||||
|
|
@ -1088,8 +1152,9 @@ parse_line (Package *pkg, const char *untrimmed, const char *path,
|
|||
Package*
|
||||
parse_package_file (const char *key, const char *path,
|
||||
gboolean ignore_requires,
|
||||
gboolean ignore_private_libs,
|
||||
gboolean ignore_requires_private)
|
||||
gboolean ignore_libs_private,
|
||||
gboolean ignore_requires_private,
|
||||
gboolean ignore_cflags_private)
|
||||
{
|
||||
FILE *f;
|
||||
Package *pkg;
|
||||
|
|
@ -1133,8 +1198,8 @@ parse_package_file (const char *key, const char *path,
|
|||
{
|
||||
one_line = TRUE;
|
||||
|
||||
parse_line (pkg, str->str, path, ignore_requires, ignore_private_libs,
|
||||
ignore_requires_private);
|
||||
parse_line (pkg, str->str, path, ignore_requires, ignore_libs_private,
|
||||
ignore_requires_private, ignore_cflags_private);
|
||||
|
||||
g_string_truncate (str, 0);
|
||||
}
|
||||
|
|
|
|||
5
parse.h
5
parse.h
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
Package *parse_package_file (const char *key, const char *path,
|
||||
gboolean ignore_requires,
|
||||
gboolean ignore_private_libs,
|
||||
gboolean ignore_requires_private);
|
||||
gboolean ignore_libs_private,
|
||||
gboolean ignore_requires_private,
|
||||
gboolean ignore_cflags_private);
|
||||
|
||||
GList *parse_module_list (Package *pkg, const char *str, const char *path);
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,13 @@ Libs: -L${libdir} -lfoo</pre>
|
|||
libraries support <tt>pkg-config</tt>, they should be added to
|
||||
<tt>Requires</tt> or <tt>Requires.private</tt>.</li>
|
||||
|
||||
<li><b>Cflags.private</b>: The compiler flags specific to the static version
|
||||
of your package. This may be required if your public headers need to change
|
||||
according to linkage mode, as is for example the case on Microsoft Windows
|
||||
if a library exposes a variable.
|
||||
Don't add any flags for required packages supporting <tt>pkg-config</tt>;
|
||||
<tt>pkg-config</tt> will add those automatically.</li>
|
||||
|
||||
<li><b>Libs</b>: The link flags specific to this package and any required
|
||||
libraries that don't support <tt>pkg-config</tt>. The same rule as
|
||||
<tt>Cflags</tt> applies here.</li>
|
||||
|
|
@ -186,8 +193,9 @@ includedir=${prefix}/include
|
|||
Cflags: -I${includedir}/foo</pre>
|
||||
|
||||
<p>The most important <tt>pkg-config</tt> metadata fields are
|
||||
<tt>Requires</tt>, <tt>Requires.private</tt>, <tt>Cflags</tt>, <tt>Libs</tt>
|
||||
and <tt>Libs.private</tt>. They will define the metadata used by external
|
||||
<tt>Requires</tt>, <tt>Requires.private</tt>, <tt>Cflags</tt>, <tt>Cflags.private</tt>
|
||||
<tt>Libs</tt> and <tt>Libs.private</tt>.
|
||||
They will define the metadata used by external
|
||||
projects to compile and link with the library.</p>
|
||||
|
||||
<p><tt>Requires</tt> and <tt>Requires.private</tt> define other modules
|
||||
|
|
@ -214,9 +222,9 @@ Cflags: -I${includedir}/foo</pre>
|
|||
additional direct dependency.</p>
|
||||
|
||||
<p>Finally, the <tt>Cflags</tt> contains the compiler flags for using the
|
||||
library. Unlike the <tt>Libs</tt> field, there is not a private variant of
|
||||
<tt>Cflags</tt>. This is because the data types and macro definitions are
|
||||
needed regardless of the linking scenario.</p>
|
||||
library. <tt>Cflags.private</tt> contain compiler flags specific to only the
|
||||
static version of the library; they will be used in addition to the regular
|
||||
<tt>Cflags</tt> if <tt>--static</tt> is set.</p>
|
||||
|
||||
<h2><a name="using">Using pkg-config files</a></h2>
|
||||
|
||||
|
|
|
|||
|
|
@ -629,6 +629,14 @@ installed.
|
|||
This line should list the compile flags specific to your package.
|
||||
Don't add any flags for required packages; \fIpkg-config\fP will
|
||||
add those automatically.
|
||||
.TP
|
||||
.I "Cflags.private:"
|
||||
This line should list the compile flags specific to the static version
|
||||
of your package. This may be required if your public headers need to change
|
||||
according to linkage mode, as is for example the case on Microsoft Windows
|
||||
if a library exposes a variable.
|
||||
Don't add any flags for required packages; \fIpkg-config\fP will
|
||||
add those automatically.
|
||||
.\"
|
||||
.SH AUTHOR
|
||||
|
||||
|
|
|
|||
31
pkg.c
31
pkg.c
|
|
@ -49,7 +49,8 @@ static GList *search_dirs = NULL;
|
|||
gboolean disable_uninstalled = FALSE;
|
||||
gboolean ignore_requires = FALSE;
|
||||
gboolean ignore_requires_private = TRUE;
|
||||
gboolean ignore_private_libs = TRUE;
|
||||
gboolean ignore_libs_private = TRUE;
|
||||
gboolean ignore_cflags_private = TRUE;
|
||||
|
||||
void
|
||||
add_search_dir (const char *path)
|
||||
|
|
@ -300,7 +301,8 @@ internal_get_package (const char *name, gboolean warn)
|
|||
|
||||
debug_spew ("Reading '%s' from file '%s'\n", name, location);
|
||||
pkg = parse_package_file (key, location, ignore_requires,
|
||||
ignore_private_libs, ignore_requires_private);
|
||||
ignore_libs_private, ignore_requires_private,
|
||||
ignore_cflags_private);
|
||||
g_free (key);
|
||||
|
||||
if (pkg != NULL && strstr (location, "uninstalled.pc"))
|
||||
|
|
@ -950,7 +952,7 @@ packages_get_flags (GList *pkgs, FlagType flags)
|
|||
}
|
||||
if (flags & LIBS_L)
|
||||
{
|
||||
cur = get_multi_merged (pkgs, LIBS_L, TRUE, !ignore_private_libs);
|
||||
cur = get_multi_merged (pkgs, LIBS_L, TRUE, !ignore_libs_private);
|
||||
debug_spew ("adding LIBS_L string \"%s\"\n", cur);
|
||||
g_string_append (str, cur);
|
||||
g_free (cur);
|
||||
|
|
@ -958,7 +960,7 @@ packages_get_flags (GList *pkgs, FlagType flags)
|
|||
if (flags & (LIBS_OTHER | LIBS_l))
|
||||
{
|
||||
cur = get_multi_merged (pkgs, flags & (LIBS_OTHER | LIBS_l), FALSE,
|
||||
!ignore_private_libs);
|
||||
!ignore_libs_private);
|
||||
debug_spew ("adding LIBS_OTHER | LIBS_l string \"%s\"\n", cur);
|
||||
g_string_append (str, cur);
|
||||
g_free (cur);
|
||||
|
|
@ -1181,6 +1183,7 @@ print_package_list (void)
|
|||
|
||||
ignore_requires = TRUE;
|
||||
ignore_requires_private = TRUE;
|
||||
ignore_cflags_private = TRUE;
|
||||
|
||||
/* Add the packages to a pointer array and sort by pkg->key first, to give
|
||||
* deterministic output. While doing that, work out the maximum key length
|
||||
|
|
@ -1212,15 +1215,15 @@ print_package_list (void)
|
|||
}
|
||||
|
||||
void
|
||||
enable_private_libs(void)
|
||||
enable_libs_private(void)
|
||||
{
|
||||
ignore_private_libs = FALSE;
|
||||
ignore_libs_private = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
disable_private_libs(void)
|
||||
disable_libs_private(void)
|
||||
{
|
||||
ignore_private_libs = TRUE;
|
||||
ignore_libs_private = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -1246,3 +1249,15 @@ disable_requires_private(void)
|
|||
{
|
||||
ignore_requires_private = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
enable_cflags_private(void)
|
||||
{
|
||||
ignore_cflags_private = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
disable_cflags_private(void)
|
||||
{
|
||||
ignore_cflags_private = TRUE;
|
||||
}
|
||||
|
|
|
|||
7
pkg.h
7
pkg.h
|
|
@ -84,6 +84,7 @@ struct Package_
|
|||
int path_position; /* used to order packages by position in path of their .pc file, lower number means earlier in path */
|
||||
int libs_num; /* Number of times the "Libs" header has been seen */
|
||||
int libs_private_num; /* Number of times the "Libs.private" header has been seen */
|
||||
int cflags_private_num; /* Number of times the "Cflags.private" header has been seen */
|
||||
char *orig_prefix; /* original prefix value before redefinition */
|
||||
};
|
||||
|
||||
|
|
@ -116,12 +117,14 @@ void verbose_error (const char *format, ...);
|
|||
|
||||
gboolean name_ends_in_uninstalled (const char *str);
|
||||
|
||||
void enable_private_libs(void);
|
||||
void disable_private_libs(void);
|
||||
void enable_libs_private(void);
|
||||
void disable_libs_private(void);
|
||||
void enable_requires(void);
|
||||
void disable_requires(void);
|
||||
void enable_requires_private(void);
|
||||
void disable_requires_private(void);
|
||||
void enable_cflags_private(void);
|
||||
void disable_cflags_private(void);
|
||||
|
||||
/* If TRUE, do not automatically prefer uninstalled versions */
|
||||
extern gboolean disable_uninstalled;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue