I want to build V8 and embed it in a C++ program to use SWIG to allow a Javascript app to call into the C++ library. However, after following the steps for building V8, I am missing some of the important libs for linking to V8 (e.g. V8_base.lib):
fetch v8
cd v8
git pull origin
gclient sync
python tools/dev/v8gen.py x64.release
ninja -C out.gn/x64.release
I have DEPOT_TOOLS_WIN_TOOLCHAIN = 0 and GYP_MSVS_VERSION = 2019.
My args.gn is the following (I have built with and without the last line):
is_debug = false
target_cpu = "x64"
is_component_build = false
v8_static_library = true
is_clang = false
use_lld = false
After a successful build, I find that there is no v8_base.lib file under out.gn\x64.release\obj as all of the docs indicate there should be. Strangely, I see a v8.stamp and v8_base.stamp files, but no corresponding *.lib. What am I missing? Are these libraries no longer needed for embedding into a C++ program?
Overview
The instructions on the website to build a sample app are a bit better than whatever instructions you're following now
The v8_base.a target was removed from the build.gn file here in april, 2019
Prerequisites
Python2 (Python3 For newer versions)
Git
Ninja
G++ (or clang)
Updated instructions for building v8 (on linux/macos)
Here are the steps I followed today to successfully compile and run v8
Install google's depot tools: git clone "https://chromium.googlesource.com/chromium/tools/depot_tools.git" ./depot_tools
Add the depot tools to your path export PATH=$(pwd)/depot_tools:$PATH
If you are building on windows, be sure to set DEPOT_TOOLS_WIN_TOOLCHAIN=0 as an environment variable
Download v8: fetch v8 OR fetch --no-history v8
Move into the v8 directory cd v8
Generate a release for your system (probably): tools/dev/v8gen.py x64.release
Run gn args out.gn/x64.release to the following build arguments:
is_debug = false
target_cpu = "x64"
use_custom_libcxx = false
v8_monolithic = true
v8_use_external_startup_data = false
is_clang = {whether or not you're using clang}
(* More here)
gn automatically regenerates build files when you close your editor
Build v8 (slow) ninja -C out.gn/x64.release
Using your newly created v8 library
In the root of your project directory create a folder called src and inside that folder create a new file main.cc which looks like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
int main(int argc, char* argv[]) {
v8::V8::InitializeICUDefaultLocation(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate); // Create a stack-allocated handle scope.
v8::Local<v8::Context> context = v8::Context::New(isolate); // Create a new context.
v8::Context::Scope context_scope(context); // Enter the context for compiling and running the hello world script.
{
v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "Object.keys({ h: 1, e: 2, ll: 3, o: 4, _: 5, w: 6, or: 7, l: 8, d: 9 })", v8::NewStringType::kNormal).ToLocalChecked(); // Create a string containing the JavaScript source code.
v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked(); // Compile the source code.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked(); // Run the script to get the result.
v8::String::Utf8Value utf8(isolate, result); // Convert the result to an UTF8 string and print it.
printf("%s\n", *utf8);
}
}
isolate->Dispose();
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
delete create_params.array_buffer_allocator;
return 0;
}
Build your source using the new monolithic library created in the ninja build: g++ -Iv8/include src/main.cc -o bin/my_program -lv8_monolith -Lv8/out.gn/x64.release.sample/obj/ -pthread -std=c++11
For this to work, your file structure should look something like
depot_tools
v8
src/main.cc
It will create a new executable in your bin folder called my_program which you can execute directly ./bin/my_program
Related
I've tried to get an audio library statically linked to my program. I use this nimble package. To get it run, i had to build the soloud library as described here. For short after download i ran "genie --with-miniaudio-only --platform=x64 vs2017" in the "build" folder and got the source code to generate the dynamic and the static library. For now i can run the following demo program from the nimble package with the generated dll alongside:
import solouddotnim, times, os
var i, spin = 0
var sl : ptr Soloud
sl = Soloud_create()
discard Soloud_init(sl)
Soloud_setGlobalVolume(sl, 1)
var stream = WavStream_create()
discard WavStream_load(cast[ptr Wav](stream), "test.ogg")
let currentTime = epochTime()
let length = WavStream_getLength(stream)
discard Soloud_play(cast[ptr Soloud](sl), cast[ptr Wav](stream))
while epochTime() - currentTime <= length:
sleep(100)
Soloud_deinit(sl)
Soloud_destroy(sl)
Now to the static-link part. In the solouddotnim.nim file of the nimble package i use, i see this part:
when defined(windows):
const
libname* = "libsoloud.dll"
elif ...
So i simple changed the windows part to the following, re-installed the nimble-package and placed the "soloud_static_x64.lib" alongside to the "main.nim" of the testproject:
when defined(windows):
const
libname* = "soloud_static_x64.lib"
elif ...
But this doesent make it. (cant open "soloud_static_x64.lib" error when build)
Evereywhere where the constant "libname" is used there are the pragmas "cdecl", "importc" and "dynlib". For example:
proc Soloud_create*(): ptr Soloud {.cdecl, importc: "Soloud_create", dynlib: libname.}
So "dynlib" is telling nim to use a dll on windows. But was is the pragma for static libraries?
In the nim documentations i only found DynlibOverride to link to static libraries, but i dont understand the example and here is where i stuck. I've tried the followings:
nim c --dynlibOverride:libname --passL:soloud_static_x64.lib "examples\00-ogg\Example00_ogg.nim"
nim c --dynlibOverride:soloudtotnim --passL:soloud_static_x64.lib "examples\00-ogg\Example00_ogg.nim"
Firstly i dont know what parameter dynlibOverride expects and secondly both compiles, but dont work. It expects a dynamic library alongside the exe.
My last try was to remove all dynlib pragmas from the nimble package. But now i cant compile it.
undefined reference to `Soloud_create'
...
Error: execution of an external program failed: 'gcc.exe...
My knowlege ends here. Can someone help me?
Thanks in advance.
Edit:
I could not get any of your solutions work. I break down the problem as small as possible so everybody can reproduce this:
"foo.nim" contains this:
proc add*(a, b: int): int {.cdecl, exportc.} =
a + b
proc sub*(a, b: int): int {.cdecl, exportc.} =
a - b
The .lib is simply generated with this command: "nim c --app:staticlib foo.nim"
Now to use it i created a file "main.nim" with this content:
{.passL:"foo.lib".}
proc add*(a, b: int):int {.cdecl, importc.}
proc sub*(a, b: int):int {.cdecl, importc.}
echo add(10, 5)
echo sub(10, 5)
if i simply build it with "nim c -r main.nim", i get the following output and error:
P:\Nim\LearnCBinding>nim c -r main.nim
Hint: used config file 'C:\nim-1.5.1\config\nim.cfg' [Conf]
Hint: used config file 'C:\nim-1.5.1\config\config.nims' [Conf]
....CC: stdlib_io.nim
CC: stdlib_system.nim
CC: main.nim
Hint: [Link]
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x1f6): multiple definition of `PreMainInner'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x120): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x20a): multiple definition of `PreMain'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x134): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x240): multiple definition of `NimMainInner'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x16f): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x254): multiple definition of `NimMain'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x183): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x285): multiple definition of `main'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x1b4): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x2da): multiple definition of `NimMainModule'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x209): first defined here
collect2.exe: error: ld returned 1 exit status
Error: execution of an external program failed: 'C:\nim-1.5.1\dist\mingw64\bin\gcc.exe -o P:\Nim\LearnCBinding\main.exe C:\Users\Peter\nimcache\main_d\stdlib_io.nim.c.o C:\Users\Peter\nimcache\main_d\stdlib_system.nim.c.o C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o foo.lib '
Because of the multiple definition error i also tried to build foo.lib with parameter "--noMain:on", but it doesnt make any difference.
Do you have the same problem? By the way i use the current version of Nim "nim-1.5.1" and reinstalled MingW with the finish.exe from nim.
I will try to help you with the following error you have:
undefined reference to `Soloud_create'
but i will assume that you have configured your environment so you can compile your nim programs with visual studio compiler (by adding --cc:vcc to your compile command)
this is because you already seem to have visual studio 2017 and you are compiling soloud static library with it. I think this is the best option when you are compiling with one compiler both: static library and executable that will use it.
open your static library (soloud_static_x64.lib) with some text/hex editor and search for "Soloud_create". i guess you will not find anything. so why is that? because for some reason author decided to not include "C interfacing" in a static library project. so it contains only C++ symbols and not pure C symbols that are needed for our solouddotnim.nim module.
let's try to find out what .cpp file we need for that. i noticed this information on official web site of Soloud - http://sol.gfxile.net/soloud/c_api.html
so i guess we need only one file: soloud_c.cpp
let's try to just include it in SoloudStatic.vcxproj file generated by you with Genie. like this:
..
<ClCompile Include="..\..\src\c_api\soloud_c.cpp">
</ClCompile>
..
and recompile our static library. i use this command in powershell:
& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\MSBuild.exe' /p:PlatformToolset=v142`;WindowsTargetPlatformVersion=10`;Configuration=Release`;Platform=x64 .\SoloudStatic.vcxproj
but you can compile how you want. just make sure that it's architecture is really x64. you can check it with this command:
dumpbin /headers soloud_static_x64.lib | more
finally just link it with your nim file. add this line to the top:
{.link:"soloud_static_x64.lib".}
and compile nim file with this command:
nim c --cc:vcc --dynlibOverride:libsoloud.dll -r "examples\00-ogg\Example00_ogg.nim"
As default, Forth has only a little amount of working libraries so that everything has to be programmed from scratch. The reason is, that the stackbased Forth virtual machine identifies itself as a slim system.
According to the Gforth manual, it's possible to use existing C libraries and get access to precompiled graphics libraries and game-engines written in C. Before it's possible to include the C library in Forth, it's a good idea to test the library within a normal C project.
I've created a library in C from scratch. It provides an add function and can be called from the main program. The files are compiled and linked and it works fine.
### add.c ###
int add(int a, int b) {
return a + b;
}
### add.h ###
int add(int, int);
### main.c ###
#include <stdio.h>
#include "add.h"
void main() {
printf("5 + 7 = %d\n", add(5,7));
}
### compile ###
gcc -c -fPIC add.c
gcc -c main.c
gcc main.o add.o
./a.out
5 + 7 = 12
The plan is to use this precompiled c-library from Forth. The Gforth compiler provides a special keyword for that purpose which connects a Forth program with a C library. Unfortunately, I get an error message saying that the library wasn't found. Even after copying it manually to the Gforth folder, the error message doesn't disappear.
### Forth source code ###
\c #include "add.h"
c-function add add n n -- n
5 7 add .
bye
### Execution ###
gforth "main.fs"
/home/user1/.gforth/libcc-tmp/gforth_c_7F5655710258.c:2:10: fatal error: add.h: No such file or directory
#include "add.h"
^~~~~~~
compilation terminated.
in file included from *OS command line*:-1
b.fs:3: libtool compile failed
5 7 >>>add<<< .
Backtrace:
$7F56556BD988 throw
$7F56556F9798 c(abort")
$7F56556F9F08 compile-wrapper-function
gforth: symbol lookup error: /home/user1/.gforth/libcc-tmp/.libs/gforth_c_7F0593846258.so.0: undefined symbol: add
### Copy missing file and execute again ###
cp add.h /home/user1/.gforth/libcc-tmp/
gforth "main.fs"
gforth: symbol lookup error: /home/user1/.gforth/libcc-tmp/.libs/gforth_c_7F5256AC2258.so.0: undefined symbol: add
What's wrong with the “Forth-to-C interface”?
You have to declare add as a function for export, compile it as a shared library (e.g. libadd.so) and add this library using the add-lib word, see Declaring OS-level libraries.
s" add" add-lib
NB: prefix 'lib' and suffix '.so' are added automatically.
I'm trying to build a project, using the DMD-compiler itself (without IDE) in Windows. And I found myself hardly capable to realise some moments about linking. Usually the IDE does this for me.
The structure of my project
project
├──bin
| ├──exemple.obj
| └──exemple.exe
└──src
├──a
| └──b.d
└──exemple.d
exemple.d
import a.b;
void main() { B obg = new B(); }
b.d
module a.b;
class B {
private int i;
public this() {i=0;}
public void act() {i++;}
}
At first it seemed to be easy to build with command:
cd C:\path\to\my\project
dmd bin\exemple.exe src\exemple.d -IC:\path\to\my\project\src
But it only showed me some error-massages:
OPTLINK (R) for Win32 Release 8.00.13
Copyright (C) Digital Mars 1989-2010 All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
bin\exemple.obj(exemple)
Error 42: Symbol Undefined _D1a1b1B7__ClassZ
bin\exemple.obj(exemple)
Error 42: Symbol Undefined _D1a1b1B6__ctorMFZC1a1b1B
--- errorlevel 2
Finally I guessed that the obj-file was missing. I made it manually with commands:
cd bin
dmd ..\src\a\b.d -c
cd ..
And manually added it to my build-command:
dmd bin\exemple.exe src\exemple.d -IC:\path\to\my\project\src bin\b.obj
And now it works.
Great. But what if we've got lots of additional d-files and complicated folders structure?
How could it be atomised?
I was strongly surprised, when I found out that DMD doesn't doing all this automatically. Maybe, I'm just doing it wrong.
You don't have to build a/b.d separately. But you do have to pass all source (or object) files to dmd. dmd does not figure out the dependencies.
Have a look at rdmd. It's a tool that does figure out the dependencies and then runs dmd on all of them (and then it runs the executable by default, --build-only prevents that). It comes with the dmd releases.
I have been trying to get GTK 3.0 to work, and have followed all the steps here
How to configure gtk on Visual studio 2010
And changing to 3.0 where needed to get GTK to work, and it seems to have loaded everything it needs in order to compile, but it gives me the error
Error 3 error LNK1104: cannot open file 'gtk-3.lib'
Whenever I try to run the program.
I am using visual studios 2012, but this was the only place i found anything about getting GTK to run on any visual studios.
Here is the code I am using:
#include <gtk-3.0\gtk\gtk.h>
int main(int argc, char* argv[])
{
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
//gtk_widget_get_preferred_size(window, 300, 200);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_window_set_title(GTK_WINDOW(window), "GTK+ with VS2010");
gtk_widget_show(window);
gtk_main();
return 0;
}
I commented out the gtk_widget_get_prefered_size call because it is irrelevant to the problem
any suggestions? I've looked in several places but none came up with clear answers.
The library gtk-3.lib does not exist. In fact, the library reference is not required to build your GTK 3 application. The pkg-config helper doesn't seem to generate the correct linker flags needed to link your application.
Just add in your Additional Options area all the existing libraries found in your GTK package (\gtk3\lib). The lib files for my bundle (gtk+-bundle_3.6.4-20130921) were as follows:
atk-1.0.lib cairo.lib fontconfig.lib gailutil.lib gdk-win32-3.0.lib gdk_pixbuf-2.0.lib gio-2.0.lib glib-2.0.lib gmodule-2.0.lib gobject-2.0.lib gthread-2.0.lib gtk-win32-3.0.lib pango-1.0.lib pangocairo-1.0.lib pangoft2-1.0.lib pangowin32-1.0.lib
(or you can go to your library path via a command prompt and enter dir *.lib /B)
Don't forget to include the /ENTRY:mainCRTStartup flag mention in the initial answer you started with.
you may have to edit your project settings or use a pragma comment to link with your gtk library:
#pragma comment(lib, "gtk-3")//if the libray is on your project's path
#define PATH "C:\\example\\"
#pragma comment(lib, PATH"gtk-3")//if the library is on PATH
I'm trying to create a shared library from Haskell source code.
I've tried following the instruction here: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/ but I'm just not having any luck.
When I compile with Haskell 64-bit (ghc 7.0.4 from 2011.4.0.0) I get the following error:
ld: pointer in read-only segment not allowed in slidable image, used in
___gmpn_modexact_1c_odd
As an alternative I also tried the 32-bit version, and depending on the exact flags I use to link get errors such as:
Library not loaded: /usr/local/lib/ghc-7.0.4/base-4.3.1.0/libHSbase-4.3.1.0-ghc7.0.4.dylib
I did manage to get a little further by adding -lHSrts to the linker line. This got me to the point of successfully linking and loading the library, but I'm then unable to find the function name using dlsym (or manually using nm | grep)
Any hints would be greatly appreciated, an example make file, or build line that has successfully built (and used) a shared library on OS X would be appreciated. I'm quite new to Haskell and don't know if I should keep banging my head assuming that the problem is on my end, or for various reasons I shouldn't expect this to work on OS X.
A git repo with all the combinations I've tried is available here: https://github.com/bennoleslie/haskell-shared-example I did manage to get something working for 32-bit ghc, but not 64-bit yet.
It is possible to create working shared libraries on 64-bit OS X, with the latest Haskell Platform release (2012.4 64bit)
The invocation line works for me:
ghc -O2 --make \
-no-hs-main -optl '-shared' -optc '-DMODULE=Test' \
-o libTest.so Test.hs module_init.c
module_init.c should be something like:
#define CAT(a,b) XCAT(a,b)
#define XCAT(a,b) a ## b
#define STR(a) XSTR(a)
#define XSTR(a) #a
#include <HsFFI.h>
extern void CAT(__stginit_, MODULE)(void);
static void library_init(void) __attribute__((constructor));
static void library_init(void)
{
/* This seems to be a no-op, but it makes the GHCRTS envvar work. */
static char *argv[] = { STR(MODULE) ".so", 0 }, **argv_ = argv;
static int argc = 1;
hs_init(&argc, &argv_);
hs_add_root(CAT(__stginit_, MODULE));
}
static void library_exit(void) __attribute__((destructor));
static void library_exit(void)
{
hs_exit();
}
This git repo: https://github.com/bennoleslie/haskell-shared-example contains a working example.
All credit goes to this original source: http://weblog.haskell.cz/pivnik/building-a-shared-library-in-haskell/
You might want to try the ghc port in Homebrew -- https://github.com/mxcl/homebrew/blob/master/Library/Formula/ghc.rb