module map help - duplicate symbol definitions

I’m trying to create a module map, but I keep getting duplicate symbol errors for the same source line. What does this mean?

For example:

orbis-clang -c -I"D:\usr\local\psp2\ORBIS SDKs\2.000_pre_mod" -fmodules -fcxx-modules -fmodules-cache-path=./cache_path-o target_include_common_fios2_srcfios2_debug_h.o target/include_common/fios2/srcfios2_debug_h.cpp

In file included from target/include_common/fios2/srcfios2_debug_h.cpp:1:

In file included from D:\usr\local\psp2\ORBIS SDKs\2.000_pre_mod/target/include…/include_common/fios2/fios2_debug.h:13:

D:\usr\local\psp2\ORBIS SDKs\2.000_pre_mod/target/include…/include_common/fios2/fios2_types.h:153:14: error:

redefinition of ‘SceFiosOpFlags’

typedef enum SceFiosOpFlags

^

D:\usr\local\psp2\ORBIS SDKs\2.000_pre_mod/target/include…/include_common/fios2/fios2_types.h:153:14: note: previous

definition is here

typedef enum SceFiosOpFlags

^

Thanks.

-John

You can use -fdiagnostics-show-note-include-stack to help debug this sort of thing. It is likely because a header is being picked up through a module, but also through a regular include. E.g. your header file might be getting pulled into a module without being declared as such in the module map; it will thus be pulled into the module, but clang won’t know to grab the module when it sees an include of the header, so you can end up simultaneously having the header #include’d but also having it imported through the module.

– Sean Silva

-fdiagnostics-show-note-include-stack didn’t produce any additional messages.

Basically I have the case where I have an umbrella header in the top-level include directory, and the sub headers in a subdirectory:

fios2.h

fios2/fios2_file1.h

fios2/fios2_file2.h // etc.

fios2/subdir/fios2_file3.h // etc.

In the map:

module ps4 {

// …

module fios2_impl {

umbrella “…/include_common/fios2”

export *

}

module fios2 {

header “…/include_common/fios2.h”

export *

}

}

I also tried:

module ps4 {

// …

module fios2_impl {

header “…/include_common/fios2.h”

umbrella “…/include_common/fios2”

export *

}

}

All the headers involved are accounted for in the module map.

The error message only occurs when I include one of the sub header files in a stub C++ source file from my test bed, i.e.:

#include <fios2/fios2_file1.h>

Can I not include sub headers from a module with an umbrella?

If I can, there seems to be some problem, since all headers are accounted for.

If I can’t include sub headers, this might be a problem for users, as they might want to avoid the umbrella header.

Thanks.

-John

I also have problems if I just put all the headers in separate modules.

-fdiagnostics-show-note-include-stack didn’t produce any additional
messages.

You should see some additional notes, at least. If not, something very
weird is going on.

Basically I have the case where I have an umbrella header in the top-level
include directory, and the sub headers in a subdirectory:

fios2.h

fios2/fios2_file1.h

fios2/fios2_file2.h // etc.

fios2/subdir/fios2_file3.h // etc.

In the map:

module ps4 {

  // ...

  module fios2_impl {

    umbrella "../include_common/fios2"

Your module map file appears not to be in the directory containing the
headers (nor a parent directory of that directory). That won't work
very well; we won't necessarily find this module map file implicitly
when we see an include naming a file within it. Try adding a
-fmodule-map-file= command-line argument pointing at this file.

-fdiagnostics-show-note-include-stack didn’t produce any additional
messages.

Basically I have the case where I have an umbrella header in the top-level
include directory, and the sub headers in a subdirectory:

fios2.h

fios2/fios2_file1.h

fios2/fios2_file2.h // etc.

fios2/subdir/fios2_file3.h // etc.

In the map:

module ps4 {

  // ...

  module fios2_impl {

    umbrella "../include_common/fios2"

    export *

  }

  module fios2 {

    header "../include_common/fios2.h"

    export *

  }

}

I also tried:

module ps4 {

  // ...

  module fios2_impl {

    header "../include_common/fios2.h"

    umbrella "../include_common/fios2"

    export *

  }

}

All the headers involved are accounted for in the module map.

The error message only occurs when I include one of the sub header files
in a stub C++ source file from my test bed, i.e.:

#include <fios2/fios2_file1.h>

Can I not include sub headers from a module with an umbrella?

You should be able to. I have attached a zip file with a test. A #include
of the subheader of the umbrella pulls in the entire module.

-- Sean Silva

testumbrella.zip (1.63 KB)

Richard,

Thanks, Richard. That is indeed the case. Because of the issue of finding the module map, I moved the map into the main include directory, and these (fios) headers are in a different directory. Because it probably does include some stuff from the main directory, it finds the module map, but perhaps get confused because there's no module map.

A quick solution is to move the module map up to a common parent, because of a few circular references, but then I have to use the -fmodule-map-file option to tell Clang where it is. It seems Clang used to walk up the path until it finds a module map. Does it not still do that? It seems if I only include a single include/sys file it still finds it, doesn't it, without a module map in include/sys? Having to include that option is problematic, but worst case, we might hard code it into our version of the compiler, as we're already doing that with the include paths for our three include directories.

But I'm going to try to refactor the module maps to isolate the few circular references, so I can have separate module maps in each of the three include directories.

Thanks again for helping me out.

-John

Richard,

Thanks, Richard. That is indeed the case. Because of the issue of
finding the module map, I moved the map into the main include directory,
and these (fios) headers are in a different directory. Because it probably
does include some stuff from the main directory, it finds the module map,
but perhaps get confused because there's no module map.

A quick solution is to move the module map up to a common parent, because
of a few circular references, but then I have to use the -fmodule-map-file
option to tell Clang where it is. It seems Clang used to walk up the path
until it finds a module map. Does it not still do that?

It does, but it only walks parent directories, and this module map file
appears to not have been in a parent directory of the relevant files (the
'header' lines start '../'). We should handle that case better; see PR19501.

It seems if I only include a single include/sys file it still finds it,