• A singleton based on the ACE_Singleton template class in a shared libra

    From Chuck Wanner@21:1/5 to All on Fri Dec 8 13:30:21 2017
    Hello,

    I am trying to port software from using ACE 5.8.2 to ACE 6.4.5. We were using Redhat 5.4. We are now using CentOS 7.4. The software builds a few shared libraries and executable. Everything built until trying to link the executable.

    One of my shared libraries declared a singleton using the ACE_Singleton Template.

    class MyLib_Export MyClass {
    friend class ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>;
    public:

    };

    // define the macro MYCLIENT to point to our MyClass Singleton
    typedef ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex> MyClassSingleton;
    #define MYCLIENT MyClassSingleton::instance()

    MYLIB_SINGLETON_DECLARE(ACE_Singleton, MyClass, ACE_Recursive_Thread_Mutex)

    When trying to perform the link to my executable, the following Link Error is generated:

    undefined reference to `ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>::instance()'

    I thought templates did not require to be exported, __attribute__((visibility(default))). The ACE Singleton template class does not have an export.

    I did check the contents of the new generate_export_file.pl tool. The contents of the export file for the MyLib did not change.

    I was hoping someone would recognize this error and know what I was doing wrong.

    Thank You,
    Chuck Wanner

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chuck Wanner@21:1/5 to Chuck Wanner on Wed Dec 13 14:21:12 2017
    On Friday, December 8, 2017 at 1:30:24 PM UTC-8, Chuck Wanner wrote:
    Hello,

    I am trying to port software from using ACE 5.8.2 to ACE 6.4.5. We were using Redhat 5.4. We are now using CentOS 7.4. The software builds a few shared libraries and executable. Everything built until trying to link the executable.

    One of my shared libraries declared a singleton using the ACE_Singleton Template.

    class MyLib_Export MyClass {
    friend class ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>;
    public:

    };

    // define the macro MYCLIENT to point to our MyClass Singleton
    typedef ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex> MyClassSingleton;
    #define MYCLIENT MyClassSingleton::instance()

    MYLIB_SINGLETON_DECLARE(ACE_Singleton, MyClass, ACE_Recursive_Thread_Mutex)

    When trying to perform the link to my executable, the following Link Error is generated:

    undefined reference to `ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>::instance()'

    I thought templates did not require to be exported, __attribute__((visibility(default))). The ACE Singleton template class does not have an export.

    I did check the contents of the new generate_export_file.pl tool. The contents of the export file for the MyLib did not change.

    I was hoping someone would recognize this error and know what I was doing wrong.

    Thank You,
    Chuck Wanner

    Hello,

    I have more information on my problem. Small sample code was generated to reproduce the problem.

    Version 6.4.5 of the ACE Library is being used. I personally downloaded the ACE 6.4.5 tar ball, built, and installed the ACE library. The same compiler is being used for the test code.

    The Linux Workstation is running CentOS Version 7.4.

    cat /etc/redhat-release
    CentOS Linux release 7.4.1708 (Core)

    The GNU compiler is version 4.8.5.
    g++ --version
    g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-16)
    Copyright (C) 2015 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    A testSingleton class was created that uses the ACE_Singleton class. The class was built as a shared library. I used the tool generate_export_file.pl to generate the export macros for the shared library. The main routine accesses the singleton
    class. When linking the main executable, the error “ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex>::instance is an undefined reference” is generated.

    Here is the sample code that has the problem:

    testSingleton.h:
    #ifndef _TESTSINGLETON_H
    #define _TESTSINGLETON_H

    #include <ace/Singleton.h>
    #include "testSingleton_export.h"

    class TestSingleton_Export testSingleton
    {
    public:
    testSingleton();

    ~testSingleton();

    void hello(void);
    };

    typedef ACE_Singleton <testSingleton, ACE_Recursive_Thread_Mutex> TESTSINGLETON;

    TESTSINGLETON_SINGLETON_DECLARE (ACE_Singleton, testSingleton, ACE_Recursive_Thread_Mutex)

    #define SHORTCUT TESTSINGLETON::instance()

    #endif /* _TESTSINGLETON_H */

    testSingleton.cpp:
    #include <stdio.h>
    #include "testSingleton.h"

    testSingleton::testSingleton()
    {
    }

    testSingleton::~testSingleton()
    {
    }

    void testSingleton::hello(void)
    {
    printf("Hello\n");
    }

    testSingleton_export.h:
    // -*- C++ -*-
    // Definition for Win32 Export directives.
    // This file is generated automatically by generate_export_file.pl -d TestSingleton
    // ------------------------------
    #ifndef TESTSINGLETON_EXPORT_H
    #define TESTSINGLETON_EXPORT_H

    #include "ace/config-all.h"

    #if defined (ACE_AS_STATIC_LIBS) && !defined (TESTSINGLETON_HAS_DLL)
    # define TESTSINGLETON_HAS_DLL 0
    #endif /* ACE_AS_STATIC_LIBS && TESTSINGLETON_HAS_DLL */

    #if !defined (TESTSINGLETON_HAS_DLL)
    # define TESTSINGLETON_HAS_DLL 1
    #endif /* ! TESTSINGLETON_HAS_DLL */

    #if defined (TESTSINGLETON_HAS_DLL) && (TESTSINGLETON_HAS_DLL == 1)
    # if defined (TESTSINGLETON_BUILD_DLL)
    # define TestSingleton_Export ACE_Proper_Export_Flag
    # define TESTSINGLETON_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T)
    # define TESTSINGLETON_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
    # else /* TESTSINGLETON_BUILD_DLL */
    # define TestSingleton_Export ACE_Proper_Import_Flag
    # define TESTSINGLETON_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T)
    # define TESTSINGLETON_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
    # endif /* TESTSINGLETON_BUILD_DLL */
    #else /* TESTSINGLETON_HAS_DLL == 1 */
    # define TestSingleton_Export
    # define TESTSINGLETON_SINGLETON_DECLARATION(T)
    # define TESTSINGLETON_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK)
    #endif /* TESTSINGLETON_HAS_DLL == 1 */

    // Set TESTSINGLETON_NTRACE = 0 to turn on library specific tracing even if
    // tracing is turned off for ACE.
    #if !defined (TESTSINGLETON_NTRACE)
    # if (ACE_NTRACE == 1)
    # define TESTSINGLETON_NTRACE 1
    # else /* (ACE_NTRACE == 1) */
    # define TESTSINGLETON_NTRACE 0
    # endif /* (ACE_NTRACE == 1) */
    #endif /* !TESTSINGLETON_NTRACE */

    #if (TESTSINGLETON_NTRACE == 1)
    # define TESTSINGLETON_TRACE(X)
    #else /* (TESTSINGLETON_NTRACE == 1) */
    # if !defined (ACE_HAS_TRACE)
    # define ACE_HAS_TRACE
    # endif /* ACE_HAS_TRACE */
    # define TESTSINGLETON_TRACE(X) ACE_TRACE_IMPL(X)
    # include "ace/Trace.h"
    #endif /* (TESTSINGLETON_NTRACE == 1) */

    #endif /* TESTSINGLETON_EXPORT_H */

    // End of auto generated file.

    main.cpp:
    #include <testSingleton.h>

    int main(int argc, char** argv)
    {
    int temp = argc;
    char ** temp_ptr = argv;
    temp++;
    temp_ptr++;

    SHORTCUT->hello();

    return 0;
    }

    I performed the following commands to build my source code:

    Command to build testSingleton.o:
    g++ -fvisibility=hidden -fvisibility-inlines-hidden -Wnon-virtual-dtor -O3 -ggdb -pthread -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -D_GNU_SOURCE -DTESTSINGLETON_BUILD_DLL -c -fPIC -o testSingleton.o testSingleton.cpp

    Command to build libTestSingleton.so:
    g++ -pthread -fPIC -shared -o libTestSingleton.so testSingleton.o -L/usr/local/lib -Wl,-R/usr/local/lib -Wl,--enable-new-dtags -ldl -lrt –lACE

    Command to build main.o:
    g++ -Wnon-virtual-dtor -O3 -ggdb -pthread -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -D_GNU_SOURCE -I. -fPIC -c -o main.o main.cpp

    Command to build main.out:
    g++ -L. -fPIC -Xlinker -rpath /usr/local/lib -Xlinker -rpath ./ -pthread main.o -lACE
    main.o: In function `main':
    /home/wanner/Templates/TestSingleton/main.cpp:11: undefined reference to `ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex>::instance()'
    /home/wanner/Templates/TestSingleton/main.cpp:11: undefined reference to `testSingleton::hello()'

    The test code is very similar the ACE_Utils::UUID_Generator class that uses the ACE Singleton class. Objdump was used to show the difference in the code generation. The UUID.o object has the ACE_Singleton code for the instance declared as part of
    the object. But the testSingleton.o object does not have any ACE_Singleton code for the instance of the ACE_Singleton declared.


    The testSingleton.o is very small, so the complete symbol table was provided. objdump -C -w -t testSingleton.o

    testSingleton.o: file format elf64-x86-64

    SYMBOL TABLE:
    0000000000000000 l df *ABS* 0000000000000000 testSingleton.cpp 0000000000000000 l d .text 0000000000000000 .text
    0000000000000000 l d .data 0000000000000000 .data
    0000000000000000 l d .bss 0000000000000000 .bss
    0000000000000000 l d .rodata.str1.1 0000000000000000 .rodata.str1.1 0000000000000000 l d .debug_info 0000000000000000 .debug_info 0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev 0000000000000000 l d .debug_loc 0000000000000000 .debug_loc 0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges 0000000000000000 l d .debug_line 0000000000000000 .debug_line 0000000000000000 l d .debug_str 0000000000000000 .debug_str 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
    0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l .rodata.str1.1 0000000000000000 .LC0
    0000000000000000 l d .comment 0000000000000000 .comment 0000000000000000 g F .text 0000000000000002 testSingleton::testSingleton() 0000000000000000 g F .text 0000000000000002 testSingleton::testSingleton() 0000000000000010 g F .text 0000000000000002 testSingleton::~testSingleton()
    0000000000000010 g F .text 0000000000000002 testSingleton::~testSingleton()
    0000000000000020 g F .text 000000000000000c testSingleton::hello() 0000000000000000 *UND* 0000000000000000 _GLOBAL_OFFSET_TABLE_ 0000000000000000 *UND* 0000000000000000 puts

    The objdump on the ACE UUID.o object. The UUID.o had large symbol table, so UUID’s symbol table was filtered on the symbol ACE_Singleton.
    objdump -C -w -t .shobj/UUID.o | grep ACE_Singleton
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED2Ev 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED2Ev
    0000000000000000 l d .gcc_except_table._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED2Ev 0000000000000000 .gcc_except_table._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED2Ev
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED0Ev 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED0Ev
    0000000000000000 l d .gcc_except_table._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED0Ev 0000000000000000 .gcc_except_table._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED0Ev
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE4dumpEv 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE4dumpEv
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexEC2Ev 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexEC2Ev
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE10instance_iEv 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE10instance_iEv
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE7cleanupEPv 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE7cleanupEPv
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE5closeEv 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE5closeEv
    0000000000000000 l d .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE8instanceEv 0000000000000000 .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE8instanceEv
    0000000000000000 l d .bss._ZZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE8instanceEvE4lock 0000000000000000 .bss._ZZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE8instanceEvE4lock
    0000000000000000 l d .rodata._ZTS13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE 0000000000000000 .rodata._ZTS13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE
    0000000000000000 l d .data.rel.ro._ZTI13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE 0000000000000000 .data.rel.ro._ZTI13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE
    0000000000000000 l d .data.rel.ro._ZTV13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE 0000000000000000 .data.rel.ro._ZTV13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE
    0000000000000000 l d .bss._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE10singleton_E 0000000000000000 .bss._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE10singleton_E
    0000000000000000 l .group 0000000000000000 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::~ACE_Singleton()
    0000000000000000 l .group 0000000000000000 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::ACE_Singleton()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED2Ev 0000000000000042 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::~ACE_Singleton()
    0000000000000000 w O .data.rel.ro._ZTV13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE 0000000000000028 vtable for ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED2Ev 0000000000000042 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::~ACE_Singleton()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexED0Ev 000000000000004a ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::~ACE_Singleton()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE4dumpEv 0000000000000002 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::dump()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexEC2Ev 000000000000003b ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::ACE_Singleton()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexEC2Ev 000000000000003b ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::ACE_Singleton()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE10instance_iEv 0000000000000008 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::instance_i()
    0000000000000000 u O .bss._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE10singleton_E 0000000000000008 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::singleton_
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE7cleanupEPv 0000000000000030 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::cleanup(void*)
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE5closeEv 000000000000002a ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::close()
    0000000000000000 w F .text._ZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE8instanceEv 0000000000000184 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::instance()
    0000000000000000 u O .bss._ZZN13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE8instanceEvE4lock 0000000000000008 ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>::instance()::lock
    0000000000000000 w O .rodata._ZTS13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE 0000000000000040 typeinfo name for ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>
    0000000000000000 w O .data.rel.ro._ZTI13ACE_SingletonIN9ACE_Utils14UUID_GeneratorE16ACE_Thread_MutexE 0000000000000018 typeinfo for ACE_Singleton<ACE_Utils::UUID_Generator, ACE_Thread_Mutex>

    I do not see what I am doing wrong. Why the compiler generated ACE_Singleton code for the UUID_Generator class, but not my class. Any ideas what I am doing wrong.

    Thank You,
    Chuck Wanner

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chuck Wanner@21:1/5 to Chuck Wanner on Thu Dec 14 12:39:42 2017
    On Friday, December 8, 2017 at 1:30:24 PM UTC-8, Chuck Wanner wrote:
    Hello,

    I am trying to port software from using ACE 5.8.2 to ACE 6.4.5. We were using Redhat 5.4. We are now using CentOS 7.4. The software builds a few shared libraries and executable. Everything built until trying to link the executable.

    One of my shared libraries declared a singleton using the ACE_Singleton Template.

    class MyLib_Export MyClass {
    friend class ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>;
    public:

    };

    // define the macro MYCLIENT to point to our MyClass Singleton
    typedef ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex> MyClassSingleton;
    #define MYCLIENT MyClassSingleton::instance()

    MYLIB_SINGLETON_DECLARE(ACE_Singleton, MyClass, ACE_Recursive_Thread_Mutex)

    When trying to perform the link to my executable, the following Link Error is generated:

    undefined reference to `ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>::instance()'

    I thought templates did not require to be exported, __attribute__((visibility(default))). The ACE Singleton template class does not have an export.

    I did check the contents of the new generate_export_file.pl tool. The contents of the export file for the MyLib did not change.

    I was hoping someone would recognize this error and know what I was doing wrong.

    Thank You,
    Chuck Wanner

    A Minor Update to my last post. I forgot the -lTestSingleton on the command to build main.out. The updated command and output are below.

    Command to build main.out:
    g++ -L. -fPIC -Xlinker -rpath /usr/local/lib -Xlinker -rpath ./ -pthread main.o -lACE -lTestSingleton
    main.o: In function `main':
    /home/wanner/Templates/TestSingleton/main.cpp:11: undefined reference to `ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex>::instance()'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chuck Wanner@21:1/5 to Chuck Wanner on Thu Dec 14 16:27:01 2017
    On Friday, December 8, 2017 at 1:30:24 PM UTC-8, Chuck Wanner wrote:
    Hello,

    I am trying to port software from using ACE 5.8.2 to ACE 6.4.5. We were using Redhat 5.4. We are now using CentOS 7.4. The software builds a few shared libraries and executable. Everything built until trying to link the executable.

    One of my shared libraries declared a singleton using the ACE_Singleton Template.

    class MyLib_Export MyClass {
    friend class ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>;
    public:

    };

    // define the macro MYCLIENT to point to our MyClass Singleton
    typedef ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex> MyClassSingleton;
    #define MYCLIENT MyClassSingleton::instance()

    MYLIB_SINGLETON_DECLARE(ACE_Singleton, MyClass, ACE_Recursive_Thread_Mutex)

    When trying to perform the link to my executable, the following Link Error is generated:

    undefined reference to `ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>::instance()'

    I thought templates did not require to be exported, __attribute__((visibility(default))). The ACE Singleton template class does not have an export.

    I did check the contents of the new generate_export_file.pl tool. The contents of the export file for the MyLib did not change.

    I was hoping someone would recognize this error and know what I was doing wrong.

    Thank You,
    Chuck Wanner

    I performed another test. I removed the shared library from my test and linked testSingleton.o and main.o to create main.out. The results were the same using a shared library.

    Command to build testSingleton.o:
    g++ -fvisibility=hidden -fvisibility-inlines-hidden -Wnon-virtual-dtor -O3 -ggdb -pthread -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -D_GNU_SOURCE -DTESTSINGLETON_BUILD_DLL -c -fPIC -o testSingleton.o testSingleton.cpp

    Command to build main.o:
    g++ -Wnon-virtual-dtor -O3 -ggdb -pthread -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -D_GNU_SOURCE -I. -fPIC -c -o main.o main.cpp

    Command to build main.out:
    g++ -L. -fPIC -Xlinker -rpath /usr/local/lib -Xlinker -rpath ./ -pthread main.o testSingleton.o -lACE
    main.o: In function `main':
    /home/wanner/Templates/TestSingleton/main.cpp:11: undefined reference to `ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex>::instance()'

    I think the fundamental issue with the first command, building the testSingleton.o object. Why is the command not generating the ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex> code? Any ideas would be appreciated.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Leitgeb@21:1/5 to Chuck Wanner on Fri Dec 15 10:03:21 2017
    Chuck Wanner <cwwanner1967@gmail.com> wrote:
    I performed another test. I removed the shared library from my test and linked testSingleton.o and main.o to create main.out. The results were the same using a shared library.

    Command to build testSingleton.o:
    g++ -fvisibility=hidden -fvisibility-inlines-hidden -Wnon-virtual-dtor -O3 -ggdb -pthread -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -D_GNU_SOURCE -DTESTSINGLETON_BUILD_DLL -c -fPIC -o testSingleton.o testSingleton.cpp

    Command to build main.o:
    g++ -Wnon-virtual-dtor -O3 -ggdb -pthread -fno-strict-aliasing -Wall -W -Wpointer-arith -pipe -D_GNU_SOURCE -I. -fPIC -c -o main.o main.cpp

    Command to build main.out:
    g++ -L. -fPIC -Xlinker -rpath /usr/local/lib -Xlinker -rpath ./ -pthread main.o testSingleton.o -lACE
    main.o: In function `main':
    /home/wanner/Templates/TestSingleton/main.cpp:11: undefined reference to `ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex>::instance()'

    I think the fundamental issue with the first command, building the testSingleton.o object. Why is the command not generating the ACE_Singleton<testSingleton, ACE_Recursive_Thread_Mutex> code? Any ideas would be appreciated.

    Another way to debug stuff is to let the preprocessor process a source
    file and examine the output. usually, the option (to gcc/g++) for
    merely preprocessing is "-E", (and the output is usually sent to stdout
    so either redirect it to a file or pipe it to "less")

    This preprocessing output might reveal what templates are defined
    and/or instanciated.

    On another thought, some compilers are "smart" and add certain symbols
    to that particular ".o" file, that also contains the implementation of
    the first method of the class that is actually supposed to have an implementation (i.e. non-pure-virtual, non-inline)

    In case your testclass contains methods that are declared, but not
    implemented (even if not used, either), that could lead to similar
    problems. (I know you posted your test class, but it was still too
    long for me to scan through it and check if that is the case)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Chuck Wanner@21:1/5 to Chuck Wanner on Fri Dec 15 14:07:48 2017
    On Friday, December 8, 2017 at 1:30:24 PM UTC-8, Chuck Wanner wrote:
    Hello,

    I am trying to port software from using ACE 5.8.2 to ACE 6.4.5. We were using Redhat 5.4. We are now using CentOS 7.4. The software builds a few shared libraries and executable. Everything built until trying to link the executable.

    One of my shared libraries declared a singleton using the ACE_Singleton Template.

    class MyLib_Export MyClass {
    friend class ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>;
    public:

    };

    // define the macro MYCLIENT to point to our MyClass Singleton
    typedef ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex> MyClassSingleton;
    #define MYCLIENT MyClassSingleton::instance()

    MYLIB_SINGLETON_DECLARE(ACE_Singleton, MyClass, ACE_Recursive_Thread_Mutex)

    When trying to perform the link to my executable, the following Link Error is generated:

    undefined reference to `ACE_Singleton<MyClass, ACE_Recursive_Thread_Mutex>::instance()'

    I thought templates did not require to be exported, __attribute__((visibility(default))). The ACE Singleton template class does not have an export.

    I did check the contents of the new generate_export_file.pl tool. The contents of the export file for the MyLib did not change.

    I was hoping someone would recognize this error and know what I was doing wrong.

    Thank You,
    Chuck Wanner

    Andreas,

    Using -E helped to solved my problem. I noticed extra code in the output of the UUID.cpp had but was not present in output my file. It appears that ACE Singletons with classes required a new (relative term, since I am porting from 5.8.2) macro to
    instantiate the singleton.

    I found this macro at the end of the UUID.cpp:

    ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Singleton, ACE_Utils::UUID_Generator, ACE_SYNCH_MUTEX);

    Once I started to add this macro for each of my singletons, my code was able to link with ACE 6.4.5.

    Where is the best source of information to help with porting code to new versions of ACE?

    Thank You,
    Chuck Wanner

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Johnny Willemsen@21:1/5 to All on Sat Dec 16 11:05:48 2017
    Hi,

    Where is the best source of information to help with porting code to new
    versions of ACE?

    The NEWS files in the ACE_wrappers and ACE_wrappers/TAO are a starting point.

    Johnny Willemsen
    http://www.remedy.nl

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)