Difference between prefixed EXPORT_NAME and NAMESPACE?

What is the difference between setting scope of an exported target directly the EXPORT_NAME vs setting the scope of an exported target with NAMESPACE?

For example, let’s say I have a target named proj_target which I want to be consumed as Proj::Target. In the first variant I set the scope via the NAMESPACE argument in the export sets. This is what is normally advertised in CMake tutorials, so it looks something like this:

add_library(Proj::Target ALIAS proj_target)
set_target_properties(proj_target PROPERTIES EXPORT_NAME Target)
install(TARGETS proj_target EXPORT proj-export-set DESTINATION ...)
export(EXPORT proj-export-set NAMESPACE Proj)
install(EXPORT proj-export-set NAMESPACE Proj)

However, this means that targets with other scopes cannot be exported in the same export set proj-export-set. So one has to keep track of a different export sets per namespace. If I want several scopes, I find this restriction quite inconvenient because the target is defined in the same project after all. So I found that one can alternatively set the scope of the target in the EXPORT_NAME.

add_library(Proj::Target ALIAS proj_target)
set_target_properties(proj_target PROPERTIES EXPORT_NAME Proj::Target)
install(TARGETS proj_target EXPORT proj-export-set DESTINATION ...)
export(EXPORT proj-export-set)
install(EXPORT proj-export-set DESTINATION ...)

But I could not find any reference whether this usage is correct. I checked the two versions and they seem to generate the same targets file. So, here are my questions:

  • Is there anything fundamentally different on just setting the scope in the EXPORT_NAME directly? Is there any restriction them that one has to be aware of?
  • Is the NAMESPACE argument in the export sets doing something different than a string prefix?

Related:

I’m…not sure. I think it is just string manipulation. However, other things may want to use the namespace for other reasons (e.g., in VTK these things are controlled and the NAMESPACE is used to make in-project aliases of the same pattern as the exported targets). But for core CMake, it seems fine. Any additional behaviors CMake would want for the NAMESPACE argument would have to take this into account though.

AFAIK, no.

Prefer to use NAMESPACE rather than putting the namespace in the EXPORT_NAME. If and when issue 22687 eventually gets some attention, I’d expect that would attach some additional meaning and behavior to NAMESPACE, but not to EXPORT_NAME.

Thanks for your answers! I am just puzzled that I read two contradictory answers here:

[…] Any additional behaviors CMake would want for the NAMESPACE argument would have to take this into account though.

[…] I’d expect that would attach some additional meaning and behavior to NAMESPACE, but not to EXPORT_NAME.

So this is how I interpret this (please correct me if I am wrong): Prefixed namespaces in EXPORT_NAME is “blessed” by the current CMake specification but may not be the case in the future. A proposal like @craig.scott’s would need a new CMake policy to allow the change of that behavior.

It’s more like NAMESPACE today only has the “prepend to EXPORT_NAME”; it may gain more in the future. I don’t think it’s worth a policy as it is not changing behavior, only adding additional semantics to the (preferred) way of getting a desired result.

1 Like

Great, that clarifies the issue, thanks!