Compile Linux OpenGL Application on Windows? - c++

I have made a OpenGL application which I can compile fine on Linux. It uses static .a librarys. Now I tried compiling with MinGW (and .lib libraries) and g++, but the resulting main.exe displays this error when I try to execute it: https://i.imgur.com/dpidmsw.png.
g++.exe -std=c++11 -Wall -o main.exe Main.cpp FastNoise.cpp shader.cpp texture.cpp glew32.lib glfw3.dll -lglu32 -lopengl32
When using cmake with the CMakeGUI to create a Visual Studio Project it works fine:
cmake_minimum_required(VERSION 3.5)
add_definitions(-DGLEW_STATIC)
set (CMAKE_CXX_STANDARD 11)
add_executable(main Main.cpp texture.cpp shader.cpp FastNoise.cpp)
find_package(OpenGL REQUIRED)
include_directories( ${OPENGL_INCLUDE_DIRS} )
IF (WIN32)
target_link_libraries(main ${CMAKE_CURRENT_SOURCE_DIR}/GLEW_1130.lib ${CMAKE_CURRENT_SOURCE_DIR}/glfw3.lib ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${X11_LIBRARIES})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vertex.glsl ${CMAKE_CURRENT_BINARY_DIR}/Debug/vertex.glsl COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fragment.glsl ${CMAKE_CURRENT_BINARY_DIR}/Debug/fragment.glsl COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/dirt.bmp ${CMAKE_CURRENT_BINARY_DIR}/Debug/dirt.bmp COPYONLY)
ELSE()
include_directories( ${X11_INCLUDE_DIRS} )
find_package(X11 REQUIRED)
target_link_libraries(main ${CMAKE_CURRENT_SOURCE_DIR}/libGLEW.a ${CMAKE_CURRENT_SOURCE_DIR}/libglfw3.a ${OPENGL_LIBRARIES} ${GLUT_LIBRARY} ${X11_LIBRARIES} X11 Xxf86vm pthread dl Xrandr Xinerama Xcursor)
ENDIF()

Just because you have static libraries that doesn't mean that these are in any way system independent. The static libraries you have are all built for a Linux target. They expect to talk with Linux operating system functions using the a calling convention (i.e. the way functions are to be called) that's different from Windows. Essentially you're trying to shove a square peg through a round hole here. It doesn't work that way.
To build for Windows you need also all the prerequisites being ported and built for Windows, too. Luckily all the libraries you mention have Windows ports, so that's not a problem.
I fixed it by adding these praeprocessor definitions:
…
You fixed nothing. You just lied to something (compiler, your program source code, etc.) about the toolchain it's built with and the target it's built for.
If you start redefining system level preprocessor definitions, you're doing something very, very wrong.
Here's what you should do (well, what I recommend): Head over to http://www.msys2.org/ and grab the MSys2 installer. Install it, launch the MinGW… environment (there's a 32 bit and a 64 bit environment). MSys2 uses the Pacman package manager of the Arch Linux distribution. Use that to install the toolchain (make, binutils, gcc) – make sure you install the right variant, the package database has packages for msys, mingw32 and mingw64 – and all the development libraries you need. There are packages for GLEW, GLFW3 and so on available.
Next install CMake. I strongly recommend not to use the MSys2 package, but the standalone installer from https://cmake.org/ – the CMake installed this way knows how to work with MSys/MinGW …and more.
Then create a CMakeLists.txt for your project, and use that to create the build environment. The nice thing about CMake is, that it's cross platform and knows a ton of build systems and compiler environments. If your project is structured sanely and you don't do crazy stuff (or you do crazy stuff and put the right straightjackets around it so it doesn't go on a rampage) you'll get something that you can build effortlessly on or for most target environments.

Related

How do I compile and deliver my application without requiring installation of shared libraries on other machines

On my Ubuntu machine I installed libGLEW. However, I did not install it on my other Ubuntu machine. It works on my compiling machine, but now I received the following error after copying my executable to my other machine.
I want to find a solution where I don't have to require my other machine to install the library. Maybe I can simply share the file along with the executable, like I would do in Windows with DLL files? Would that be possible? And if so, how do I do that?
error while loading shared libraries: libGLEW.so.2.1: cannot open shared object file: No such file or directory
In CMake, I used the following relevant pieces of code:
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -g" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64 -g" )
include_directories(
...
"/usr/include/GL" # Also includes glew.h
)
add_executable( ${PROJECT_NAME}
${PROJECT_SRC}
)
target_link_libraries( ${PROJECT_NAME}
...
"GLEW"
)
Maybe I can simply share the file along with the executable, like I would do in Windows with DLL files?
It 'depends' on the 'dependencies'.
Use the command ldd to figure out, which libraries are required by a library or program. Those required libraries have to be present (installed) on the target system.
Even if a required library is installed on the target system, it could be possible, that the required version is not available.
That's why the different (linux) systems have their package management systems, which are able to resolve the dependencies and install them automatically.
To solve the issue for my situation, I added glew.c to my source files which solves the issue.

Enabling curses in both Linux and Windows

I am working on small project in C++ and I am using curses for user interface. I am pretty nicely able to make it work in my arch-linux installation, because it is pretty simple to set up ncurses to work there. But with my cmake setting which is working nicely at Linux I am not able to properly make it work at Windows.
Here is my CMakeList.txt
cmake_minimum_required(VERSION 3.9)
project(fighting_pit)
find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})
set(CMAKE_CXX_STANDARD 11)
include_directories( ./include)
include_directories( ./src)
add_executable(fighting_pit
include/Arena.h
include/cursor.h
include/Player.h
include/spell.h
include/Turns.h
include/weapon.h
include/Draw.h
src/Arena.cpp
src/cursor.cpp
src/Player.cpp
src/spell.cpp
src/Turns.cpp
src/weapon.cpp
src/Draw.cpp
main.cpp )
target_link_libraries(fighting_pit ${CURSES_LIBRARIES})
I tried several approaches to make it work on Windows too.
1. Downloading sources
I tried to build pdcurses with mingw32-make. It created pdcurses.a I added it to same location as project, but it still shows it cannot find curses library.
2. Downloading via mingw32-get
I used installation manager from mingw and let it download both .dll and dev package of libpdcurses. Just trying to run cmake through clion showed it is still not found. So I copied it both into windows32 and project folder but it still didn't help.
I don't know what I should do. Unfortunately I am neither C++ user neither Windows user.
I needed to build a cross-platform project that uses ncurses on Linux and MacOS but uses pdcurses on Windows. Some variant of curses is usually installed on popular distributions of Linux. ncurses is also available on MacOS as well. The same isn't quite true for Windows. My solution was to download the pdcurses sources and write a cmake script for building it on Windows. if (WIN32 or MSVC) build pdcurses else() find ncurses. You might also want to create a proxy header that #includes pdcurses or ncurses depending on the platform.
After cloning the GitHub repo, I copied the headers in ., the C files in ./pdcurses, the sources in ./wincon into a new directory in my project. Then I wrote a CMakeLists.txt file to compile all of these files into a library. It looked something like this:
cmake_minimum_required(VERSION 3.2)
add_library(PDcurses
# all of the sources
addch.c
addchstr.c
addstr.c
attr.c
beep.c
# ...
)
target_include_directories(PDcurses
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
)
My main CMakeLists.txt file compiled the pdcurses sources if the target is windows.
if(WIN32 OR MSVC)
add_subdirectory(pdcurses)
target_link_libraries(MyTarget
PRIVATE
PDcurses
)
else()
# find ncurses and use that
endif()
PDCurses seems to be a (more or less) drop-in replacement for ncurses in most situations. I was able to compile the example programs that came with PDcurses on my Mac using curses without any troubles.

CMake on Windows 10 doesn't generate executable

So I have a tiny C++ project that I code on both Windows 10 and Ubuntu 16.04, and I'm using CMake to coordinate relatively platform-independent build processes. I'm no master of CMake, but it worked up until recently, however now I cannot get the solution generated by CMake-gui to actually compile into an executable to run, despite my usage of add_executable. Here is my CMakeLists (there's a hideous mix of platform-specific stuff in there, however it appears that CMake simply ignores it):
cmake_minimum_required(VERSION 3.10)
set (CMAKE_CXX_STANDARD 17)
project (TestProject)
include_directories(C:/include/CImg-2.2.2)
ADD_LIBRARY(LibsModule Game.cpp Game.h TestGame.cpp TestGame.h)
target_link_libraries(LibsModule -lpthread)
target_link_libraries(LibsModule -lm)
target_link_libraries(LibsModule -lX11)
add_executable(TestProject TestGame.h)
target_link_libraries(TestProject LibsModule)
This compiles and runs fine on Ubuntu using CLion, however on 64-bit Windows 10 using VS17 it fails upon trying to run the executable it expects to be generated because the executable doesn't exist in the build folder (but the .lib file noted is generated just fine).
I've seen some mention that a third party antivirus program could cause this, but I have no such thing installed.
Now I'm pretty new to CMake so if this file is completely off the mark I would really appreciate a clear explanation as to what I'm doing wrong, this code is made from a short study of basic CMake usage.

C++ How to run programs in Clion when you need to include OpenGL libraries?

Hello I need to work with OpenGL and want to create my project in Clion. But Clion cannot compile and run my projects because of the libraries I need to include. I can create my own makefile and run the program in terminal, but I want to do it in the IDE. How can I make this happen?
First make sure you installed all libraries correctly using the compiler you configured in clion/cmake. Assuminf you have a fresh CMakeLists.txt like
cmake_minimum_required(VERSION 3.3.2)
project(MyGL CPP)
add_executable(demo-run main.cpp)
For linking your libraries you need two things. First tell the compiler where to find the include files and second which libraries to link. You could just hard code you local installation like
target_link_libraries(demo-run path/to/glfw.lib path/to/opengl.lib path/to/jpeg.lib ...)
target_include_directories(demo-run PRIVATE path/to/glfw/include path/to/opengl/include path/to/jpeg/include ...)
however this is not very portable and if you want to work with another compiler or on another machine your project file will fail. Instead you can use the package system of cmake
find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)
find_package(JPEG REQUIRED)
find_package(GLEW REQUIRED)
find_package (OpenGL REQUIRED)
find_package (GLM REQUIRED)
target_link_libraries(demo-run ${GLFW_LIBRARIES} ${GLEW_LIBRARIES} ${JPEG_LIBRARIES} ${OPENGL_LIBRARIES})
target_include_directories(demo-run PRIVATE ${GLFW_INCLUDE_DIRS} ${GLEW_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLM_INCLUDE_DIR})
The glfw part is a bit tricky and works only on linux i guess see http://www.glfw.org/docs/3.0/build.html.
This code is not tested at all and you may need to specify some enviroment variables so cmake can find the packages or provide additional find scripts like https://github.com/lighttransport/nanogi/blob/master/cmake/FindGLM.cmake.
I would recommend to use the CMake build tool which does the work generating Makefiles for you and is also directly supported by clion. When you open the directory containing a CMakeLists.txt (CMake Project File) with clion, it should be automatically be loaded and compiled (if not just hit build)
A very simple example CMake project would look like this
cmake_minimum_required (VERSION 2.8.9)
project (OpenGl-Stuff)
include_directories(src)
add_executable(your-binary src/your-code.c src/your-code.h)
target_link_libraries(your-binary opengl)
# target_link_libraries will search for libopengl on standard system paths,
# maybe the library is not called libopengl, then you have to adjust the name above
this cmake project will generate the binary for you and link it against opengl

How to use pkg-config in CMake (juCi++)

I've been happily programming in C++ and compiling with g++ for quite a while. Not long ago, I'd decided to get an IDE, and I came accross juCi++.
This IDE is absolutely brilliant, but it uses CMake (or Meson) to build projects. This wasn't a problem, until I had to include a library (GTK+ 3.0 if you're wondering) using pkg-config. This could be done quite easily when compiling with g++, but, as I am completely new to CMake, I have no idea how to do it in the new IDE.
Can somebody please explain?
If your IDE handles CMake and Meson, it should be able to detect your project files. I'd say go for Meson, it's the future, and CMake syntax has a few quirks that Meson doesn't.
Meson:
Meson documentation
He's a basic meson.build that expects to find your application code in main.c and produces a binary named gtk3-test.
project('gtk3-test', 'c')
cc = meson.get_compiler('c')
deps = dependency ('gtk+-3.0')
sources = ['main.c']
executable('gtk3-test', sources, dependencies: deps)
CMake
CMake documentation
For CMake, just give a look at my answer to How do I link gtk library more easily with cmake in windows? (which also works under Linux). It was for GTK+2, but adapting it to GTK+3 is easy, so here's the CMakeLists.txt to use:
project (gtk3-test)
cmake_minimum_required (VERSION 2.4)
find_package (PkgConfig REQUIRED)
pkg_check_modules (GTK3 REQUIRED gtk+-3.0)
include_directories (${GTK3_INCLUDE_DIRS})
link_directories (${GTK3_LIBRARY_DIRS})
add_executable (gtk3-test main.c)
add_definitions (${GTK3_CFLAGS_OTHER})
target_link_libraries (gtk3-test ${GTK3_LIBRARIES})