2014-10-11 18:11:42

Hi all,
Today, I checked out the SVN repository of Angelscript, and I successfully compiled it. However, when I try and compile one of the test programs (tutorial), I get the following error:
main.cpp:13:25: fatal error: angelscript.h: No such file or directory
This is the code in the file:
#include <iostream>  // cout
#include <assert.h>  // assert()
#include <string.h>  // strstr()
#ifdef _LINUX_
    #include <sys/time.h>
    #include <stdio.h>
    #include <termios.h>
    #include <unistd.h>
#else
    #include <conio.h>   // kbhit(), getch()
    #include <windows.h> // timeGetTime()
#endif
#include <angelscript.h>
#include "../../../add_on/scriptstdstring/scriptstdstring.h"

using namespace std;

#ifdef _LINUX_

#define UINT unsigned int
typedef unsigned int DWORD;

// Linux doesn't have timeGetTime(), this essintially does the same
// thing, except this is milliseconds since Epoch (Jan 1st 1970) instead
// of system start. It will work the same though...
DWORD timeGetTime()
{
    timeval time;
    gettimeofday(&time, NULL);
    return time.tv_sec*1000 + time.tv_usec/1000;
}

// Linux does have a getch() function in the curses library, but it doesn't
// work like it does on DOS. So this does the same thing, with out the need
// of the curses library.
int getch()
{
    struct termios oldt, newt;
    int ch;

    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~( ICANON | ECHO );
    tcsetattr( STDIN_FILENO, TCSANOW, &newt );

    ch = getchar();

    tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
    return ch;
}

#endif

// Function prototypes
int  RunApplication();
void ConfigureEngine(asIScriptEngine *engine);
int  CompileScript(asIScriptEngine *engine);
void PrintString(string &str);
void PrintString_Generic(asIScriptGeneric *gen);
void timeGetTime_Generic(asIScriptGeneric *gen);
void LineCallback(asIScriptContext *ctx, DWORD *timeOut);

int main(int argc, char **argv)
{
    RunApplication();

    // Wait until the user presses a key
    cout << endl << "Press any key to quit." << endl;
    while(!getch());

    return 0;
}

void MessageCallback(const asSMessageInfo *msg, void *param)
{
    const char *type = "ERR ";
    if( msg->type == asMSGTYPE_WARNING )
        type = "WARN";
    else if( msg->type == asMSGTYPE_INFORMATION )
        type = "INFO";

    printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
}


int RunApplication()
{
    int r;

    // Create the script engine
    asIScriptEngine *engine = asCreateScriptEngine(ANGELSCRIPT_VERSION);
    if( engine == 0 )
    {
        cout << "Failed to create script engine." << endl;
        return -1;
    }

    // The script compiler will write any compiler messages to the callback.
    engine->SetMessageCallback(asFUNCTION(MessageCallback), 0, asCALL_CDECL);

    // Configure the script engine with all the functions,
    // and variables that the script should be able to use.
    ConfigureEngine(engine);
   
    // Compile the script code
    r = CompileScript(engine);
    if( r < 0 )
    {
        engine->Release();
        return -1;
    }

    // Create a context that will execute the script.
    asIScriptContext *ctx = engine->CreateContext();
    if( ctx == 0 )
    {
        cout << "Failed to create the context." << endl;
        engine->Release();
        return -1;
    }

    // We don't want to allow the script to hang the application, e.g. with an
    // infinite loop, so we'll use the line callback function to set a timeout
    // that will abort the script after a certain time. Before executing the
    // script the timeOut variable will be set to the time when the script must
    // stop executing.
    DWORD timeOut;
    r = ctx->SetLineCallback(asFUNCTION(LineCallback), &timeOut, asCALL_CDECL);
    if( r < 0 )
    {
        cout << "Failed to set the line callback function." << endl;
        ctx->Release();
        engine->Release();
        return -1;
    }

    // Find the function for the function we want to execute.
    asIScriptFunction *func = engine->GetModule(0)->GetFunctionByDecl("float calc(float, float)");
    if( func == 0 )
    {
        cout << "The function 'float calc(float, float)' was not found." << endl;
        ctx->Release();
        engine->Release();
        return -1;
    }

    // Prepare the script context with the function we wish to execute. Prepare()
    // must be called on the context before each new script function that will be
    // executed. Note, that if you intend to execute the same function several
    // times, it might be a good idea to store the function returned by
    // GetFunctionByDecl(), so that this relatively slow call can be skipped.
    r = ctx->Prepare(func);
    if( r < 0 )
    {
        cout << "Failed to prepare the context." << endl;
        ctx->Release();
        engine->Release();
        return -1;
    }

    // Now we need to pass the parameters to the script function.
    ctx->SetArgFloat(0, 3.14159265359f);
    ctx->SetArgFloat(1, 2.71828182846f);

    // Set the timeout before executing the function. Give the function 1 sec
    // to return before we'll abort it.
    timeOut = timeGetTime() + 1000;

    // Execute the function
    cout << "Executing the script." << endl;
    cout << "---" << endl;
    r = ctx->Execute();
    cout << "---" << endl;
    if( r != asEXECUTION_FINISHED )
    {
        // The execution didn't finish as we had planned. Determine why.
        if( r == asEXECUTION_ABORTED )
            cout << "The script was aborted before it could finish. Probably it timed out." << endl;
        else if( r == asEXECUTION_EXCEPTION )
        {
            cout << "The script ended with an exception." << endl;

            // Write some information about the script exception
            asIScriptFunction *func = ctx->GetExceptionFunction();
            cout << "func: " << func->GetDeclaration() << endl;
            cout << "modl: " << func->GetModuleName() << endl;
            cout << "sect: " << func->GetScriptSectionName() << endl;
            cout << "line: " << ctx->GetExceptionLineNumber() << endl;
            cout << "desc: " << ctx->GetExceptionString() << endl;
        }
        else
            cout << "The script ended for some unforeseen reason (" << r << ")." << endl;
    }
    else
    {
        // Retrieve the return value from the context
        float returnValue = ctx->GetReturnFloat();
        cout << "The script function returned: " << returnValue << endl;
    }

    // We must release the contexts when no longer using them
    ctx->Release();

    // Release the engine
    engine->Release();

    return 0;
}

void ConfigureEngine(asIScriptEngine *engine)
{
    int r;

    // Register the script string type
    // Look at the implementation for this function for more information 
    // on how to register a custom string type, and other object types.
    RegisterStdString(engine);

    if( !strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY") )
    {
        // Register the functions that the scripts will be allowed to use.
        // Note how the return code is validated with an assert(). This helps
        // us discover where a problem occurs, and doesn't pollute the code
        // with a lot of if's. If an error occurs in release mode it will
        // be caught when a script is being built, so it is not necessary
        // to do the verification here as well.
        r = engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString), asCALL_CDECL); assert( r >= 0 );
        r = engine->RegisterGlobalFunction("uint GetSystemTime()", asFUNCTION(timeGetTime), asCALL_STDCALL); assert( r >= 0 );
    }
    else
    {
        // Notice how the registration is almost identical to the above.
        r = engine->RegisterGlobalFunction("void Print(string &in)", asFUNCTION(PrintString_Generic), asCALL_GENERIC); assert( r >= 0 );
        r = engine->RegisterGlobalFunction("uint GetSystemTime()", asFUNCTION(timeGetTime_Generic), asCALL_GENERIC); assert( r >= 0 );
    }


    // It is possible to register the functions, properties, and types in
    // configuration groups as well. When compiling the scripts it then
    // be defined which configuration groups should be available for that
    // script. If necessary a configuration group can also be removed from
    // the engine, so that the engine configuration could be changed
    // without having to recompile all the scripts.
}

int CompileScript(asIScriptEngine *engine)
{
    int r;

    // We will load the script from a file on the disk.
    FILE *f = fopen("script.as", "rb");
    if( f == 0 )
    {
        cout << "Failed to open the script file 'script.as'." << endl;
        return -1;
    }

    // Determine the size of the file   
    fseek(f, 0, SEEK_END);
    int len = ftell(f);
    fseek(f, 0, SEEK_SET);

    // On Win32 it is possible to do the following instead
    // int len = _filelength(_fileno(f));

    // Read the entire file
    string script;
    script.resize(len);
    int c =    fread(&script[0], len, 1, f);
    fclose(f);

    if( c == 0 )
    {
        cout << "Failed to load script file." << endl;
        return -1;
    }

    // Add the script sections that will be compiled into executable code.
    // If we want to combine more than one file into the same script, then
    // we can call AddScriptSection() several times for the same module and
    // the script engine will treat them all as if they were one. The script
    // section name, will allow us to localize any errors in the script code.
    asIScriptModule *mod = engine->GetModule(0, asGM_ALWAYS_CREATE);
    r = mod->AddScriptSection("script", &script[0], len);
    if( r < 0 )
    {
        cout << "AddScriptSection() failed" << endl;
        return -1;
    }
   
    // Compile the script. If there are any compiler messages they will
    // be written to the message stream that we set right after creating the
    // script engine. If there are no errors, and no warnings, nothing will
    // be written to the stream.
    r = mod->Build();
    if( r < 0 )
    {
        cout << "Build() failed" << endl;
        return -1;
    }

    // The engine doesn't keep a copy of the script sections after Build() has
    // returned. So if the script needs to be recompiled, then all the script
    // sections must be added again.

    // If we want to have several scripts executing at different times but
    // that have no direct relation with each other, then we can compile them
    // into separate script modules. Each module use their own namespace and
    // scope, so function names, and global variables will not conflict with
    // each other.

    return 0;
}

void LineCallback(asIScriptContext *ctx, DWORD *timeOut)
{
    // If the time out is reached we abort the script
    if( *timeOut < timeGetTime() )
        ctx->Abort();

    // It would also be possible to only suspend the script,
    // instead of aborting it. That would allow the application
    // to resume the execution where it left of at a later
    // time, by simply calling Execute() again.
}

// Function implementation with native calling convention
void PrintString(string &str)
{
    cout << str;
}

// Function implementation with generic script interface
void PrintString_Generic(asIScriptGeneric *gen)
{
    string *str = (string*)gen->GetArgAddress(0);
    cout << *str;
}

// Function wrapper is needed when native calling conventions are not supported
void timeGetTime_Generic(asIScriptGeneric *gen)
{
    gen->SetReturnDWord(timeGetTime());
}
Do any of you know how to fix this? I have installed angelscript with the following commands:
cd angelscript
cd sdk
cd angelscript\projects\gnuc
make -s
make install -s
Can someone tell me how to get this to compile correctly?
P.s. I have actually changed the makefile so that it compiles and adds libs into /usr/lib and include files in /usr/include but still no luck. It does compile correctly, though.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2014-10-11 19:13:19

You need to get the path to the folder containing the Angelscript headers on your include path and the path to the Angellscript libraries on your linker path.  The second hasn't hit you yet but will just as soon as you resolve the first.
There are two ways of doing this: compiler options and environment variables.  For large projects, one typically uses something like cmake that handles all of this for you.  Environment variables are kind of awful in this case, and you'd need to write batch scripts.  I haven't done this in a year--even my example projects get tiny CMakeLists.txt files these days.
So, something like,
c myfile.cpp angelscript_lib.lib /I path_to_angelscript_headers /link /LIBPATH:path_to_angelscript_libraries
I'm not 100% sure this is right, and I'm not set up to test.  You may have some better luck copying the Angelscript libs and dlls to live beside your source code-the compiler always looks in the current directory.  You can do this for headers too, but that's bad practice because they're not "your" code.
If you go into C++ heavily, then you may want to look at cmake.  Scons works but is much more complicated.  Also, Angelscript aught to be providing you a way to build the examples as part of the rest of the build; is it not?

My Blog
Twitter: @ajhicks1992

2014-10-11 19:37:52

No, its not. What about GCC? I'm using GCC, not MSVC. Would the compiler options be something like gcc -o main.exe main.cpp -L/usr/lib -I/usr/include -wl,-L/usr/lib

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2014-10-11 22:27:09

yeah. That should do it or be pretty close to what you need.

My Blog
Twitter: @ajhicks1992

2014-10-12 00:16:36

Okay.OK

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github

2014-10-12 05:12:05

hi,
you need to copy libangelscript.a to your compiler lib directory and angelscript.h, addons/*/*.h to your include directory or use

gcc -c main.cpp -o main.o -i your_include_dir
gcc main.o -o main.exe -Lyour_lib_directory -langelscript

2014-10-17 16:18:24

HEH, A real programmer should know that, but W/E.

Dreaming of a dystopian future.

2014-10-17 16:37:42

@visualstudio, thanks for that. But the assembler still gives me errors which I'm not willing to resolve because I don't know assembly language.
@dglex, Your comment was completely uncalled for. Please delete it; it will save you 1 (one) or more moderator warnings.

"On two occasions I have been asked [by members of Parliament!]: 'Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out ?' I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question."    — Charles Babbage.
My Github