Why static library not working? - c

I tried making this simple static library in Code::Blocks with MinGW:
#include <time.h>
#include <sys/time.h>
#include "header.h"
extern int go(int x)
{
struct timeval t;
gettimeofday(&t, NULL);
return 1;
}
This same snippet works if compiled as a console app (with printf), but when compiled as a static library, the calling code keeps getting this error:
unresolved external symbol "_gettimeofday"

Related

ESP-IDF on Eclipse IDE error with external Library

I am using esp-idf v4.1.1 with different compilers, I have used Visual Studio Code and Eclipse IDE with Espressif tool installed.
My intention is that I want to use an external library that, at the moment, only has a function that does a SHA256 hash for which the openssl sha library (<openssl/sha.h>) is used.
The problem is that I include the library as a component to my project and I call it from the main but I get the following error when building the project.
(https://i.stack.imgur.com/3EECj.png)
If I try it in the Eclipse IDE I get more information about the error and I get "undefined reference to SHA256_INIT()" as for the rest of the functions.
See main.c, dual.c and dual.h code:
main.c:
#include <stdio.h>
#include "dual.h"
void app_main(void)
{
printf("Empezamos");
char * data = "hola";
char * e = generateHashSHA256(data);
printf("%s",e);
}
Dual.c:
#include <stdio.h>
#include "dual.h"
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
#include <openssl/sha.h>
char * generateHashSHA256(char *data){
SHA256_CTX ctx;
u_int8_t results[SHA256_DIGEST_LENGTH];
int n;
n = strlen(data);
SHA256_Init(&ctx);
SHA256_Update(&ctx, (u_int8_t *)data, n);
SHA256_Final(results, &ctx);
char *newString;
newString = malloc(sizeof(char)*SHA256_DIGEST_LENGTH*2);
memset(newString, 0, sizeof(char)*SHA256_DIGEST_LENGTH*2);
for(n=0;n<SHA256_DIGEST_LENGTH;n++)
{
printf(newString, "%s%02x", newString, results[n]);
}
return newString;
}
And Dual.h:
char * generateHashSHA256(char *data);
and CMake files:
CMake of component Dual:
idf_component_register(SRCS "dual.c"
INCLUDE_DIRS "include"
)
CMake of main folder:
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")
CMake of project folder:
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(template-app)
I compiled the library from the terminal with "gcc -o name main.c -lssl -lcrypto" and it works correctly but when compiling it in an esp-idf project nothing...
Please HELP!
I have tried everything, I have included the openssl libraries in all the esp-idf directories, I have put the paths in the CMake... etc.

How to play sound effect or Music in C?

I am making a game and I have to add some sounds effects and Music.
I Googled it and I found The flowing Code:
#include <conio.h>
#include "inc/fmod.h"
FSOUND_SAMPLE* handle;
int main ()
{
// init FMOD sound system
FSOUND_Init (44100, 32, 0);
// load and play mp3
handle=FSOUND_Sample_Load (0,"my.mp3",0, 0, 0);
FSOUND_PlaySound (0,handle);
// wait until the users hits a key to end the app
while (!_kbhit())
{
}
// clean up
FSOUND_Sample_Free (handle);
FSOUND_Close();
}
But when I compile it I got the flowing error:
➜ Desktop gcc main.c
main.c:1:10: fatal error: 'conio.h' file not found
#include <conio.h>
^~~~~~~~~
1 error generated.
Well, firstly <conio.h> is a C++ library and you're programming in C. It's different!
Then, I remember a C code I wrote years ago, main.c has got the following code (comments are in italian because I am italian):
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "header.h"
int main(){
register unsigned char x='2';
printf("digitare tasti:\n");
while(1){
while(1){
if(x=='2'){/*blocco2*/ while(x!='1' && x!='3'){x=getch(); scala2(x);}}
if(x=='1'){/*blocco1*/ while(x!='2' && x!='3'){x=getch(); scala1(x);}}
if(x=='3'){/*blocco3*/ while(x!='1' && x!='2'){x=getch(); scala3(x);}}
}
}
system("PAUSE");
return 0;
}
Then, this is the other source file, called file.c:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "header.h"
void scala1(unsigned char x){
if(x=='a')beep(131,50);
if(x=='s')beep(147,50);
if(x=='d')beep(165,50);
if(x=='f')beep(175,50);
if(x=='g')beep(196,50);
if(x=='h')beep(220,50);
if(x=='j')beep(247,50);
if(x=='k')beep(262,50);
if(x=='l')beep(294,50);
if(x=='w')beep(139,50);
if(x=='e')beep(156,50);
if(x=='r')beep(185,50);
if(x=='t')beep(208,50);
if(x=='y')beep(233,50);
}
void scala2(unsigned char x){
if(x=='a')beep(262,50);
if(x=='s')beep(294,50);
if(x=='d')beep(330,50);
if(x=='f')beep(349,50);
if(x=='g')beep(392,50);
if(x=='h')beep(440,50);
if(x=='j')beep(494,50);
if(x=='k')beep(523,50);
if(x=='l')beep(587,50);
if(x=='w')beep(277,50);
if(x=='e')beep(311,50);
if(x=='r')beep(370,50);
if(x=='t')beep(415,50);
if(x=='y')beep(466,50);
}
void scala3(unsigned char x){
if(x=='a')beep(523,50);
if(x=='s')beep(587,50);
if(x=='d')beep(659,50);
if(x=='f')beep(698,50);
if(x=='g')beep(784,50);
if(x=='h')beep(880,50);
if(x=='j')beep(988,50);
if(x=='k')beep(1046,50);
if(x=='l')beep(1175,50);
if(x=='w')beep(554,50);
if(x=='e')beep(622,50);
if(x=='r')beep(740,50);
if(x=='t')beep(831,50);
if(x=='y')beep(932,50);
}
The last one, the file header.h. It's code is the following one:
void scala1(unsigned char x);
void scala2(unsigned char x);
void scala3(unsigned char x);
All the source files must be in the same directory. You compile main.c and then, you just need to press a,s,d,..y and 1,2,3. Try! It works, of course if you want to change part of the code, you can do. I hope you enjoy my program, it's funny :)

Is SCHED_DEADLINE officially supported in Ubuntu 16.04?

Currently I'm running Ubuntu 16.04 with linux kernel version to be 4.16. I wrote a dummy program that changes its scheduler to SCHED_DEADLINE. But when I tried to compile it, it cannot find definition of structs and macros needed for SCHED_DEADLINE. Most of the code snippet was taken from here (page 24). Below is the test program:
#define _GNU_SOURCE
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sched.h>
int main(int argc, char* argv[]) {
struct sched_attr attr;
attr.size = sizeof(attr);
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 30000000;
attr.sched_period = 100000000;
attr.sched_deadline = attr.sched_period;
if (sched_setattr(gettid(), &attr, 0))
perror("sched_setattr()");
return 0;
}
Here's the output of the compilation:
sched_deadline.c: In function ‘main’:
sched_deadline.c:11:20: error: storage size of ‘attr’ isn’t known
struct sched_attr attr;
^
sched_deadline.c:12:21: error: invalid application of ‘sizeof’ to incomplete type ‘struct attr’
attr.size = sizeof(struct attr);
^
sched_deadline.c:13:22: error: ‘SCHED_DEADLINE’ undeclared (first use in this function)
attr.sched_policy = SCHED_DEADLINE;
My gcc version:
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
However, the sample code posted in the official website works for me, but the sample code manually defines all the needed macros and system calls in the program. My goal was to compile the application without adding those definitions, which should already be included in the newest kernel version. I have seen various places saying that SCHED_DEADLINE is officially supported after Linux 3.14.10, and upgrading the kernel would automatically solve this issue.
Things I've tried:
Recompiling 4.16 kernel. Previously I thought I need to turn on a switch in config file, but I was not able to find it.
Look into /usr/include/linux/sched.h. Clearly the macros are defined in this header file, but somehow my compiler cannot find it.
I also looked into other posts in the community, but all those questions are for older linux (pre 3.14.10).
You need to include #include <linux/sched.h>
But for the definition of sched_setattr() and gettid(), see the link posted by #CraigEstey
The reason about that, it that glibc will not add function wrappers of linux specific syscall.
For example for gettid(), in the manual we can read this:
Note: There is no glibc wrapper for this system call; see NOTES.
Glibc does not provide a wrapper for this system call; call it using
syscall(2).
The thread ID returned by this call is not the same thing as a POSIX thread ID
Have a look at this article: https://lwn.net/Articles/711058/
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sched.h>
#include <linux/sched.h>
#include <sys/types.h>
struct sched_attr {
uint32_t size;
uint32_t sched_policy;
uint64_t sched_flags;
/* SCHED_NORMAL, SCHED_BATCH */
int32_t sched_nice;
/* SCHED_FIFO, SCHED_RR */
uint32_t sched_priority;
/* SCHED_DEADLINE (nsec) */
uint64_t sched_runtime;
uint64_t sched_deadline;
uint64_t sched_period;
};
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int main(int argc, char* argv[]) {
struct sched_attr attr = {
.size = sizeof(attr),
.sched_policy = SCHED_DEADLINE,
.sched_runtime = 30000000,
.sched_period = 100000000,
.sched_deadline = 100000000
};
pid_t tid = syscall(SYS_gettid);
if (sched_setattr(tid, &attr, 0))
perror("sched_setattr()");
return 0;
}
Or a more shorter code, without the redefinition of struct sched_attr
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/sched/types.h>
#include <linux/sched.h>
#include <sys/types.h>
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int main(int argc, char* argv[]) {
struct sched_attr attr = {
.size = sizeof(attr),
.sched_policy = SCHED_DEADLINE,
.sched_runtime = 30000000,
.sched_period = 100000000,
.sched_deadline = 100000000
};
pid_t tid = syscall(SYS_gettid);
if (sched_setattr(tid, &attr, 0))
perror("sched_setattr()");
return 0;
}
But this needs to be executed as root, otherwise I got sched_setattr(): Operation not permitted
Or the application needs to have the right linux capabilities.

storage size not constant when using offsetof and including termios.h with android ndk

I encounter a strange error when compiling this
#include <termios.h>
#include <stddef.h>
struct Test {
int a;
int b;
};
void test() {
static int test_array[(offsetof(struct Test,a)) > 0 ? 2 : 1];
}
with arm-linux-androideabi-gcc -c:
test.c:8:13: error: storage size of 'test_array' isn't constant
The strange thing about this is, when I remove the
#include <termios.h>
the whole thing compiles without error. Also, when I use the gcc installed on my ubuntu system, it does not complain independent of including termios.h.
Ayone any Idea why?
Background: I am trying to compile a ghc (glasgow haskell compiler) android crosscompiler, and hs2hsc fails on this situation.

Conflict error when trying to compile a syscall .c file in freebsd

i am trying to add a new syscall to freebsd 8. i am using freebsd on VMplayer .when i trying to
compile the module i give this error :
my code is(i also have a Makefile file) :
#include <sys/param.h>
#include <sys/types.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
struct user_datas{
};
static char* rot13func(struct thread* td , void* args)
{
struct user_datas* upp=args;
char* myarray=(upp->input);
return myarray;
}
static struct sysent rot13func_sysent={
1,
rot13func
};
static int offset=NO_SYSCALL;
static int load (struct module *module , int cmd, void *arg)
{
int error=0;
switch(cmd){
case MOD_LOAD:
break;
case MOD_UNLOAD:
break;
default:
error=EOPNOTSUPP;
break;
}
return(error);
}
SYSCALL_MODULE(rot13func, &offset , & rot13func_sysent , load, NULL);
It looks like your Makefile is incorrect and uses wrong include paths. Try using one from the /usr/share/examples/kld/syscall/module/ example, which looks like:
# Makefile for building the sample syscall module
# $FreeBSD: src/share/examples/kld/syscall/module/Makefile,v 1.2 2001/09/18 12:03:42 ru Exp $
KMOD= syscall
SRCS= syscall.c
.include <bsd.kmod.mk>
It will do appropriate steps to set up proper module build environment for you.

Resources