Thread: Wierd linkage error

  1. #1
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,681

    Wierd linkage error

    Now I know the bit of code I'm posting looks a bit unsightly, that's an issue for a later date when I'm inclined to put the effort into expanding it out of macros for each string type. The problem is that something that should be defined is not being seen by the linker, I can't see any valid reason why either.

    The output:
    Code:
    make build
    ...
    cc -O3 -fPIC -o "dst/_x86_64_linux_cc/QUICK/output/trypaw.elf" *.o -Wl,-rpath="." -L "dst/_x86_64_linux_cc/QUICK/output" -L "dst/_x86_64_linux_cc/QUICK/output/lib" -l paw
    /usr/bin/ld: dst/_x86_64_linux_cc/QUICK/output/libpaw.so: undefined reference to `paws2hhs'
    /usr/bin/ld: dst/_x86_64_linux_cc/QUICK/output/libpaw.so: undefined reference to `pawls2hhs'
    /usr/bin/ld: dst/_x86_64_linux_cc/QUICK/output/libpaw.so: undefined reference to `pawhs2hhs'
    /usr/bin/ld: dst/_x86_64_linux_cc/QUICK/output/libpaw.so: undefined reference to `pawts2hhs'
    /usr/bin/ld: dst/_x86_64_linux_cc/QUICK/output/libpaw.so: undefined reference to `pawjs2hhs'
    /usr/bin/ld: dst/_x86_64_linux_cc/QUICK/output/libpaw.so: undefined reference to `pawlls2hhs'
    Signal 1 returned
    collect2: error: ld returned 1 exit status
    Compilation finished successfully.
    The code:
    Code:
    #define ASDST_ARGS(S)	pawhhc *dst, pawd max, S src, pawd len
    #define ASDST_FUNC(S)	PAW_API pawzd S##2hss( ASDST_ARGS(S) )
    #define ASDST_CODE(C,E)	return paw_encode( INTO(pawhhc,"UTF-8"), FROM(C,E) )
    #define ASDST(S,C,ENC)	ASDST_FUNC(S)	{ ASDST_CODE(C,ENC);	}
    
    #define ASSRC_ARGS(C)	C *dst, pawd max, pawhhs src, pawd len
    #define ASSRC_FUNC(C,S)	PAW_API pawzd pawhhs2##S( ASSRC_ARGS(C) )
    #define ASSRC_CODE(C,E)	return paw_encode( INTO(C,E), FROM(pawhhc,"UTF-8") )
    #define ASSRC(C,S,ENC)	ASSRC_FUNC(C,S)	{ ASSRC_CODE(C,ENC);	}
    
    #define ASMBC_ARGS(C)	pawmbc *dst, C src
    #define ASMBC_FUNC(C)	PAW_API pawzd C##2hhc( ASMBC_ARGS(C) )
    #define ASMBC_CODE(C,E)	return paw_encodec( dst, E, src, sizeof(C) )
    #define ASMBC(C,ENC)	ASMBC_FUNC(C)	{ ASMBC_CODE(C,ENC);	}
    
    #define DEF_ENCODING_FUNCS(TS,TC,SFX,ENC) \
    	ASDST(TS,TC,ENC) \
    	ASSRC(TC,SFX,ENC) \
    	ASMBC(TC,ENC)
    
    /* Smallest character type */
    
    DEF_MOST_STR_FUNCS(paws,pawc,PAWC_MBC_BIT)
    DEF_ENCODING_FUNCS(paws,pawc,s,NULL)
    
    /* Wide character type */
    DEF_MOST_STR_FUNCS(pawls,pawlc,PAWLC_MBC_BIT)
    DEF_ENCODING_FUNCS(pawls,pawlc,ls,"WCHAR_T")
    
    /* UTF-8 character type */
    DEF_MOST_STR_FUNCS(pawhhs,pawhhc,PAWHHC_MBC_BIT)
    
    /* UTF-16 character type */
    DEF_MOST_STR_FUNCS(pawhs,pawhc,PAWHC_MBC_BIT)
    DEF_ENCODING_FUNCS(pawhs,pawhc,hs,"UTF-16")
    
    /* UTF-32 character type */
    DEF_MOST_STR_FUNCS(pawlls,pawllc,PAWLLC_MBC_BIT)
    DEF_ENCODING_FUNCS(pawlls,pawllc,lls,"UTF-32")
    
    /* Largest character type (char32_t is currently the only option here) */
    DEF_MOST_STR_FUNCS(pawjs,pawjc,PAWJC_MBC_BIT)
    DEF_ENCODING_FUNCS(pawjs,pawjc,js,"UTF-32")
    
    /* Native system character type (equivalent of TCHAR on windows) */
    DEF_MOST_STR_FUNCS(pawts,pawtc,PAWTC_MBC_BIT)
    #if PAWTC_MAX > PAWC_MAX
    DEF_ENCODING_FUNCS(pawts,pawtc,ts,"WCHAR_T")
    #else
    DEF_ENCODING_FUNCS(pawts,pawtc,ts,NULL)
    #endif

  2. #2
    Registered User
    Join Date
    Sep 2020
    Posts
    399
    Insufficient code to reproduce the problem. I don't think anybody will be able to offer meaningful help.

    Code:
    a.c:23:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
       23 | DEF_MOST_STR_FUNCS(paws,pawc,PAWC_MBC_BIT)
          | ^~~~~~~~~~~~~~~~~~
    a.c: In function ‘DEF_MOST_STR_FUNCS’:
    a.c:2:25: error: unknown type name ‘PAW_API’
        2 | #define ASDST_FUNC(S)   PAW_API pawzd S##2hss( ASDST_ARGS(S) )
          |                         ^~~~~~~
    a.c:4:25: note: in expansion of macro ‘ASDST_FUNC’
        4 | #define ASDST(S,C,ENC)  ASDST_FUNC(S)   { ASDST_CODE(C,ENC);    }
          |
    Best bet is to run the code through the preprocessor and see what is generated - for example use the "-E" switch if using GCC.

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,681
    Quote Originally Posted by hamster_nz View Post
    Insufficient code to reproduce the problem. I don't think anybody will be able to offer meaningful help.

    Code:
    a.c:23:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
       23 | DEF_MOST_STR_FUNCS(paws,pawc,PAWC_MBC_BIT)
          | ^~~~~~~~~~~~~~~~~~
    a.c: In function ‘DEF_MOST_STR_FUNCS’:
    a.c:2:25: error: unknown type name ‘PAW_API’
        2 | #define ASDST_FUNC(S)   PAW_API pawzd S##2hss( ASDST_ARGS(S) )
          |                         ^~~~~~~
    a.c:4:25: note: in expansion of macro ‘ASDST_FUNC’
        4 | #define ASDST(S,C,ENC)  ASDST_FUNC(S)   { ASDST_CODE(C,ENC);    }
          |
    Best bet is to run the code through the preprocessor and see what is generated - for example use the "-E" switch if using GCC.
    Thanks, I'll give that a try. Btw if you're wandering about the custom types, just ignore the 'paw' part of it and think of the equivalent printf identifier, that's the type, I'm designing my library with that as the basis, no hunting for references, you just look at the type and you have your specifier. I've also added modifiers not just for TCHAR (t), UTF-8 (hh, char or wchar_t), char16_t (h) & char32_t (ll) but also for intptr_t/uintptr_t (v for void) plus a specifier for binary (b), considering adding U for uuid_t but I'll leave that for a later date, when I'm satisfied the library is ready to be marked beta I'll post about it here so peops can give it a thorough test and tell me what still needs to be done for it to be a decent alternative to libc, mcrt etc, I'm aiming for this to be part of a cross platform solution to application development, regardless of system libraries. On that note here's the rough idea:

    On windows:
    PAW_ALL_START=C:\abi\paw\release
    PAW_ALL_DEBUG=C:\abi\paw\debug
    PAW_USR_START=...\abi\paw\release
    PAW_USR_DEBUG=...\abi\paw\debug

    paw --start command
    PAW_SYS_DIR=%PAW_SYS_START% && PAW_USR_DIR=%PAW_USR_START% && PATH=<user_start_paths>;<all_start_paths>;%PATH% && command
    paw --debug command
    PAW_SYS_DIR=%PAW_SYS_DEBUG% && PAW_USR_DIR=%PAW_USR_DEBUG% && PATH=<user_debug_paths>;<all_debug_paths>;<user_st art_paths>;<all_start_paths>;%PATH% && command

    On linux/unix:
    PAW_ALL_START=/abi/paw/release
    PAW_ALL_DEBUG=/abi/paw/debug
    PAW_USR_START=~/abi/paw/release
    PAW_USR_DEBUG=/abi/paw/debug

    paw --start command
    PAW_SYS_DIR=%PAW_SYS_START% && PAW_USR_DIR=%PAW_USR_START% && PATH=<user_start_paths>:<all_start_paths>:%PATH% && command
    paw --debug command
    PAW_SYS_DIR=%PAW_SYS_DEBUG% && PAW_USR_DIR=%PAW_USR_DEBUG% && PATH=<user_debug_paths>:<all_debug_paths>:<user_st art_paths>:<all_start_paths>:%PATH% && command

    The idea is not to isolate like flatpack etc does, but instead give a chance to use consistent names that are either symlinks to the correct library (such as libglfw to libglfw-x11 or libglfw-wayland) or a copy (due to lack of system support for symlinks), that goes both for release & debug names (for example instead of libc.*.so or libc-dbg.*.so, just libc.so that has something like hook_and_init_libc(major,minor) for libraries/apps to use - assuming they don't use libstdpaw instead, planning a libminpaw if I can manage for finding those libs without system details exposed)

    It would even be possible to launch paw from itself like this:
    paw --start paw

    Be a bit silly but it would be possible, as for valgrind etc, there would be no need to setup special packages for them, they just need to add the paw app as a dependency and pass it the appropriate paths like this:

    paw --install[=arch] .../release/paw [.../debug/paw]

    If it can be symlinked then paw will do so, otherwise it will copy it, no need for easy to mess up details, just follow the unix standard inside the directories to be symlinked/copied and paw will do the rest.

    I imagine there might be things I haven't thought of so I'm open to ideas on those things too, I want this to be a solution that seamlessly integrates with the native packaging (if it exists, either way paw will support ftp/https urls etc so systems like windows can do a package manager via paw or choco paw)

  4. #4
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,681
    Having just finished converting my temporary c++ to full c and changed the file extension to *.c I gave the -E option a try, looking through the code I did see the definition of the problem functions so I still have no idea why the linker can't find them, tried uploading the result to the forum but apparently 300 odd kilobytes is too much so I uploaded to my drive instead

    string.c - Google Drive

    Edit: Never mind, I just noticed, I made a typo with the name, had hss instead of hhs

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Linkage error I'm not seeing the cause of
    By awsdert in forum C Programming
    Replies: 2
    Last Post: 02-12-2022, 09:13 AM
  2. Linkage error
    By rgoijre23 in forum C Programming
    Replies: 1
    Last Post: 06-23-2021, 12:51 AM
  3. Linkage error
    By kwzeet in forum C Programming
    Replies: 1
    Last Post: 01-30-2011, 06:49 AM
  4. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  5. Get sense of internal linkage and external linkage
    By gandalf_bar in forum C++ Programming
    Replies: 1
    Last Post: 10-14-2003, 05:57 AM

Tags for this Thread