how to test a static library project with codeblocks and target definition - c

I have a static library project and now i want to test some functions. To achive my goal i added a new target of type console, because when i try to "run" my library i get right the message "...select an host application to run...", then i added to this target a test file, test.c, that use some function.
From my knowledge, targets are different way to process sources file, so the release target produces a *.a file, and the debug target produces other.
// test.c
#include <stdio.h>
struct object_geometry *load_ObjModel(char *fileName);
int main()
{
printf("Buongiorno!");
load_ObjModel("../dado.obj");
return 0;
}
After writing test.c, i select the last created target and during debugging something doesn't work, because i can't use the modality "go line by line", or putting breakpoint in the above code, so:
how can i debug my library, without the creation fo a new project?
what's a target in codeblocks?
(other useful related informations are appreciated)

Related

extract library version from binary with CMake

I am writing a FindXXX.cmake script for an external C library. I would like my script to provide information about the library version. However, the library only provides this information in the form of a function that returns the version number as a string.
I thought I could extract the version number by having FindXXX.cmake compile the following C program on the fly:
#include <stdio.h>
#include "library.h"
int main() {
char version[256];
get_version(version);
puts(version);
return 0;
}
In order for this to work, CMake should compile and run the program above at configure time, and use the information it prints as the version identifier. I know how to do the latter (execute_process), and I almost know how to do the former: CheckCSourceRuns comes to mind, but I do not know how to capture the stdout of the generated executable.
TL;DR: is there a way to compile a program, run it and capture its stdout from CMake at generation time?
You may use try_run for that purpose (it is assumed that your source file is named as foo_get_version.c):
try_run(foo_run_result foo_compile_result
foo_try_run ${CMAKE_CURRENT_LIST_DIR}/foo_get_version.c
RUN_OUTPUT_VARIABLE foo_run_output)
if(NOT foo_compile_result)
# ... Failed to compile
endif()
if(NOT foo_run_result EQUAL "0")
# ... Failed to run
endif()
# Now 'foo_run_output' variable contains output of your program.
Note, that try_run isn't executed when cross-compiling. Instead, CMake expects that the user will set cache variables foo_run_result and foo_run_result__TRYRUN_OUTPUT.

multiple definition of main first defined here

I'm new to programming and currently I'm learning C programming. I'm writing codes on the code blocks and in it using GCC compiler. When I create a new project, (as you know it creates main.c file with it) and due to that I'm not able to compile another file in that project.
File 1:
#include<stdio.h>
int main()
{
int a,b,c,d;
printf("Enter three numbers\n");
scanf("%d%d%d",&a,&b,&c);
d=a;
if(b>d)
d=b;
if(c>d)
d=c;
printf("\n The maximum of three numbers is %d",d);
}
File 2: main.c
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return 0;
}
When I compile the first programme, it shows the following error:
multiple definition of 'main'
first defined here
I've searched every where I could and I'm not able to solve this. In one of the answers here on stack overflow, someone had suggested to write this in
(Project->Build options...->Linker settings (tab))
-Wl,--allow-multiple-definition
When I wrote it, there were no errors. But it wasn't able to run my File 1 and instead, it runs that main.c file. Even when I close the main.c file, it opens there again and runs main.c file which gives the output "Hello World!".
Initially when I was using code blocks there were no such errors. I don't know why this is happening and I've not much knowledge about compilers.
As noted in comments you can only have one main function.
So when you start a new project you need to replace the main.c file with the main.c file you want to use. Or you can edit the 'hello world' main.c program.
When you start a new project in code::blocks you can get a new directory with a simple program that prints 'Hello World'. This file is usually main.c. You need to edit this file or replace it. The reason that code::blocks puts this simple main.c program in the new project is so that you can compile it and test your system without having to write a new program.
Some computer languages allow you to use the same function name for different functions ( which are identified by their parameters and sometimes return types ). That's called overloading. C does not allow this. Functions in C must have unique names.
The main() function is a special one in C as it is used as the standard entry point for applications. That is, the main() function will be called first and your application should start and (typically) end in that function.
As a beginner I would suggest you avoid automated editor features that create and build projects for you. You will miss out on learning how things work doing that. Use an editor to start from empty files and learn how they all connect and how to use the compiler from the command line. The command line is something every beginner should start from, IMO.
It may be harder to learn, but it will give you a much better feel for what is going on.
I guess what you maybe trying to do is have multiple sandbox "gists" that you may wanna run all as their own main function. If that is the case, then just close your project and open the files directly. As long as they are not in a project, they will run fine.

How to open files from a NaCl Dev Environment application?

I'm trying to get a simple command line application to run in the NaCl Development Environment. But I don't understand why it doesn't want to open files:
#include <stdio.h>
#include <ppapi_simple/ps_main.h>
int my_main (int argc, char ** argv) {
FILE * f = fopen ("out.txt","w");
if (f) {
fputs ("output to the file", f);
fclose(f);
} else {
puts("could not open file");
}
}
PPAPI_SIMPLE_REGISTER_MAIN(my_main)
Running:
bash.nmf-4.3$ gcc -I"$NACL_SDK_ROOT/include" test.c -lppapi_simple -lnacl_io -lppapi
bash.nmf-4.3$ ./a.out
could not open file
bash.nmf-4.3$
It's clearly possible for an application to open files in arbitrary locations within the dev environment - I'm using nano to edit the test code! But the naclports version of nano doesn't look like it's been changed in ways that are immediately connected to file manipulation..?
Lua is another app that appears to have only been modified very slightly. It falls somewhere in between, in that it can run test files but only if they're placed in /mnt/html5, and won't load them from the home folder. My test program shows no difference in behaviour if I change it to look in /mnt/html5 though.
NB. my goal here is to build a terminal application I can use within the dev environment alongside Lua and nano and so on, not a browser-based app - I assume that makes some difference to the file handling rules.
Programs run in the NaCl Dev Environment currently need to linked with -lcli_main (which in turn depends on -lnacl_spawn) for an entry point which understands how to communicate with the javascript "kernel" in naclprocess.js. They need this to know what current working directory they were run from, as well as to heard about mounted file systems.
Programs linked against just ppapi_simple can be run, but will not setup all the mount points the dev environment may expect.
There is a linker script in the dev env that simplifies linking a command line program -lmingn. For example the test program from the question can be compiled with:
gcc test.c -o test -lmingn
NOTE: This linker script had a recently resolved issue, a new version with the fix was published to the store on 5/5/2015.
In the near future, we have plans to simplify things further, by allowing main to be the entry point.
Thanks for pointing out the lua port lacks the new entry point!
I've filed an issue and will look into fixing it soon:
https://code.google.com/p/naclports/issues/detail?id=215
I found a solution to this, although I don't fully understand what it's doing. It turns out that the small changes made to nano are important, because they cause some other functions elsewhere in the NaCl libraries to get pulled in that correctly set up the environment for file handling.
If the above file is changed to:
#include <stdio.h>
int nacl_main (int argc, char ** argv) {
FILE * f = fopen ("out.txt","w");
if (f) {
fputs ("output to the file", f);
fclose(f);
} else {
puts("could not open file");
}
}
...and compiled with two more libraries:
gcc -I"$NACL_SDK_ROOT/include" test.c -lppapi_simple -lnacl_io -lppapi -lcli_main -lnacl_spawn
...then it will work as expected and write the file.
Instead of registering our own not-main function with PPAPI_SIMPLE_REGISTER_MAIN, pulling in cli_main causes it to do so with an internal function that sets some things up, presumably including what is needed for file writing to work, and expects to then be able to call nacl_main, which is left to the program to define with external visibility (several layers of fake-main stacking going on). This is why the changes to nano look so minimal.
nacl_spawn needs to be linked because cli_main uses it for ...something.

How to link two source files properly? undefined reference error

Ok so I am doing a final project for one of my classes and trying to do a bit extra and create multiple files to work with. I am coding inside of CodeBlocks. So far I have a main.c, levels.c, and levels.h for my files. Inside of the levels.c levelOne function, I put the printf statement as a test to make sure I could have the two files work with each other before I went forward in my coding. I got a "undefined reference to 'levelOne' when I compiled and ran the program.
Inside my main.c file:
#include <stdio.h>
#include <stdlib.h>
#include "levels.h"
int main()
{
levelOne();
return 0;
}
Inside my levels.h file:
#ifndef LEVELS_H_INCLUDED
#define LEVELS_H_INCLUDED
void levelSelect(char c);
void levelOne();
void levelTwo();
void levelThree();
void levelCustom(int difficulty);
#endif // LEVELS_H_INCLUDED
Inside my levels.c file:
void levelOne()
{
//level scope of 1 to 10
srand(time(NULL));
int randomNum = (rand() % 9)+1);
printf("the random number is: %i\n", randomNum);
}
levels.c is not getting passed into the compiler, are you sure you have included levels.c in the whole project? If not it will not link. You need a project if you want to compile multiple files. In CodeBlocks, the sources and the settings for the build process are stored in a project file <name>.cbp
Here is the User Manual
gcc levels.c main.c should link successfully. gcc main.c will only compile one file and try and link to create final executable and levelOne() will not be found. since it is in file levels.c
You need to include levels.h in levels.c as well or if a function (physically) above levelOne calls it, it is undefined.
Then compile it with gcc -Wall *.c -o myapp to compile and link all of the c files in that directory into myapp (or you can name them individually) with (almost) all warnings enabled. This is provided you have it in its own directory.
Once you get into larger projects with more code, you can compile individual .c files into .o object files with gcc -Wall -c somecode.c and then link all the objects with gcc *.o -o myapp. If it gets really large, you'll want a build system to help with rebuilding objects only when its code (or dependent code) changes (such as Makefiles, waf, and dare I say autotools).
I had this exact same problem, the solution is easy. Right click on levels.c and select properties. A properties window should come up select the "Build" tab tick compile file, link file, and in the box check debug and release. This should fix your problem.
Don't make the mistake of doing this with a header file because it will give you a "...h.gch: file not recognized: File format not recognized.." error.

Including a static library in a C project (Eclipse)

I'm currently developing an application using SDL. In order to utilize it, I have already added the library and header files in the project's settings under C/C++ Build -> Settings -> Tool Settings -> Libraries/Includes. However, when I try to build a test program like
#include <stdio.h>
#include <SDL/SDL.h>
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Quit();
return 0;
}
I get this beautiful error message during the link process:
d:/programme/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../libmingw32.a(main.o): In function main':
C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference toWinMain#16'
Which is rather weird, given that the directory C:\MinGW doesn't even exist at all.
The command used for linking is this one:
gcc "-LD:\Programme\SDL\lib" -o test.exe test.o -lsdl
After two hours of trying to get a library link to work, I'm pretty confused and have no idea what I'm doing wrong. Help would be appreciated.
It looks like you are building a Windows GUI application, which requires a WinMain, while your code only provides a main function which would be for console applications.
So if this is supposed to be a console application, you must adjust your linker settings accordingly, or you must declare a WinMain.

Resources