Emscripten: Module not found: Can't resolve 'env' - c++

I am trying to compile a small project which references a static library (.a) in /usr/local/lib and it's header (.h) files in /usr/local/include/test into a standalone wasm file. The following code runs fine with no compilation errors.
main.cpp
#include <iostream>
#include "libtest/libtest.h"
int main(int argc, char *argv[]) {
LibTest Test;
std::cout << Test.version() << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(test_project)
set(CMAKE_CXX_STANDARD 14)
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} test)
However, when I compile into wasm using the following command:
emcc main.cpp -I/usr/local/include -Os -s WASM=1 -s SIDE_MODULE=1 -o main.wasm
I get the error: Module not found: Can't resolve 'env' when importing the wasm file into the client application.
Here's how I'm importing it:
const Component = dynamic({
loader: async () => {
const module = await import("../../main.wasm");
},
ssr: false,
});
NOTE: This will work fine if remove the imported library and do just about anything else (e.g. the Hello World or add(x, y) function examples.)
Anyone ran into this problem?
I'm assuming that the emcc command I am running is failing to compile the library correctly.

You are compiling it into pure Wasm but the C++ code contains functions without a Wasm equivalent; they have to be replaced with JavaScript equivalents and "imported" into the Wasm.
This is normally done by Emscripten but you are telling it not to do this when you specify that you want a standalone Wasm file.

Related

Using CMake and Clang++ with C++20 Modules support [duplicate]

Clang and MSVC already supports Modules TS from unfinished C++20 standard.
Can I build my modules based project with CMake or other build system and how?
I tried build2, it supports modules and it works very well, but i have a question about it's dependency management (UPD: question is closed).
CMake currently does not support C++20 modules.
See also the relevant issue in the CMake issue tracker. Note that supporting modules requires far more support from the build system than inserting a new compiler option. It fundamentally changes how dependencies between source files have to be handled during the build: In a pre-modules world all cpp source files can be built independently in any order. With modules that is no longer true, which has implications not only for CMake itself, but also for the downstream build system.
Take a look at the CMake Fortran modules paper for the gory details. From a build system's point of view, Fortran's modules behave very similar to the C++20 modules.
Update: CMake 3.20 introduces experimental support for Modules with the Ninja Generator (and only for Ninja). Details can be found in the respective pull request. At this stage, this feature is still highly experimental and not intended for production use. If you intend to play around with this anyway, you really should be reading both the Fortran modules paper and the dependency format paper to understand what you're getting into.
This works on Linux Manjaro (same as Arch), but should work on any Unix OS. Of course, you need to build with new clang (tested with clang-10).
helloworld.cpp:
export module helloworld;
import <cstdio>;
export void hello() { puts("Hello world!"); }
main.cpp:
import helloworld; // import declaration
int main() {
hello();
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(main)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(PREBUILT_MODULE_PATH ${CMAKE_BINARY_DIR}/modules)
function(add_module name)
file(MAKE_DIRECTORY ${PREBUILT_MODULE_PATH})
add_custom_target(${name}.pcm
COMMAND
${CMAKE_CXX_COMPILER}
-std=c++20
-stdlib=libc++
-fmodules
-c
${CMAKE_CURRENT_SOURCE_DIR}/${ARGN}
-Xclang -emit-module-interface
-o ${PREBUILT_MODULE_PATH}/${name}.pcm
)
endfunction()
add_compile_options(-fmodules)
add_compile_options(-stdlib=libc++)
add_compile_options(-fbuiltin-module-map)
add_compile_options(-fimplicit-module-maps)
add_compile_options(-fprebuilt-module-path=${PREBUILT_MODULE_PATH})
add_module(helloworld helloworld.cpp)
add_executable(main
main.cpp
helloworld.cpp
)
add_dependencies(main helloworld.pcm)
Assuming that you're using gcc 11 with a Makefile generator, the following code should work even without CMake support for C++20:
cmake_minimum_required(VERSION 3.19) # Lower versions should also be supported
project(cpp20-modules)
# Add target to build iostream module
add_custom_target(std_modules ALL
COMMAND ${CMAKE_COMMAND} -E echo "Building standard library modules"
COMMAND g++ -fmodules-ts -std=c++20 -c -x c++-system-header iostream
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
# Function to set up modules in GCC
function (prepare_for_module TGT)
target_compile_options(${TGT} PUBLIC -fmodules-ts)
set_property(TARGET ${TGT} PROPERTY CXX_STANDARD 20)
set_property(TARGET ${TGT} PROPERTY CXX_EXTENSIONS OFF)
add_dependencies(${TGT} std_modules)
endfunction()
# Program name and sources
set (TARGET prog)
set (SOURCES main.cpp)
set (MODULES mymod.cpp)
# Setup program modules object library
set (MODULE_TARGET prog-modules)
add_library(${MODULE_TARGET} OBJECT ${MODULES})
prepare_for_module(${MODULE_TARGET})
# Setup executable
add_executable(${TARGET} ${SOURCES})
prepare_for_module(${TARGET})
# Add modules to application using object library
target_link_libraries(${TARGET} PRIVATE ${MODULE_TARGET})
Some explanation:
A custom target is added to build the standard library modules, in case you want to include standard library header units (search for "Standard Library Header Units" here). For simplicity, I just added iostream here.
Next, a function is added to conveniently enable C++20 and Modules TS for targets
We first create an object library to build the user modules
Finally, we create our executable and link it to the object library created in the previous step.
Not consider the following main.cpp:
import mymod;
int main() {
helloModule();
}
and mymod.cpp:
module;
export module mymod;
import <iostream>;
export void helloModule() {
std::cout << "Hello module!\n";
}
Using the above CMakeLists.txt, your example should compile fine (successfully tested in Ubuntu WSL with gcc 1.11.0).
Update:
Sometimes when changing the CMakeLists.txt and recompiling, you may encounter an error
error: import "/usr/include/c++/11/iostream" has CRC mismatch
Probably the reason is that every new module will attempt to build the standard library modules, but I'm not sure. Unfortunately I didn't find a proper solution to this (avoiding rebuild if the gcm.cache directory already exists is bad if you want to add new standard modules, and doing it per-module is a maintenance nightmare). My Q&D solution is to delete ${CMAKE_BINARY_DIR}/gcm.cache and rebuild the modules. I'm happy for better suggestions though.
CMake ships with experimental support for C++20 modules:
https://gitlab.kitware.com/cmake/cmake/-/blob/master/Help/dev/experimental.rst
This is tracked in this issue:
https://gitlab.kitware.com/cmake/cmake/-/issues/18355
There is also a CMakeCXXModules repository that adds support for modules to CMake.
https://github.com/NTSFka/CMakeCxxModules
While waiting for proper C++20 modules support in CMake, I've found that if using MSVC Windows, for right now you can make-believe it's there by hacking around the build instead of around CMakeLists.txt: continously generate with latest VS generator, and open/build the .sln with VS2020. The IFC dependency chain gets taken care of automatically (import <iostream>; just works). Haven't tried Windows clang or cross-compiling. It's not ideal but for now at least another decently workable alternative today, so far.
Important afterthought: use .cppm and .ixx extensions.
CMake does not currently support C++20 modules like the others have stated. However, module support for Fortran is very similar, and perhaps this could be easily changed to support modules in C++20.
http://fortranwiki.org/fortran/show/Build+tools
Now, perhaps there i an easy way to modify this to support C++20 directly. Not sure. It is worth exploring and doing a pull request should you resolve it.
Add MSVC version (revised from #warchantua 's answer):
cmake_minimum_required(VERSION 3.16)
project(Cpp20)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(PREBUILT_MODULE_DIR ${CMAKE_BINARY_DIR}/modules)
set(STD_MODULES_DIR "D:/MSVC/VC/Tools/MSVC/14.29.30133/ifc/x64") # macro "$(VC_IFCPath)" in MSVC
function(add_module name)
file(MAKE_DIRECTORY ${PREBUILT_MODULE_DIR})
add_custom_target(${name}.ifc
COMMAND
${CMAKE_CXX_COMPILER}
/std:c++latest
/stdIfcDir ${STD_MODULES_DIR}
/experimental:module
/c
/EHsc
/MD
${CMAKE_CURRENT_SOURCE_DIR}/${ARGN}
/module:export
/ifcOutput
${PREBUILT_MODULE_DIR}/${name}.ifc
/Fo${PREBUILT_MODULE_DIR}/${name}.obj
)
endfunction()
set(CUSTOM_MODULES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/modules)
add_module(my_module ${CUSTOM_MODULES_DIR}/my_module.ixx)
add_executable(test
test.cpp
)
target_compile_options(test
BEFORE
PRIVATE
/std:c++latest
/experimental:module
/stdIfcDir ${STD_MODULES_DIR}
/ifcSearchDir ${PREBUILT_MODULE_DIR}
/reference my_module=${PREBUILT_MODULE_DIR}/my_module.ifc
/EHsc
/MD
)
target_link_libraries(test ${PREBUILT_MODULE_DIR}/my_module.obj)
add_dependencies(test my_module.ifc)
With C++20 Modules the file compilation order matters, which is totally new. That's why the implementation is complicated and still experimental in 2023. Please read the authors blogpost
I was not able to find Cmake support for modules. Here is an example how to use modules using clang. I am using Mac and this example works ok on my system. It took me quite a while to figure this out so unsure how general this is across linux or Windows.
Source code in file driver.cxx
import hello;
int main() { say_hello("Modules"); }
Source code in file hello.cxx
#include <iostream>
module hello;
void say_hello(const char *n) {
std::cout << "Hello, " << n << "!" << std::endl;
}
Source code in file hello.mxx
export module hello;
export void say_hello (const char* name);
And to compile the code with above source files, here are command lines on terminal
clang++ \
-std=c++2a \
-fmodules-ts \
--precompile \
-x c++-module \
-Xclang -fmodules-embed-all-files \
-Xclang -fmodules-codegen \
-Xclang -fmodules-debuginfo \
-o hello.pcm hello.mxx
clang++ -std=c++2a -fmodules-ts -o hello.pcm.o -c hello.pcm
clang++ -std=c++2a -fmodules-ts -x c++ -o hello.o \
-fmodule-file=hello.pcm -c hello.cxx
clang++ -std=c++2a -fmodules-ts -x c++ -o driver.o \
-fmodule-file=hello=hello.pcm -c driver.cxx
clang++ -o hello hello.pcm.o driver.o hello.o
and to get clean start on next compile
rm -f *.o
rm -f hello
rm -f hello.pcm
expected output
./hello
Hello, Modules!
Hope this helps, all the best.

How to use c++20 modules with CMake?

Clang and MSVC already supports Modules TS from unfinished C++20 standard.
Can I build my modules based project with CMake or other build system and how?
I tried build2, it supports modules and it works very well, but i have a question about it's dependency management (UPD: question is closed).
CMake currently does not support C++20 modules.
See also the relevant issue in the CMake issue tracker. Note that supporting modules requires far more support from the build system than inserting a new compiler option. It fundamentally changes how dependencies between source files have to be handled during the build: In a pre-modules world all cpp source files can be built independently in any order. With modules that is no longer true, which has implications not only for CMake itself, but also for the downstream build system.
Take a look at the CMake Fortran modules paper for the gory details. From a build system's point of view, Fortran's modules behave very similar to the C++20 modules.
Update: CMake 3.20 introduces experimental support for Modules with the Ninja Generator (and only for Ninja). Details can be found in the respective pull request. At this stage, this feature is still highly experimental and not intended for production use. If you intend to play around with this anyway, you really should be reading both the Fortran modules paper and the dependency format paper to understand what you're getting into.
This works on Linux Manjaro (same as Arch), but should work on any Unix OS. Of course, you need to build with new clang (tested with clang-10).
helloworld.cpp:
export module helloworld;
import <cstdio>;
export void hello() { puts("Hello world!"); }
main.cpp:
import helloworld; // import declaration
int main() {
hello();
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(main)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(PREBUILT_MODULE_PATH ${CMAKE_BINARY_DIR}/modules)
function(add_module name)
file(MAKE_DIRECTORY ${PREBUILT_MODULE_PATH})
add_custom_target(${name}.pcm
COMMAND
${CMAKE_CXX_COMPILER}
-std=c++20
-stdlib=libc++
-fmodules
-c
${CMAKE_CURRENT_SOURCE_DIR}/${ARGN}
-Xclang -emit-module-interface
-o ${PREBUILT_MODULE_PATH}/${name}.pcm
)
endfunction()
add_compile_options(-fmodules)
add_compile_options(-stdlib=libc++)
add_compile_options(-fbuiltin-module-map)
add_compile_options(-fimplicit-module-maps)
add_compile_options(-fprebuilt-module-path=${PREBUILT_MODULE_PATH})
add_module(helloworld helloworld.cpp)
add_executable(main
main.cpp
helloworld.cpp
)
add_dependencies(main helloworld.pcm)
Assuming that you're using gcc 11 with a Makefile generator, the following code should work even without CMake support for C++20:
cmake_minimum_required(VERSION 3.19) # Lower versions should also be supported
project(cpp20-modules)
# Add target to build iostream module
add_custom_target(std_modules ALL
COMMAND ${CMAKE_COMMAND} -E echo "Building standard library modules"
COMMAND g++ -fmodules-ts -std=c++20 -c -x c++-system-header iostream
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
# Function to set up modules in GCC
function (prepare_for_module TGT)
target_compile_options(${TGT} PUBLIC -fmodules-ts)
set_property(TARGET ${TGT} PROPERTY CXX_STANDARD 20)
set_property(TARGET ${TGT} PROPERTY CXX_EXTENSIONS OFF)
add_dependencies(${TGT} std_modules)
endfunction()
# Program name and sources
set (TARGET prog)
set (SOURCES main.cpp)
set (MODULES mymod.cpp)
# Setup program modules object library
set (MODULE_TARGET prog-modules)
add_library(${MODULE_TARGET} OBJECT ${MODULES})
prepare_for_module(${MODULE_TARGET})
# Setup executable
add_executable(${TARGET} ${SOURCES})
prepare_for_module(${TARGET})
# Add modules to application using object library
target_link_libraries(${TARGET} PRIVATE ${MODULE_TARGET})
Some explanation:
A custom target is added to build the standard library modules, in case you want to include standard library header units (search for "Standard Library Header Units" here). For simplicity, I just added iostream here.
Next, a function is added to conveniently enable C++20 and Modules TS for targets
We first create an object library to build the user modules
Finally, we create our executable and link it to the object library created in the previous step.
Not consider the following main.cpp:
import mymod;
int main() {
helloModule();
}
and mymod.cpp:
module;
export module mymod;
import <iostream>;
export void helloModule() {
std::cout << "Hello module!\n";
}
Using the above CMakeLists.txt, your example should compile fine (successfully tested in Ubuntu WSL with gcc 1.11.0).
Update:
Sometimes when changing the CMakeLists.txt and recompiling, you may encounter an error
error: import "/usr/include/c++/11/iostream" has CRC mismatch
Probably the reason is that every new module will attempt to build the standard library modules, but I'm not sure. Unfortunately I didn't find a proper solution to this (avoiding rebuild if the gcm.cache directory already exists is bad if you want to add new standard modules, and doing it per-module is a maintenance nightmare). My Q&D solution is to delete ${CMAKE_BINARY_DIR}/gcm.cache and rebuild the modules. I'm happy for better suggestions though.
CMake ships with experimental support for C++20 modules:
https://gitlab.kitware.com/cmake/cmake/-/blob/master/Help/dev/experimental.rst
This is tracked in this issue:
https://gitlab.kitware.com/cmake/cmake/-/issues/18355
There is also a CMakeCXXModules repository that adds support for modules to CMake.
https://github.com/NTSFka/CMakeCxxModules
While waiting for proper C++20 modules support in CMake, I've found that if using MSVC Windows, for right now you can make-believe it's there by hacking around the build instead of around CMakeLists.txt: continously generate with latest VS generator, and open/build the .sln with VS2020. The IFC dependency chain gets taken care of automatically (import <iostream>; just works). Haven't tried Windows clang or cross-compiling. It's not ideal but for now at least another decently workable alternative today, so far.
Important afterthought: use .cppm and .ixx extensions.
CMake does not currently support C++20 modules like the others have stated. However, module support for Fortran is very similar, and perhaps this could be easily changed to support modules in C++20.
http://fortranwiki.org/fortran/show/Build+tools
Now, perhaps there i an easy way to modify this to support C++20 directly. Not sure. It is worth exploring and doing a pull request should you resolve it.
Add MSVC version (revised from #warchantua 's answer):
cmake_minimum_required(VERSION 3.16)
project(Cpp20)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(PREBUILT_MODULE_DIR ${CMAKE_BINARY_DIR}/modules)
set(STD_MODULES_DIR "D:/MSVC/VC/Tools/MSVC/14.29.30133/ifc/x64") # macro "$(VC_IFCPath)" in MSVC
function(add_module name)
file(MAKE_DIRECTORY ${PREBUILT_MODULE_DIR})
add_custom_target(${name}.ifc
COMMAND
${CMAKE_CXX_COMPILER}
/std:c++latest
/stdIfcDir ${STD_MODULES_DIR}
/experimental:module
/c
/EHsc
/MD
${CMAKE_CURRENT_SOURCE_DIR}/${ARGN}
/module:export
/ifcOutput
${PREBUILT_MODULE_DIR}/${name}.ifc
/Fo${PREBUILT_MODULE_DIR}/${name}.obj
)
endfunction()
set(CUSTOM_MODULES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/modules)
add_module(my_module ${CUSTOM_MODULES_DIR}/my_module.ixx)
add_executable(test
test.cpp
)
target_compile_options(test
BEFORE
PRIVATE
/std:c++latest
/experimental:module
/stdIfcDir ${STD_MODULES_DIR}
/ifcSearchDir ${PREBUILT_MODULE_DIR}
/reference my_module=${PREBUILT_MODULE_DIR}/my_module.ifc
/EHsc
/MD
)
target_link_libraries(test ${PREBUILT_MODULE_DIR}/my_module.obj)
add_dependencies(test my_module.ifc)
With C++20 Modules the file compilation order matters, which is totally new. That's why the implementation is complicated and still experimental in 2023. Please read the authors blogpost
I was not able to find Cmake support for modules. Here is an example how to use modules using clang. I am using Mac and this example works ok on my system. It took me quite a while to figure this out so unsure how general this is across linux or Windows.
Source code in file driver.cxx
import hello;
int main() { say_hello("Modules"); }
Source code in file hello.cxx
#include <iostream>
module hello;
void say_hello(const char *n) {
std::cout << "Hello, " << n << "!" << std::endl;
}
Source code in file hello.mxx
export module hello;
export void say_hello (const char* name);
And to compile the code with above source files, here are command lines on terminal
clang++ \
-std=c++2a \
-fmodules-ts \
--precompile \
-x c++-module \
-Xclang -fmodules-embed-all-files \
-Xclang -fmodules-codegen \
-Xclang -fmodules-debuginfo \
-o hello.pcm hello.mxx
clang++ -std=c++2a -fmodules-ts -o hello.pcm.o -c hello.pcm
clang++ -std=c++2a -fmodules-ts -x c++ -o hello.o \
-fmodule-file=hello.pcm -c hello.cxx
clang++ -std=c++2a -fmodules-ts -x c++ -o driver.o \
-fmodule-file=hello=hello.pcm -c driver.cxx
clang++ -o hello hello.pcm.o driver.o hello.o
and to get clean start on next compile
rm -f *.o
rm -f hello
rm -f hello.pcm
expected output
./hello
Hello, Modules!
Hope this helps, all the best.

CMake project for Emscripten

I want to make CMake and Emscripten friends. Didn't find more or less informative documentation on the Emscripten project website, but they provide CMake toolchain file so I think it should be possible.
So far very basic compilation without advanced parameters works fine, but I have issues while using embind and preloading files.
Linking process seems to miss Emscripten "binaries" and produces warnings for all embind related functions like this one: warning: unresolved symbol: _embind_register_class which results in respective errors while loading compiled JS file in rowser.
No .data file is generated during the compilation.
I've created a minimalistic example which includes two targets: one "normal" (client) and one manual (manual-client) which simply runs emcc as I expect it to be run: https://github.com/xwaffelx/minimal-cmake-emscripten-project/blob/master/README.md
Although manual way works, I don't think it is a proper way to do it...
--- Update ---
As requested, here is even more short example:
CMakeLists.txt file
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0015 NEW)
project(emtest)
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build.emscripten)
include_directories("lib/assimp/include")
link_directories("lib/assimp/lib-js")
link_libraries("assimp")
file(GLOB_RECURSE CORE_HDR src/.h)
file(GLOB_RECURSE CORE_SRC src/.cpp)
add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
add_executable(client ${CORE_SRC} ${CORE_HDR})
Result should be equivalent to running the following command manualy:
emcc
-Ilib/assimp/include
-s DEMANGLE_SUPPORT=1
--preload-file assets
--bind
Application.cpp
lib/assimp/lib-js/libassimp.so
-o client.js
Here is the Application.cpp:
#include "Application.h"
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
void Application::Initialize() {
std::cout << "Initializing application." << std::endl;
Assimp::Importer importer; // For test purpose
}
void Application::SayHello() {
std::cout << "Hello!" << std::endl;
}
and Application.h:
#ifndef APPLICATION_H
#define APPLICATION_H
#include <emscripten/html5.h>
#include <emscripten/bind.h>
namespace e = emscripten;
class Application {
public:
void Initialize();
void SayHello();
};
EMSCRIPTEN_BINDINGS(EMTest) {
e::class_<Application>("Application")
.constructor()
.function("Initialize", &Application::Initialize)
.function("SayHello", &Application::SayHello);
}
#endif
THen I run cmake as follows:
cmake -DCMAKE_TOOLCHAIN_PATH=path/to/Emscripten.cmake .. && make
However, warnings like warning: unresolved symbol: _embind_register_class are produced during linking and running the code and no preloaded data in client.data file is created while compiling CMake project. At the same time no warnings and everything runs OK while compiling manually.
The solution was to specify all the flags during the linking by providing following CMake instruction:
set_target_properties(client PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")
Thanks to developers of emscripten who helped in the github issues tracker.

undefined reference to glfwSetErrorCallback

I'm trying to use the GLFW library, but am having difficulty with compiling a simple program. I went to the GLFW website and download the latest release, then using "How to build & install GLFW 3 and use it in a Linux project" I built and installed it.
Here's my code:
#include <GLFW/glfw3.h>
#include <iostream>
using std::cout;
using std::endl;
void GLFW_error(int error, const char* description)
{
fputs(description, stderr);
}
void run()
{
cout << "pooch" << endl;
}
int main()
{
glfwSetErrorCallback(GLFW_error);
if (!glfwInit()) exit(EXIT_FAILURE);
run();
glfwTerminate();
return 0;
}
Using the command line:
bulletbill22#ROBOTRON ~/Desktop $ g++ -std=c++11 -lglfw source.cpp
yields
source.cpp:function main: error: undefined reference to 'glfwSetErrorCallback'
glfwSetErrorCallback is taken from their tutorial for "Setting an error callback".
Inclusion of -glfw3 results in /usr/bin/ld: error: cannot find -lglfw3
Even though everything seemed to be installed correctly, I suspect the problem may lie somewhere with the installation of the GLFW library because I'm not used to CMake and don't entirely understand how it works. I'm frustrated because the answer must be simple, but I'm not sure which keywords are really relevant when googling the problem; mostly the results are people who were incorrectly compiling with CMake, which I'm not compiling with in this case.
It seems that the directories for the glfw3.h header and libglfw3.so (and/or libglfw3.a) library are not in the default path.
You can check with by adding the -v option to the g++ options. Locate the directory where the glfw3.h header is found - call this $GLFW_INCDIR - it typically ends with .../GLFW. Locate the directory where the library is found - call this $GLFW_LIBDIR. Try:
g++ -std=c++11 -I$GLFW_INCDIR source.cpp -o pooch -L$GLFW_LIBDIR -lglfw3
If all the library dependencies are satisfied, this hopefully results in a program called pooch.
One other thing: GLFW3 is a C library, and the callback function arguments are expected to be C functions. So your callback should have 'C' linkage, i.e.,
extern "C" void GLFW_error(int error, const char* description) ...
Also, if you're having trouble with cmake, you may have ccmake installed. Try ccmake . in the top-level directory of the GLFW3 package for 'interactive' configuration.

How to use wxwidget2.9.2 in linux

I am new to wxWidgets
My platform is fedora 16,gcc 4.6.2 editor is vim
I download the wxwidget.gz.tar file on sourceforge, and tried to compile.
I typed ./configure --with-gtk --enable-unicode --disable-shared in bash, and make install and the wxwidget install is finished.
I tried to comile a file: test.cpp
Here are the contents of the file:
#include <wx/wx.h>
int main()
{
return 0;
}//i have copied the head file folder to /usr/include/wx
use gcc -o
gcc shows the wx/platform.h:wx/setup.h, no such file
How do I solve this?
You should use wx-config --cxxflags and wx-config --libs to get the include paths, flags and libraries you need in order to compile.
To elaborate more: you need to tell the compiler where to find the include files and what libraries need to be linked. wx-config is a convenience program that will give you that information. On my system the output from wx-config looks like this:
-I/usr/local/lib/wx/include/gtk2-unicode-2.9 -I/usr/local/include/wx-2.9 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread -L/usr/local/lib -pthread -lwx_gtk2u_xrc-2.9 -lwx_gtk2u_html-2.9 -lwx_gtk2u_qa-2.9 -lwx_gtk2u_adv-2.9 -lwx_gtk2u_core-2.9 -lwx_baseu_xml-2.9 -lwx_baseu_net-2.9 -lwx_baseu-2.9
Let's take this minimalistic wxWidgets application:
#include <wx/app.h>
#include <wx/frame.h>
/** Main application class.
* This class is derived from the main wxWidgets application class.
*/
class MyApp : public wxApp
{
public:
/// Initialization function. Called at startup.
virtual bool OnInit();
virtual ~MyApp();
};
DECLARE_APP(MyApp);
IMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
wxFrame* MainFrame = new wxFrame(NULL, wxID_ANY, wxT("MyApp"));
MainFrame->Show();
return true;
}
MyApp::~MyApp() {}
You can compile this using the following call:
gcc OUTPUT_OF_WX-CONFIG test.cpp -o test
where OUTPUT_OF_WX-CONFIG is the flags and library directories like above and test.cpp contains the above source code. If you wxWidgets installation is setup properly this should compile and run fine (will show an empty window).
I STRONGLY encourage you to use CMake for managing you wxWidgets application build process.
You can find LiMuBei's example app bundled with CMake configuration file here.
Just clone the project and follow the instructions int the "README" file.
git clone https://bitbucket.org/vizz/wxstartapp.git
The basic idea is to describe your project sources, dependencies and to use CMake to handle all the "gathering process" ( so that you don't have to worry about "wx-config" and its options ) through appropriate built-in macros/functions.
For example, to configure you wxWidgets project you would write:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(wxstartapp)
FIND_PACKAGE(wxWidgets REQUIRED core base)
IF(wxWidgets_FOUND)
INCLUDE(${wxWidgets_USE_FILE})
...some CMake stuff here...
INCLUDE_DIRECTORIES(
... some additional CMake stuff here...
${wxWidgets_INCLUDE_DIRS}
)
TARGET_LINK_LIBRARIES(wxstartapp ${wxWidgets_LIBRARIES})
ENDIF(wxWidgets_FOUND)
See the "CMakeLists.txt" file for yourself.