1

I'm currently using a script which validates an invalid XML file or string using tidy library.

A sample code to test it's running:

#include <tidy.h>
#include <tidybuffio.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char **argv )
{
  const char* input = "&lt;title&gt;Foo&lt;/title&gt;&lt;p&gt;Foo!";
  TidyBuffer output = {0};
  TidyBuffer errbuf = {0};
  int rc = -1;
  Bool ok;

  TidyDoc tdoc = tidyCreate();                     // Initialize "document"
  printf( "Tidying:\t%s\n", input );

  ok = tidyOptSetBool( tdoc, TidyXhtmlOut, yes );  // Convert to XHTML
  if ( ok )
    rc = tidySetErrorBuffer( tdoc, &errbuf );      // Capture diagnostics
  if ( rc >= 0 )
    rc = tidyParseString( tdoc, input );           // Parse the input
  if ( rc >= 0 )
    rc = tidyCleanAndRepair( tdoc );               // Tidy it up!
  if ( rc >= 0 )
    rc = tidyRunDiagnostics( tdoc );               // Kvetch
  if ( rc > 1 )                                    // If error, force output.
    rc = ( tidyOptSetBool(tdoc, TidyForceOutput, yes) ? rc : -1 );
  if ( rc >= 0 )
    rc = tidySaveBuffer( tdoc, &output );          // Pretty Print

  if ( rc >= 0 )
  {
    if ( rc > 0 )
      printf( "\nDiagnostics:\n\n%s", errbuf.bp );
    printf( "\nAnd here is the result:\n\n%s", output.bp );
  }
  else
    printf( "A severe error (%d) occurred.\n", rc );

  tidyBufFree( &output );
  tidyBufFree( &errbuf );
  tidyRelease( tdoc );
  return rc;
}

on running

gcc -I/usr/include/tidy tidy_example.c

I get this output on my terminal:

/tmp/cclFfP4I.o: In function main': tidy_exa.c:(.text+0x6e): undefined reference totidyCreate' tidy_exa.c:(.text+0x9e): undefined reference to tidyOptSetBool' tidy_exa.c:(.text+0xba): undefined reference totidySetErrorBuffer' tidy_exa.c:(.text+0xd6): undefined reference to tidyParseString' tidy_exa.c:(.text+0xeb): undefined reference totidyCleanAndRepair' tidy_exa.c:(.text+0x100): undefined reference to tidyRunDiagnostics' tidy_exa.c:(.text+0x11f): undefined reference totidyOptSetBool' tidy_exa.c:(.text+0x149): undefined reference to tidySaveBuffer' tidy_exa.c:(.text+0x1a6): undefined reference totidyBufFree' tidy_exa.c:(.text+0x1b2): undefined reference to tidyBufFree' tidy_exa.c:(.text+0x1be): undefined reference totidyRelease' collect2: error: ld returned 1 exit status

Any Idea as to how to resolve this issue, or any other library to do the same thing on a file or a string (invalid XML) in c/c++.

Any suggestions will also be welcomed.

LPs
  • 16,045
  • 8
  • 30
  • 61
SilentFlame
  • 487
  • 5
  • 15
  • 1
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Mike Kinghan Jul 04 '17 at 09:42
  • See [this answer](https://stackoverflow.com/a/12574400/1362568) to [this question](https://stackoverflow.com/q/12573816/1362568) – Mike Kinghan Jul 04 '17 at 09:43
  • tried the approaches it mentioned, none seems to work for me. – SilentFlame Jul 04 '17 at 11:34
  • Or, even more saliently, an [answer](https://stackoverflow.com/a/43305704/15168) about link order of libraries and object files by one @MikeKinghan, in the same "What is an undefined reference…" question. Presumably he'd forgotten about that — it's a little lower down the list of answers. – Jonathan Leffler Jul 05 '17 at 19:32

1 Answers1

2

You forgot to link the lib using -l option.

For example

gcc -I/usr/include/tidy -ltidy tidy_example.c -o example

If you also need to specify a specific folder for libs you must add -L option like

gcc -I/usr/include/tidy -L/usr/local/lib/tidy -ltidy tidy_example.c -o example
LPs
  • 16,045
  • 8
  • 30
  • 61
  • It gives the same output even when I use **-ltidy** with my command. and for the later one, I don't see a tidy-tidy file/directory in my "/usr/local/lib". – SilentFlame Jul 04 '17 at 10:48
  • First of all: where is libtidy installed? – LPs Jul 04 '17 at 11:50
  • 1
    Libraries should be listed _after_ source or object files, not before. On some systems and with some libraries, it won't matter. On other systems, it will matter. Hence: `gcc -I/usr/include/tidy tidy_example.c -ltidy` will work (if there is a `libtidy.a` or `libtidy.so` in a library directory that's searched by the linker anyway. If it is in an obscure directory, you may need `gcc -I/opt/tidy/include -o tidy_example tidy_example.c -L/opt/tidy/lib -ltidy`. The `-L` option can be placed anywhere before the `-l` option. – Jonathan Leffler Jul 04 '17 at 15:09
  • @JonathanLeffler the above mentioned **gcc -I/usr/include/tidy tidy_example.c -ltidy** does work. Thanks you for the help. But would like to know why keeping `-ltidy` before `tidy_example.c` does not work? – SilentFlame Jul 05 '17 at 16:31
  • @SilentFlame: there are definitely other questions that cover this. Succinctly, when the linker scans the library looking for symbols, if it does not find any currently undefined symbols, it ignores (or can ignore) the library. With static libraries, it strictly ignores it; it pulls no information in. With shared libraries, sometimes the linker remembers what was defined and if a symbol the shared library defines is later needed, it will list the library as a dependency after all. Sometimes it doesn't. Assuming your tidy library is a shared object, yours doesn't. – Jonathan Leffler Jul 05 '17 at 19:27