IMPORTED_LINK_INTERFACE_LANGUAGES property is ignored?

Hi,

A possible bug related to the IMPORTED_LINK_INTERFACE_LANGUAGES
property.

I created a very simple CMake script to show my issue, available here:

The test.c file referenced in the script is a dead simple example
source file, whose goal is only to call enough libxml2 functions for it
to be linked. I uploaded it there:

The libxml2 library is itself written in C, but has an optional
dependency on libicu, which is a C++ library with a C interface. In my
test case, the libxml2-config.cmake file provided by libxml2 is used,
and the libxml2 and dependencies have been statically compiled.

My problem is that the test.c will fail to link, as the compiler
complains about missing C++ symbols. Indeed, it is linked with gcc and
not g++, and the stdc++ library is not passed on the command line.

Note that my script sets the IMPORTED_LINK_INTERFACE_LANGUAGES property
to CXX on the LibXml2::LibXml2 library to try to force things, but this
property is already set on the libicu targets, that are linked as part
of the static build.

My expectation is that having IMPORTED_LINK_INTERFACE_LANGUAGES set to
CXX on an imported target would switch the compiler from gcc to g++,
but this does not seem to be the case.

Note that I also tried:
project(test LANGUAGES C CXX)

But this actually doesn’t change anything, and gcc will still be used
for linking. Besides, my project is C, my dependencies are C, so I
don’t want to add a dependency on C++ just to address a particular case.

Any ideas?

Cheers,
-Paul

Please trace through the libxml2-config.cmake code that calls add_library(LibXml2::LibXml2 ...). What kind of library target does it create?

IMPORTED_LINK_INTERFACE_LANGUAGES is meaningful only for STATIC IMPORTED library targets.

I uploaded the libxml2-config.cmake here:

It does:
add_library(LibXml2::LibXml2 UNKNOWN IMPORTED)

Note that FindICU.cmake (which is shipped as part of CMake) does this
too, and sets the IMPORTED_LINK_INTERFACE_LANGUAGES property as well,
and it fails there too.

The following example, which uses only scripts provided by CMake, shows
the exact same problem:

cmake_minimum_required(VERSION 3.16)
project(test LANGUAGES C)

set(BUILD_SHARED_LIBS OFF)

include(CMakeFindDependencyMacro)
find_dependency(ICU COMPONENTS data i18n uc)

add_executable(test test.c)
target_link_libraries(test ${ICU_LIBRARIES})
#include <unicode/ucnv.h>

int main(void)
{
ucnv_close(NULL);

return 0;
}

UNKNOWN is not STATIC, so IMPORTED_LINK_INTERFACE_LANGUAGES won’t be used.

Package configuration files come with the projects they describe, so that file should be able to specify the real type of the library: SHARED or STATIC.

Hi Brad,

Package configuration files come with the projects they describe

If you read my response carefully, I just gave you an example that does not depend on any package configuration file outside of CMake.

Please have a look at:

You will see that it does create a UNKNOWN IMPORTED library, and sets the IMPORTED_LINK_INTERFACE_LANGUAGES property to CXX. My expectation is that this should work.

See CMake Issue 18564 and related issues linked in its discussion.

Hi Brad,

What’s the way forward then?

Cheers,
-Paul

For libxml2, its libxml2-config.cmake file needs to be fixed as I described above.

This is primarily a problem in Find modules because we don’t know what kind of artifacts will be assigned to the imported targets. That’s what the CMake Issues I linked are about. See discussion in those issues about possible paths forward for CMake itself. However, AFAIK no one is working on them right now.

Projects can set the LINKER_LANGUAGE target property on a target that has C sources in order to force linking as CXX.