main function not being detected when compiled - c++

I am trying to run a program that opens a window. the purpose is to get the program started opening a window is the start of all programs right?
But when I run my code for some reason I get this error:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
However, in my code I do have the main() function so why am I getting this error?
This is my code:
#include <SDL2/SDL.h>
#include <SDL2_image/SDL_image.h>
#include <SDL2_ttf/SDL_ttf.h>
#include <stdio.h>
int main(){
if(SDL_Init( SDL_INIT_EVERYTHING ) < 0){
std::cout << "error 1\n";
std::cout << SDL_GetError();
std::cout << "\n";
return -1;
}
if(TTF_Init() < 0){
std::cout << "error 2\n";
std::cout << TTF_GetError();
std::cout << "\n";
return -1;
}
SDL_Window* window = SDL_CreateWindow("test", 0, 0, 500, 500, 0);
if(!window){
std::cout << "error 3\n";
std::cout << SDL_GetError();
std::cout << "\n";
return -1;
}
int windowid = SDL_GetWindowID(window);
SDL_Renderer* Renderer = SDL_CreateRenderer(window, -1, 0);
running = true;
SDL_Event event;
while(running){
while(SDL_PollEvent(&event)){
if(event.type == SDL_WindowEvent){
if(event.window.windowID == windowid){
if(event.window.type == SDL_WindowClose){
Destroywindow(window);
running = false;
}
}
}
}
}
return 0;
}
my make file looks like this:
#!/bin/bash
brew update
brew install sdl2
g++ -o /Users/mikahshattuck/noneproject/none2019-05-0909-22-
14:2:/none.app/Contents/MacOS/mainrun.cpp -I /Library/Frameworks -l
SDL2
exit 0
this is the full out:
Already up-to-date.
Warning: sdl2 2.0.9_1 is already installed and up-to-date
To reinstall 2.0.9_1, run `brew reinstall sdl2`
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see
invocation)
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
thank you in advance

When using SDL on macOS or Windows, you need to add -Dmain=SDL_main to your compile flags and -lSDL2main to your link flags. Since you're using Homebrew, you can make it easier and just use pkg-config to get the correct flags. Use this compiler command as a template and adapt it to your needs:
g++ $(pkg-config --cflags sdl2) -I /Library/Frameworks source.cpp -o output_executable $(pkg-config --libs sdl2)
However, it seems you are also using SDL_ttf, not just plain SDL. In this case, you should probably use SDL2_ttf instead of sdl2 as the package argument of pkg-config:
g++ $(pkg-config --cflags SDL2_ttf) -I /Library/Frameworks source.cpp -o output_executable $(pkg-config --libs SDL2_ttf)
The SDL2_ttf package depends on the sdl2 package, so using SDL2_ttf will also emit the needed flags for sdl2.
The names of the pkg-config packages correspond to *.pc files installed by Homebrew into /usr/local/lib/pkgconfig.

Related

Unable to initialise sdl2

Im trying to check if sdl is properly installed on my Ubuntu 20.04 and its not.
Running all on 64bit type.
This is my code:
#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_timer.h>
bool initSDL()
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
std::cout << "Failed to init sdl: " << SDL_GetError() << std::endl;
return false;
}
if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG)
{
std::cout << "Failed to init sdl_image: " << IMG_GetError() << std::endl;
return false;
}
return true;
}
int main(int argc, char *argv[])
{
std::cout << "Code Starting..." << std::endl;
initSDL();
int winX = 900, winY = 600;
std::cout << "Code Exited Properly." << std::endl;
return 0;
}
And this is my output:
Code Starting...
Failed to init sdl: No available video device
Code Exited Properly.
Im running my code with this commands:
gcc -c src/*.cpp -I include -m64 -lstdc++ -std=c++11
gcc *.o -o out/main -lSDL2main -lSDL2 -lSDL2_image -m64 -lstdc++ -std=c++11
./out/main
My code strucure is this way:
Main directory 'sdl_hello_world'
->src -> contains 'main.cpp'
->out -> contains compiled 'main'
Some methods i tried was:
export DISPLAY=:0
export SDL_VIDEODRIVER=x11
So how do i fix this ?
EDIT: I also followed this tutorial (https://www.youtube.com/watch?v=P3_xhDIP7bc&list=PLvv0ScY6vfd-p1gSnbQhY7vMe2rng0IL0&ab_channel=MikeShah), and still it gave the same error. So i guess the problem is in some computer setting.
EDIT: SOLVED:
i followed almost all tutorials and fix methods on the internet to solve my issue which uses gcc in linux. Some solutions on stack overflow seemed to prefer to compile the source code on their own computer WHICH WORKED.
So im pretty sure the way ubuntu installs it on my computer/ idk im new to using sdl. Updating this as might come handy to anyone else.
Still curious, is there a chance i did something wrong, or could this be considered a bug ?
EDIT: followed this btw https://wiki.libsdl.org/Installation

Xcode gives Mach-O linker error: "_JNI_CreateJavaVM", referenced from: _main in main.o

I get this error from testing JNI:
Undefined symbols for architecture x86_64:
"_JNI_CreateJavaVM", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Here is c++ code:
#include <jni.h>
#include <iostream>
using namespace std;
int main()
{
int res;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
JavaVM *jvm;
JNIEnv *env;
jmethodID mid;
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path = /Users/stephen/course/test/Test";
options[2].optionString = "-verbose:NONE";
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 3;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
res = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
if(res == JNI_ERR){
cout << "Error invoking the JVM";
return 1;
}
cout <<"create JVM successfully!"<<endl;
jclass cls = env->FindClass("/Users/stephen/course/Qt-project/test/Test");
if(cls != 0){
cout<<"find class successfully!" << endl;
}
mid = env->GetMethodID(cls,"sayHello","stephen");
if(mid != 0){
cout<<"Invoke method successfully!" << endl;
}
jvm->DestroyJavaVM();
return 0;
}
Here is java code:
public class Test
{
public static void sayHello(String s){
System.out.print("hello I am" + s + "\n");
}
}
I add the include path of " jdk/include; jdk/include/darwin" the project, also I add lib path of " jdk/jre/lib/server" to the project to get the libjvm.dylib. The c++ standard library of my project is libstdc++(gnu c++ standard library.
But I can't solve this problem as expected.
Take a look here for a sample code where JVM library is linked with your project:
https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo028
Take a look at Makefile. Especially, here:
main: recipeNo028_main.o
ld -o lib/recipeNo028_main -L${JAVA_HOME}/jre/lib/server/ \
-ljvm \
$(MAC_OS_FLAGS) \
lib/recipeNo028_main.o
where jvm lib is linked with the code, and here:
CC=llvm-gcc
MAC_OS_FLAGS=-rpath ${JAVA_HOME}/jre/lib/server -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -lSystem
where all required libs are added to your code as well. It should work. Try to compile sample code. You can find more samples here: http://jnicookbook.owsiak.org
Update
How to use arbitrary JDK version for compilation.
First, take a look at all installations you have
/usr/libexec/java_home -V
This will produce something like this
/usr/libexec/java_home -V
Matching Java Virtual Machines (4):
9, x86_64: "Java SE 9" /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
1.8.0_144, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
1.8.0_111, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
1.7.0_80, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home
Then, before running make, simply set JAVA_HOME to whatever you like
export JAVA_HOME=$(/usr/libexec/java_home -v 9)
Now, your code will use version that you have chosen.

Compiling libzip on Mac: Undefined symbols for architecture x86_64

I've been learning C++ and have decided to try to create a simple file reader using libzip on archive files (e.g. Word).
I’ve recently installed libzip on my Macbook using brew but I seem to keep on getting the following issue whenever I try to compile a program that uses libzip:
Undefined symbols for architecture x86_64:
"_zip_fopen", referenced from:
_main in main-918bfa.o
"_zip_open", referenced from:
_main in main-918bfa.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [a.exe] Error 1
The command I use to compile:
g++ -g main.cpp -std=c++11 -I/usr/local/Cellar/libzip/0.11.2/include -I/usr/local/Cellar/libzip/0.11.2/lib/libzip/include -L/usr/local/Cellar/libzip/0.11.2/lib -o ../a.exe
main.cpp:
#include <iostream>
#include <fstream>
#include <zip.h>
#include <zlib.h>
using namespace std;
int numArgs = 2;
int main(int argc, char** argv){
// Parse command line arguments
if(argc != numArgs){
std::cout << "Incorrect number of arguments provided.\n";
std::cout << "Command line syntax: fileReader.exe inputFile" << endl;
exit(0);
}
// Try out libzip functionality
std::string inputDocument(argv[1]);
int err = 0;
zip* z = zip_open(inputDocument.c_str(), 0, &err);
if(z == NULL) {
printf("Could not read docx file. Error code: %d", err);
exit(-1);
}
zip_file* contentTypes = zip_fopen(z, "[Content_Types].xml", ZIP_FL_UNCHANGED);
exit(0);
}
Doesn't look like your including the libzip library in the compilation command. Try adding -lzip to your g++ command

Trying to compile a simple opencv c++ file

I'm new to open cv. At the moment I'm trying to test if I could run a simple file.
// Example showing how to read and write images
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cvaux.h>
int main(int argc, char** argv)
{
IplImage * pInpImg = 0;
// Load an image from file - change this based on your image name
pInpImg = cvLoadImage("bear.jpg", CV_LOAD_IMAGE_UNCHANGED);
if(!pInpImg)
{
fprintf(stderr, "failed to load input image\n");
return -1;
}
// Write the image to a file with a different name,
// using a different image format -- .png instead of .jpg
if( !cvSaveImage("my_image_copy.png", pInpImg) )
{
fprintf(stderr, "failed to write image file\n");
}
// Remember to free image memory after using it!
cvReleaseImage(&pInpImg);
return 0;
}
I compiled it:
g++ `pkg-config –cflags opencv` cv.cpp -o cv `pkg-config –libs opencv`
I got this error:
Undefined symbols for architecture x86_64:
"_cvLoadImage", referenced from:
_main in cv-zQ5X30.o
"_cvReleaseImage", referenced from:
_main in cv-zQ5X30.o
"_cvSaveImage", referenced from:
_main in cv-zQ5X30.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I'm lost here, any help would be very much appreciated.
Thank you.
i think the problem might be using "-libs" and "-cflags" instead of "--libs" and "--cflags", use this instead:
g++ `pkg-config --cflags opencv` cv.cpp -o cv `pkg-config --libs opencv`

Error linking personal library which uses log4cplus

I have a weird problem trying to link a simple code which use a personal library which uses lib4cplus.
The file with the main code is so easy and doesn't use log4cplus. I only use lib4cplus into the library. The library compiles correctly but when i link the main file with the library it thowrs errors like that (loggers var not defined under architecture x86_64)
g++ leer.cpp -c
ar r libfichero.a blowfish.o clase.o
g++ -o Class leer.o -lm -lz -llog4cplus libfichero.a
Undefined symbols for architecture x86_64:
"fichero::loggerFichero", referenced from:
fichero::startLoggers() in libfichero.a(clase.o)
fichero::fichero()in libfichero.a(clase.o)
fichero::fichero()in libfichero.a(clase.o)
"fichero::errorLoggerFichero", referenced from:
fichero::startLoggers() in libfichero.a(clase.o)
fichero::fichero()in libfichero.a(clase.o)
fichero::fichero()in libfichero.a(clase.o)
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make[1]: *** [all] Error 1
make: *** [p21] Error 2
The errors comes when i want to define my private logger vars (ficheroLogger and errorFicheroLogger).
That's the code in the cpp file of my library.
bool fichero::startLoggers()
{
// Aquí inico los loggers que voy a usar en la clase.
loggerFichero = Logger::getInstance(LOG4CPLUS_TEXT("utils"));
errorLoggerFichero = Logger::getInstance("BigFail");
}
// Método para definir los logs.
bool fichero::initLogFichero()
{
cout << "Entering LOG Config part..." << endl;
LogLog::getLogLog()->setInternalDebugging(true);
Logger root = Logger::getRoot();
// Load the properties
PropertyConfigurator::doConfigure("ficheroLog4cplus.properties");
Logger fileLog = Logger::getInstance(LOG4CPLUS_TEXT("filelogger"));
// Log with INFO level
LOG4CPLUS_INFO(fileLog, "Application startup");
cout << "Exiting the main part()..." << endl;
// Log with INFO level
if (fileLog.isEnabledFor(INFO_LOG_LEVEL))
{
LOG4CPLUS_WARN(fileLog, "Application shutdown");
}
startLoggers();
return true;
}
// Constructor y Destructor
fichero::fichero()
{
nomFile = "file.txt";
delimitador = "";
hayDelimiatador = false;
initLogFichero();
LOG4CPLUS_WARN(loggerFichero, "Inicio normal");
LOG4CPLUS_WARN(errorLoggerFichero, "Inicio error.");
}
This does not look a like a problem of log4cplus. Try to reshuffle the command line:
g++ -o Class leer.o libfichero.a -llog4cplus -lz -lm