2011-04-17 36 views
8

Recientemente he decidido usar yaml como mi tecnología de archivo de configuración, y estoy escribiendo una aplicación de C++ linux en OpenSuse 11.3.¿Cómo usar yaml-cpp en un programa C++ en Linux?

El problema es que incluso después de instalar con éxito cmake, compilando yaml-cpp como se muestra en la página de documentos yaml-cpp, todavía no puedo compilar los programas de demostración simples en la página yaml-cpp here.

Por ejemplo, cuando intento compilar el del monster.yaml and main.cpp example

mi compilador de emitir el comando gcc main.cpp, emite los siguientes errores:

main.cpp:24:25: error: ‘YAML’ does not name a type
main.cpp:24:35: error: expected unqualified-id before ‘&’ token
main.cpp:24:35: error: expected ‘)’ before ‘&’ token
main.cpp:24:35: error: expected initializer before ‘&’ token
main.cpp:30:25: error: ‘YAML’ does not name a type
main.cpp:30:35: error: expected unqualified-id before ‘&’ token
main.cpp:30:35: error: expected ‘)’ before ‘&’ token
main.cpp:30:35: error: expected initializer before ‘&’ token
main.cpp:35:25: error: ‘YAML’ does not name a type
main.cpp:35:35: error: expected unqualified-id before ‘&’ token
main.cpp:35:35: error: expected ‘)’ before ‘&’ token
main.cpp:35:35: error: expected initializer before ‘&’ token

He intentado cambiar la directiva de inclusión de #include "yaml-cpp/yaml.h" a #include <yaml.h> , ya que había instalado el yaml lib, pero esto no solucionó nada.

Entonces, ¿qué hice mal?

Este es el código problemático pegado de las líneas 24 a 40:

void operator >> (const YAML::Node& node, Vec3& v) { 
    node[0] >> v.x; 
    node[1] >> v.y; 
    node[2] >> v.z; 
} 

void operator >> (const YAML::Node& node, Power& power) { 
    node["name"] >> power.name; 
    node["damage"] >> power.damage; 
} 

void operator >> (const YAML::Node& node, Monster& monster) { 
    node["name"] >> monster.name; 
    node["position"] >> monster.position; 
    const YAML::Node& powers = node["powers"]; 
    for(unsigned i=0;i<powers.size();i++) { 
     Power power; 
     powers[i] >> power; 
     monster.powers.push_back(power); 
    } 
} 

Y aquí es un volcado de la salida del sudo make install después de ejecutar el comando make:

[ 81%] Built target yaml-cpp 
[ 96%] Built target run-tests 
[100%] Built target parse 
Install the project... 
-- Install configuration:  "Release"                                    
-- Installing: /usr/local/lib/libyaml-cpp.so.0.2.6 
-- Up-to-date: /usr/local/lib/libyaml-cpp.so.0.2 
-- Up-to-date: /usr/local/lib/libyaml-cpp.so 
-- Up-to-date: /usr/local/include/yaml-cpp/aliasmanager.h 
-- Up-to-date: /usr/local/include/yaml-cpp/anchor.h 
-- Up-to-date: /usr/local/include/yaml-cpp/conversion.h 
-- Up-to-date: /usr/local/include/yaml-cpp/dll.h 
-- Up-to-date: /usr/local/include/yaml-cpp/emitfromevents.h 
-- Up-to-date: /usr/local/include/yaml-cpp/emitter.h 
-- Up-to-date: /usr/local/include/yaml-cpp/emittermanip.h 
-- Up-to-date: /usr/local/include/yaml-cpp/eventhandler.h 
-- Up-to-date: /usr/local/include/yaml-cpp/exceptions.h 
-- Up-to-date: /usr/local/include/yaml-cpp/iterator.h 
-- Up-to-date: /usr/local/include/yaml-cpp/ltnode.h 
-- Up-to-date: /usr/local/include/yaml-cpp/mark.h 
-- Up-to-date: /usr/local/include/yaml-cpp/node.h 
-- Up-to-date: /usr/local/include/yaml-cpp/nodeimpl.h 
-- Up-to-date: /usr/local/include/yaml-cpp/nodereadimpl.h 
-- Up-to-date: /usr/local/include/yaml-cpp/nodeutil.h 
-- Up-to-date: /usr/local/include/yaml-cpp/noncopyable.h 
-- Up-to-date: /usr/local/include/yaml-cpp/null.h 
-- Up-to-date: /usr/local/include/yaml-cpp/ostream.h 
-- Up-to-date: /usr/local/include/yaml-cpp/parser.h 
-- Up-to-date: /usr/local/include/yaml-cpp/stlemitter.h 
-- Up-to-date: /usr/local/include/yaml-cpp/stlnode.h 
-- Up-to-date: /usr/local/include/yaml-cpp/traits.h 
-- Up-to-date: /usr/local/include/yaml-cpp/yaml.h 
-- Up-to-date: /usr/local/include/yaml-cpp/anchordict.h 
-- Up-to-date: /usr/local/include/yaml-cpp/graphbuilder.h 
-- Installing: /usr/local/lib/pkgconfig/yaml-cpp.pc 

Podría haber probablemente sea alguna directiva especial/opción que tengo que agregar al comando gcc al compilar con libyaml? algo así como gcc main.cpp -libyaml?

Para obtener más resultado del compilador (gcc version 4.5.0 20100604 [gcc-4_5-branch revision 160292] (SUSE Linux)):

/tmp/ccYltArL.o: In function `operator>>(YAML::Node const&, Monster&)': 
main.cpp:(.text+0x1a8): undefined reference to `YAML::Node::size() const' 
/tmp/ccYltArL.o: In function `main': 
main.cpp:(.text+0x1fe): undefined reference to `std::basic_ifstream<char,  std::char_traits<char> >::basic_ifstream(char const*, std::_Ios_Openmode)' 
main.cpp:(.text+0x215): undefined reference to `YAML::Parser::Parser(std::basic_istream<char, std::char_traits<char> >&)' 
main.cpp:(.text+0x224): undefined reference to `YAML::Node::Node()' 
main.cpp:(.text+0x23e): undefined reference to `YAML::Parser::GetNextDocument(YAML::Node&)' 
main.cpp:(.text+0x29c): undefined reference to `std::cout' 

y mucho más cosas que puede encajar aquí , terminando finalmente en:

/tmp/ccYltArL.o:(.rodata._ZTIN4YAML14BadDereferenceE[typeinfo for YAML::BadDereference]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info' 
/tmp/ccYltArL.o:(.rodata._ZTIN4YAML11KeyNotFoundE[typeinfo for YAML::KeyNotFound]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info' 
/tmp/ccYltArL.o:(.rodata._ZTIN4YAML13InvalidScalarE[typeinfo for YAML::InvalidScalar]+0x0): more undefined references to `vtable for __cxxabiv1::__si_class_type_info' follow 
/tmp/ccYltArL.o:(.rodata._ZTIN4YAML9ExceptionE[typeinfo for YAML::Exception]+0x8): undefined reference to `typeinfo for std::runtime_error' 
/tmp/ccYltArL.o:(.eh_frame+0x18f): undefined reference to `__gxx_personality_v0' 
collect2: ld returned 1 exit status 

- finalmente -

Lo resolvió con la solución de Chris (consulte a continuación), aunque en realidad encontré una forma aún más clara de cargar previamente bibliotecas 'personalizadas', usando el comando ldconfig para configurar la ruta de búsqueda de la biblioteca luego de agregar la ruta a mis libs en un archivo *.conf en /etc/ld.so.conf.d/. Consulte detailed guide here...

+0

pasta de línea main.cpp 24 30 y 35 – fazo

Respuesta

8

gcc no se le indica que busque en/usr/local. Tienes que hacerlo explícitamente. Además, eso realmente debería ser g ++ y no gcc.Así que, primero asegúrese de que las necesidades de inclusión se ve así:

#include "yaml-cpp/yaml.h" 

compilarlo como esto: Código

g++ -I/usr/local/include -L/usr/local/lib -lyaml-cpp -o testprogram main.cpp 
+0

Esto realmente compila el programa correctamente, PERO cuando trato de ejecutar el ejecutable con './Testprogram', obtengo el error en tiempo de ejecución:' ./testprogram: error al cargar bibliotecas compartidas: libyaml-cpp.so.0.2 : no se puede abrir el archivo de objeto compartido: No existe ningún archivo o directorio' – nemesisfixx

+0

'$> LD_PRELOAD =/usr/local/lib/libyaml-cpp.so./testprogram' –

+0

Si la línea anterior funciona, deberá agregar libyaml- La ruta de cpp.so a la ruta de búsqueda de tu biblioteca. No recuerdo cómo hacerlo, tendrás que googlear ese. La mejor manera es que cuando esté compilando un programa, haga que se instale en/usr y no/usr/local. –

0

Parece que no puede encontrar los encabezados yaml-cpp. En primer lugar, la directiva de inclusión debe ser

#include "yaml-cpp/yaml.h" 

ya que, como se puede ver, las cabeceras se instalan en /usr/local/include/yaml-cpp/.

¿Aparece un mensaje de error en la línea de la instrucción include? (¿Se puede publicar la salida completa del compilador?)

+0

sí, ya ha ejecutado el 'make' y el 'sudo make install', ¡pero sigue teniendo problemas! – nemesisfixx

+0

He agregado el resultado de los comandos make, ¿qué crees que está mal? – nemesisfixx

+0

@mcnemesis, editado: ¿puedes publicar la salida completa del compilador? –

Cuestiones relacionadas