diff --git a/check/Makefile.am b/check/Makefile.am index 68c6d84312941a13277554b342e818b558aed563..618a90ad004e1da257acc5437701f29f704b73e0 100644 --- a/check/Makefile.am +++ b/check/Makefile.am @@ -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 \ diff --git a/check/check-cflags-private b/check/check-cflags-private new file mode 100755 index 0000000000000000000000000000000000000000..544f1d35c94e943258a99e6cf4bf5b7c4b7081f3 --- /dev/null +++ b/check/check-cflags-private @@ -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 diff --git a/check/private-cflags.pc b/check/private-cflags.pc new file mode 100644 index 0000000000000000000000000000000000000000..0cfbdfdaeea68b93f7bab775389d235c62be9feb --- /dev/null +++ b/check/private-cflags.pc @@ -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 + diff --git a/main.c b/main.c index cfebdba1ad538337246c1d57b5de6e053c433b7f..1ca3347da27be42f78dab40eebf484f3cb46e011 100644 --- a/main.c +++ b/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 */ diff --git a/parse.c b/parse.c index 6e9907c2a7562eb28ebe972a2773da00076ec0c6..75e016e1dddc3f1da059a36cba16589478200c3d 100644 --- a/parse.c +++ b/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); } diff --git a/parse.h b/parse.h index db1bf8629e85e0d940b377f9b9e7d156a917197d..93a3f95ccd7a14ac6409c227edbd3ceac25114e8 100644 --- a/parse.h +++ b/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); diff --git a/pkg-config-guide.html b/pkg-config-guide.html index c666fe5d69297252dea9e58431ca3d2373539fa3..79335ff46f14303599604dff5bd1dc372681f080 100644 --- a/pkg-config-guide.html +++ b/pkg-config-guide.html @@ -137,6 +137,13 @@ Libs: -L${libdir} -lfoo libraries support pkg-config, they should be added to Requires or Requires.private. +
The most important pkg-config metadata fields are - Requires, Requires.private, Cflags, Libs - and Libs.private. They will define the metadata used by external + Requires, Requires.private, Cflags, Cflags.private + Libs and Libs.private. + They will define the metadata used by external projects to compile and link with the library.
Requires and Requires.private define other modules @@ -214,9 +222,9 @@ Cflags: -I${includedir}/foo additional direct dependency.
Finally, the Cflags contains the compiler flags for using the - library. Unlike the Libs field, there is not a private variant of - Cflags. This is because the data types and macro definitions are - needed regardless of the linking scenario.
+ library. Cflags.private contain compiler flags specific to only the + static version of the library; they will be used in addition to the regular + Cflags if --static is set.