Skip to content

Commit db470bb

Browse files
hefroySergeyRyabinin
authored andcommitted
Fix template class instantiation
- For Windows DLL, export definition of template class instantiation directly in the header using __declspec(dllexport). - For other builds (including Windows static lib), declare as extern in the header and define in the cpp. This change is required to fix 'multiple definition of typeinfo' linker errors seen with some compilers, e.g. GCC for 32-bit armhf arm-linux-gnueabihf-gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1).
1 parent b3f8d3d commit db470bb

File tree

8 files changed

+51
-11
lines changed

8 files changed

+51
-11
lines changed

src/aws-cpp-sdk-core/include/aws/core/Core_EXPORTS.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818
#else // AWS_CORE_EXPORTS
1919
#define AWS_CORE_API __declspec(dllimport)
2020
#endif // AWS_CORE_EXPORTS
21+
#define AWS_CORE_EXTERN
2122
#else // USE_IMPORT_EXPORT
2223
#define AWS_CORE_API
24+
#define AWS_CORE_EXTERN extern
2325
#endif // USE_IMPORT_EXPORT
2426
#define AWS_CORE_LOCAL
2527
#else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (_WIN32)
2628
#define AWS_CORE_API
29+
#define AWS_CORE_EXTERN extern
2730
#if __GNUC__ >= 4
2831
#define AWS_CORE_LOCAL __attribute__((visibility("hidden")))
2932
#else

src/aws-cpp-sdk-core/include/aws/core/endpoint/DefaultEndpointProvider.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,13 @@ namespace Aws
110110
BuiltInParametersT m_builtInParameters;
111111
};
112112

113-
// Export symbol from the DLL:
114-
template class AWS_CORE_API DefaultEndpointProvider<Aws::Client::GenericClientConfiguration</*HasEndpointDiscovery*/ true> >;
113+
/**
114+
* Export endpoint provider symbols for Windows DLL, otherwise declare as extern
115+
*/
116+
AWS_CORE_EXTERN template class AWS_CORE_API DefaultEndpointProvider<Aws::Client::GenericClientConfiguration<false>,
117+
Aws::Endpoint::BuiltInParameters,
118+
Aws::Endpoint::ClientContextParameters>;
119+
120+
AWS_CORE_EXTERN template class AWS_CORE_API DefaultEndpointProvider<Aws::Client::GenericClientConfiguration<true>>;
115121
} // namespace Endpoint
116122
} // namespace Aws

src/aws-cpp-sdk-core/include/aws/core/endpoint/EndpointProviderBase.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ namespace Aws
7070
virtual ResolveEndpointOutcome ResolveEndpoint(const EndpointParameters& endpointParameters) const = 0;
7171
};
7272

73-
// Export symbol from the DLL:
74-
template class AWS_CORE_API EndpointProviderBase<Aws::Client::GenericClientConfiguration</*HasEndpointDiscovery*/ true> >;
73+
/**
74+
* Export endpoint provider symbols for Windows DLL, otherwise declare as extern
75+
*/
76+
AWS_CORE_EXTERN template class AWS_CORE_API EndpointProviderBase<Aws::Client::GenericClientConfiguration<true>>;
7577
} // namespace Endpoint
7678
} // namespace Aws

src/aws-cpp-sdk-core/source/endpoint/DefaultEndpointProvider.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,17 @@ namespace Aws
1212
namespace Endpoint
1313
{
1414

15+
#ifndef AWS_CORE_EXPORTS // Except for Windows DLL
1516
/**
16-
* Export endpoint provider symbols from DLL
17+
* Instantiate endpoint providers
1718
*/
18-
template class AWS_CORE_API DefaultEndpointProvider<Aws::Client::GenericClientConfiguration<false>,
19+
template class DefaultEndpointProvider<Aws::Client::GenericClientConfiguration<false>,
1920
Aws::Endpoint::BuiltInParameters,
2021
Aws::Endpoint::ClientContextParameters>;
2122

23+
template class DefaultEndpointProvider<Aws::Client::GenericClientConfiguration<true>>;
24+
#endif
25+
2226
char CharToDec(const char c)
2327
{
2428
if(c >= '0' && c <= '9')

src/aws-cpp-sdk-core/source/endpoint/EndpointProviderBase.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ namespace Aws
99
{
1010
namespace Endpoint
1111
{
12+
#ifndef AWS_CORE_EXPORTS // Except for Windows DLL
1213
/**
13-
* Export endpoint provider symbols from DLL
14+
* Instantiate endpoint providers
1415
*/
15-
template class AWS_CORE_API EndpointProviderBase<Aws::Client::GenericClientConfiguration<false>,
16+
template class EndpointProviderBase<Aws::Client::GenericClientConfiguration<false>,
1617
Aws::Endpoint::BuiltInParameters,
1718
Aws::Endpoint::ClientContextParameters>;
1819

20+
template class EndpointProviderBase<Aws::Client::GenericClientConfiguration<true>>;
21+
#endif
1922
} // namespace Endpoint
2023
} // namespace Aws

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/ServiceExportHeader.vm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
\#else
2222
$define ${api} __declspec(dllimport)
2323
#endif /* AWS_${metadata.classNamePrefix.toUpperCase()}_EXPORTS */
24+
$define AWS_${metadata.classNamePrefix.toUpperCase()}_EXTERN
2425
\#else
2526
$define ${api}
27+
$define AWS_${metadata.classNamePrefix.toUpperCase()}_EXTERN extern
2628
#endif // USE_IMPORT_EXPORT
2729
\#else // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32)
2830
$define ${api}
31+
$define AWS_${metadata.classNamePrefix.toUpperCase()}_EXTERN extern
2932
#endif // defined (USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32)

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/endpoint/EndpointProviderHeader.vm

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#set($epContextClassName = "${metadata.classNamePrefix}ClientContextParameters")
88
#set($epBuiltInClassName = "${metadata.classNamePrefix}BuiltInParameters")
99
#set($exportMacro = "${CppViewHelper.computeExportValue($metadata.classNamePrefix)}")
10+
#set($externMacro = "AWS_${metadata.classNamePrefix.toUpperCase()}_EXTERN")
1011
#pragma once
1112
\#include <aws/${metadata.projectName}/${metadata.classNamePrefix}_EXPORTS.h>
1213
#if($serviceModel.metadata.serviceId == "S3" || $serviceModel.metadata.serviceId == "S3 Control")
@@ -101,12 +102,12 @@ using ${metadata.classNamePrefix}DefaultEpProviderBase =
101102
namespace Endpoint
102103
{
103104
/**
104-
* Export endpoint provider symbols from DLL
105+
* Export endpoint provider symbols for Windows DLL, otherwise declare as extern
105106
*/
106-
template class ${exportMacro}
107+
${externMacro} template class ${exportMacro}
107108
Aws::Endpoint::EndpointProviderBase<${serviceNamespace}::Endpoint::${metadata.classNamePrefix}ClientConfiguration, ${serviceNamespace}::Endpoint::${epBuiltInClassName}, ${serviceNamespace}::Endpoint::${epContextClassName}>;
108109

109-
template class ${exportMacro}
110+
${externMacro} template class ${exportMacro}
110111
Aws::Endpoint::DefaultEndpointProvider<${serviceNamespace}::Endpoint::${metadata.classNamePrefix}ClientConfiguration, ${serviceNamespace}::Endpoint::${epBuiltInClassName}, ${serviceNamespace}::Endpoint::${epContextClassName}>;
111112
} // namespace Endpoint
112113

tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/endpoint/EndpointProviderSource.vm

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,24 @@
1010

1111
namespace ${rootNamespace}
1212
{
13+
#if($serviceModel.metadata.serviceId == "S3" || $serviceModel.metadata.serviceId == "S3 Control" || $serviceModel.clientContextParams)
14+
#ifndef AWS_${metadata.classNamePrefix.toUpperCase()}_EXPORTS // Except for Windows DLL
15+
namespace Endpoint
16+
{
17+
/**
18+
* Instantiate endpoint providers
19+
*/
20+
template class Aws::Endpoint::EndpointProviderBase<${serviceNamespace}::Endpoint::${metadata.classNamePrefix}ClientConfiguration,
21+
${serviceNamespace}::Endpoint::${epBuiltInClassName},
22+
${serviceNamespace}::Endpoint::${epContextClassName}>;
23+
24+
template class Aws::Endpoint::DefaultEndpointProvider<${serviceNamespace}::Endpoint::${metadata.classNamePrefix}ClientConfiguration,
25+
${serviceNamespace}::Endpoint::${epBuiltInClassName},
26+
${serviceNamespace}::Endpoint::${epContextClassName}>;
27+
} // namespace Endpoint
28+
#endif
29+
30+
#end
1331
namespace ${serviceNamespace}
1432
{
1533
namespace Endpoint

0 commit comments

Comments
 (0)