Menu

#406 Unable to link against libastyle-2.05.1.so (undefined reference)

closed-fixed
None
2017-01-18
2016-08-05
Sven Eden
No

I have a very simple test program, that does nothing:

 ~/tmp $ cat test.cpp
#include <astyle.h>

int main (int argc, char* argv[])
{
        astyle::ASFormatter formatter;
        formatter.setFormattingStyle(astyle::STYLE_KR);

        return 0;
}

Compilation, using gcc-5.4.0 works fine using:

~/tmp $ g++ -o test.o -c test.cpp

But linking fails, no matter how I try it:

 ~/tmp $ g++ -o test test.o -lastyle
test.o: In function `main':
test.cpp:(.text+0x83): undefined reference to `astyle::ASFormatter::ASFormatter()'
test.cpp:(.text+0x97): undefined reference to `astyle::ASFormatter::setFormattingStyle(astyle::FormatStyle)'
test.cpp:(.text+0xab): undefined reference to `astyle::ASFormatter::~ASFormatter()'
test.cpp:(.text+0xd0): undefined reference to `astyle::ASFormatter::~ASFormatter()'
collect2: error: ld returned 1 exit status

Could it be, that the visibility stuff is not handled correctly?

Here is the verbose output from my linking attempt:

 ~/tmp $ g++ -v -v -o test test.o -lastyle
Using built-in specs.
COLLECT_GCC=/usr/x86_64-pc-linux-gnu/gcc-bin/5.4.0/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /home/portage/sys-devel/gcc-5.4.0/work/gcc-5.4.0/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/5.4.0 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/5.4.0 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/5.4.0/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/5.4.0/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/include/g++-v5 --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/5.4.0/python --enable-languages=c,c++,fortran --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --enable-checking=release --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo 5.4.0 p1.0, pie-0.6.5' --enable-libstdcxx-time --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-altivec --disable-fixed-point --enable-targets=all --disable-libgcj --enable-libgomp --disable-libmudflap --disable-libssp --disable-libcilkrts --disable-libmpx --enable-vtable-verify --enable-libvtv --enable-lto --with-isl --disable-isl-version-check --enable-libsanitizer
Thread model: posix
gcc version 5.4.0 (Gentoo 5.4.0 p1.0, pie-0.6.5)
COMPILER_PATH=/usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/:/usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/:/usr/libexec/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../x86_64-pc-linux-gnu/bin/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../x86_64-pc-linux-gnu/lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-v' '-o' 'test' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
 /usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/collect2 -plugin /usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-pc-linux-gnu/5.4.0/lto-wrapper -plugin-opt=-fresolution=/tmp/ccGGUGfq.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o test /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../lib64/crti.o /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/crtbegin.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0 -L/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../x86_64-pc-linux-gnu/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../.. test.o -lastyle -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/../../../../lib64/crtn.o
test.o: In function `main':
test.cpp:(.text+0x83): undefined reference to `astyle::ASFormatter::ASFormatter()'
test.cpp:(.text+0x97): undefined reference to `astyle::ASFormatter::setFormattingStyle(astyle::FormatStyle)'
test.cpp:(.text+0xab): undefined reference to `astyle::ASFormatter::~ASFormatter()'
test.cpp:(.text+0xd0): undefined reference to `astyle::ASFormatter::~ASFormatter()'
collect2: error: ld returned 1 exit status

Discussion

1 2 > >> (Page 1 of 2)
  • Sven Eden

    Sven Eden - 2016-08-05

    Just a note: I downgraded to astyle-2.04 and it works.

     
  • Sven Eden

    Sven Eden - 2016-08-05

    If I remove the "-fvisibility=hidden" flags from build/gcc/Makefile, it works with 2.05.1.

    Yes. Grepping through the sources for "visibility" and "export" reveals, that -fvisibility=hidden is nowhere changed, but in astyle_main.h and astyle_main.cpp.

     
    • konsolebox

      konsolebox - 2016-12-26

      That for sharing. It worked.

       
  • Jim Pattee

    Jim Pattee - 2016-08-05

    The shared object is intended to be used for formatting as described in the Developer Information examples http://astyle.sourceforge.net/develop/cpp.html . If you need access to the classes or variables, astyle is usually compiled as a static library, using ASTYLE_LIB, and linked statically to the program.

     
  • Jim Pattee

    Jim Pattee - 2016-09-29
    • status: open --> open-fixed
    • Priority: 5 --> 7
     
  • konsolebox

    konsolebox - 2016-12-26

    Wouldn't this just make it difficult to compile dependent packages? Does it always have to be static?

     
  • Jim Pattee

    Jim Pattee - 2016-12-27

    You can remove the "-fvisibility=hidden" flags and usea DLL if you want It depends on what you want to do with it. In Linux there is no difference in linking a DLL or a static library. It will link with the one that is available.

     
    • konsolebox

      konsolebox - 2016-12-27

      But I'm using Gentoo Linux. There's a difference here.

      This is the issue I fixed: https://forums.gentoo.org/viewtopic-t-1054882-start-0-postdays-0-postorder-asc-highlight-.html

      I had to add a hack patch to dev-utils/astyle to remove the flags, and it's not a convenient thing to do; not a clean solution.

       

      Last edit: konsolebox 2016-12-27
  • Sven Eden

    Sven Eden - 2016-12-27

    I do not think it to be wise to hide core API elements.
    astyle::ASFormatter is one of those core elements. And its public methods should be accessible. Otherwise they should be protected or private.

    Btw. the example in http://astyle.sourceforge.net/develop/cpp.html is not very flexible if needed to be used through something more complex like an IDE like Code::Blocks. It'll need a lot of text processing to get something like the pOptions char array right, so any call (that'll be a fire-and-forget-call) to AStyleMain() would do the right thing.
    I can see why the Code::Blocks devs liked to use an ASFormatter instance directly. It is much more convenient if configured through a GUI.
    But that's just my two cents...

     
  • Jim Pattee

    Jim Pattee - 2016-12-27

    CodeBlocks has used astyle 2.05.1 since January 2016. Does Gentoo use the same build system as CodeBlocks? Or does it have it's own?

    As far as know CodeBlocks does not use astyle as a stand alone DLL. Their DLL includes the files that access the ASFormatter code. These are the ones that are having a problem linking in the Gentoo compile.

     
    • konsolebox

      konsolebox - 2016-12-28

      This is the (official) ebuild I use which compiles and installs codeblocks: https://github.com/gentoo/gentoo/blob/master/dev-util/codeblocks/codeblocks-9999.ebuild

      The ebuild targets the latest svn update.

      I see nothing special added in it. And it has always worked until lately.

      CodeBlocks has used astyle 2.05.1 since January 2016. Does Gentoo use the same build system as CodeBlocks? Or does it have it's own?

      After some examination I found that it might be an issue with CodeBlocks:

      https://sourceforge.net/p/codeblocks/code/HEAD/tree/trunk/src/plugins/astyle/Makefile.am#l45

      HAVE_ASTYLE is a dynamic variable that gets enabled when astyle.h is detected, as seen in configure. I think that it should even be HAVE_ASTYLE_TRUE, because HAVE_ASTYLE has a value of either 'yes' or 'no', so it could always be enabled, although that's just my theory.

      I was able to compile CodeBlocks by removing the block that generates the variable in configure. Running ldd libAstyle.so | grep -i astyle(uninstalled compiled binary) shows that it's no longer bound to /usr/lib64/libastyle-2.05.1.so as opposed to the one in the currently installed package.

      So either CodeBlocks removes the feature that makes it in some conditions link against the external astyle, or Astyle allows names or symbols to be not hidden. And I think the latter is more commendable to be done, because it allows things to be more flexible.

       
  • Jim Pattee

    Jim Pattee - 2016-12-28

    The makefile shows that the programs with the linker errors are intended to be included in the DLL. If this is done you won't have the linking problem.

     
    • Sven Eden

      Sven Eden - 2016-12-28

      Code::Blocks is just one example. And it doesn't matter whether you use the Gentoo ebuild or compile a nightly by hand.

      Astyle introduced the visibility stuff between 2.04 and 2.05.1, and since then everything that does not use AStyleMain() but something else and links against astyle breaks. Period.

      So, yes, you can just declare it a downstream problem and be done with it.
      I just thought it might be good to know.

       
  • Jim Pattee

    Jim Pattee - 2016-12-28

    The build breaks because it is linking against the dll instead of the object files. CodeBlocks does NOT use the astyle makefile and it does NOT link against the dll. It creates its own library with an independent makefile that links against the object files. The problem was created by changing the build process.

    Astyle may have exposed the problem by changing the visibility. But it is not the cause of it.

    I will be glad to help solve the problem where I can. I am not sure exactly what you are trying to do or why you had the problem. But I see no reason to make a permanent change to astyle to fix a faulty build.

     
    • konsolebox

      konsolebox - 2016-12-29

      it does NOT link against the dll,

      No it does (in one way), as you've seen in its own (not Gentoo's) Makefile.am file: libAstyle_la_LIBADD += -lastyle

      But it is not the cause of it.

      CodeBlocks chose to dynamically use the external astyle when it's available in the system, and use its own builtin version if there's none. In the case of the former, astyle's change is the cause of it.

      Edit:

      Sorry my careless assumptiont was wrong. It was just recently that CodeBlocks was made to dynamically use the system-provided astyle (2016-07-16), so it's not exactly astyle's fault: https://sourceforge.net/p/codeblocks/code/10873/log/?path=/trunk/src/plugins/astyle/Makefile.am

      Still they might have targetted the earlier version (during the change), so the change of astyle in 2.05 may have been uncalled for.

      Anyway the point still remains that allowing astyle to remain usable in a dynamic manner would help, because there are cases where developers (like those of CodeBlocks) explicitly make use of it.

       

      Last edit: konsolebox 2016-12-29
  • Sven Eden

    Sven Eden - 2016-12-29

    Oh for heavens sake!

    I am sorry to not have made this clear enough, but this riding on Code::Blocks is clearly showing that I did not express myself clearly enough. So let's try again:

    • astyle ships astyle.h
    • Any dev will #include it and look into it as the API to use
    • In there they'll find class ASFormatter : public ASBeautifier with a lot of public functions
    • There is absolutely no hint about AStyleMain() and that it is considered to be the only real API door.
    • By adding -fvisibility=hidden to build/gcc/Makefile the whole header has become a paradox: It offers an API that is unusable.
    • This leads to the breakage of every downstream code that does
      1. #include <astyle.h>
      2. Uses anything from in there
      3. Is linked with -lastyle
    • However, this was never a problem until the last release.

    Did I make myself clear now?

    This is what the Gentoo ebuild installs:

     image # find -type f
    ./usr/lib/debug/usr/bin/astyle.debug
    ./usr/lib/debug/usr/lib64/libastyle-2.05.1.so.debug
    ./usr/share/doc/astyle-2.05.1/html/styles.css
    ./usr/share/doc/astyle-2.05.1/html/notes.html
    ./usr/share/doc/astyle-2.05.1/html/news.html
    ./usr/share/doc/astyle-2.05.1/html/license.html
    ./usr/share/doc/astyle-2.05.1/html/install.html
    ./usr/share/doc/astyle-2.05.1/html/astyle.html
    ./usr/lib64/libastyle-2.05.1.so
    ./usr/bin/astyle
    ./usr/include/astyle.h
    

    Please note that astyle.h is manually installed by the ebuild, not the Makefile.

    So you'll have one binary, one library and one header.

    And that is simply the current situation and has nothing to do with any build system in any sub directory of any project neither of us is even involved in. Okay?

    So, please, what exact problem was adding -fvisibility=hidden to build/gcc/Makefile fixing? Is there really any good reason for it? And that is the core question I was so inefficient to ask.

     
  • Jim Pattee

    Jim Pattee - 2016-12-29

    OK. If developers are going to use it like this I will remove the restriction. I just released version 2.06. There will probably be a maintenance release in a few months. I will change it there. If you need a change to 2.05 I will email a fixed release package.

    Windows does not expose the entire API like Linux. Functions have to be explicitly exported to be available. So the one entry point is all there is. Making everything available on Linux should be OK, as long as the formatter object is handled correctly by the calling program.

    The shared object was created mainly to allow non-C programs to access astyle. I wasn't aware that it would be such a problem to change the options in a makefile. The change that was made for Fedora in July was to allow for a problem with their installation system.

     
    • Sven Eden

      Sven Eden - 2016-12-30

      I see...

      Then making everything available on linux is unportable and another approach to have a portable solution, might be better. It at least would allow to leave the default visibility to be hidden. Which is, by the way, the recommended way for everything that gets shared, like a dynamic library.
      This might be a way to clear up things for devs one way or another.

      So, an "official" header declaring the API is one thing. Here the problem remains, that the astyle build system does not install it.
      The "normal" procedure for package foo is to look for foo.h. So it might be a good idea to move some things around:

      1. Everything from astyle.h that is in fact internal could be moved to, let's say, astyle_internal.h
      2. Everything from astyle_main.h that is meant to be the official API could be moved to astyle.h
      3. The build system should "officially" install this astyle.h

      This way nobody ever gets confused again. And there is still the possibility to just include the sources in their project (like Code::Blocks used to do before that wretched detection was added) if, and only if, someone really needs to use the more internal classes directly.

      Or you might decide to simply declare some core classes like ASFormatter to become part of the official API, to be used at anybodys own discretion.

      The latter would involve more work, of course, but it would clear things up for the future and the default visibility can (and should) stay being hidden.

      If you like I could do this and attach a patch for you to review. Just give the word. But I'll have to ask for some patience, as I wouldn't be getting to it until next year.

       
  • Jim Pattee

    Jim Pattee - 2016-12-31

    Thanks for the offer. But for now, I think I will leave it alone and see what happens. It is not really unportable. It just gives Linux users capability I hadn't planned on. It has been in use for over 15 years so it should be ok.

    I noticed that CodeBlocks is already installing the new version. I can make a special download available if you need it. If there are no problems it will probably be a while before a new release.

     
    • Sven Eden

      Sven Eden - 2017-01-04

      A special version should not be needed, I guess.

      For Gentoo Users: You can put the attached patch into

      /etc/portage/patches/dev-util/astyle-2.06/
      

      and upgrade to (or rebuild) astyle-2.06 with it.

      Code::Blocks merges fine then.

       
  • Jim Pattee

    Jim Pattee - 2017-01-14
    • status: open-fixed --> closed-fixed
     
  • konsolebox

    konsolebox - 2017-01-16

    Sorry, but why is this considered fixed?

     
    • Sven Eden

      Sven Eden - 2017-01-18

      I guess because I have created a patch for gentoo users.
      Hmm... maybe gentoo is the only distro that installs /usr/include/astyle.h?

       
  • Sven Eden

    Sven Eden - 2017-01-18

    I submitted my patch downstream:

    https://bugs.gentoo.org/show_bug.cgi?id=606162

     
  • konsolebox

    konsolebox - 2017-01-18

    So does that mean we can presume that CodeBlocks added this functionality that dynamically uses external astyle just for Gentoo users?

    https://sourceforge.net/p/codeblocks/code/10873/

     
1 2 > >> (Page 1 of 2)

Log in to post a comment.