如何将c源程序在openbsd中编译链接后执行?

OpenBSD的安装、升级、更新等日常问题。

版主: chenjun天地乾坤

回复
yuyshfj
钛 Ti
帖子: 30
注册时间: 2012-09-01 16:46

如何将c源程序在openbsd中编译链接后执行?

帖子 yuyshfj » 2012-09-25 20:59

hello.c

# include <stdio.h>

int main(void)
{
printf("Hello world!");
return 0;
}

用gcc -o hello hello.c
会生成一个hello文件,但是接着输入hello则提示ksh找不到hello命令什么的。

f5b
锆 Zr
帖子: 643
注册时间: 2011-10-22 20:43

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 f5b » 2012-09-26 15:33

很多时候运行第三方脚本或程序
需要先给予运行权限,然后运行
类似

chmod u+x hello

然后
sh hello

f5b
锆 Zr
帖子: 643
注册时间: 2011-10-22 20:43

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 f5b » 2012-09-27 8:43

补充
没有指定运行路径的程序可能需要
#./hello

表示在在当前目录运行hello,这样才行

头像
unreal
银 Ag
帖子: 1081
注册时间: 2010-06-07 18:52

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 unreal » 2012-10-01 21:58

yuyshfj 兄弟,建议找本 UNIX基础读物 仔细研读,不要说没时间,磨刀不误砍柴功!
我这几天C语言的学习也拉下了,除了事情多、主要还是懒惰啊!能抽空看电影却不肯抽空做习题+_+
可否借 yuyshfj 兄弟的这个贴子 做做教材每章后面的习题呢?大家共勉吧~
勤能補拙 Just do it now!

junfengfan
铜 Cu
帖子: 236
注册时间: 2010-02-03 18:37

Re: 如何将c源程序在openbsd中编译链接后执行?

帖子 junfengfan » 2012-10-16 17:09

ma.c源文件:


#include <stdio.h>
main()
{
int a,b,c;
scanf ("%d,%d",&a,&b);
c=max (a,b);
printf ("max=%d",c);
}

#gcc ma.c -o ma

# gcc ma.c -o ma
/tmp//ccJvOK3L.o(.text+0x39): In function `main':
: undefined reference to `max'
collect2: ld returned 1 exit status


上面这个文件  openbsd 里面 gcc ma.c -o ma -lmath
提示找不到 math.h
可是我发现在 openbsd 的 /usr/include/ 目录下面有 math.h ,请问是何原因?

junfengfan
铜 Cu
帖子: 236
注册时间: 2010-02-03 18:37

Re: 如何将c源程序在openbsd中编译链接后执行?

帖子 junfengfan » 2012-10-16 20:16

gcc ma.c /usr/lib/libm.a -o ma
就可以了,

头像
unreal
银 Ag
帖子: 1081
注册时间: 2010-06-07 18:52

回复: Re: 如何将c源程序在openbsd中编译链接后执行?

帖子 unreal » 2012-10-16 20:50

junfengfan 写了:gcc ma.c /usr/lib/libm.a -o ma
就可以了,
#include <math.h> 不行吗?
勤能補拙 Just do it now!

junfengfan
铜 Cu
帖子: 236
注册时间: 2010-02-03 18:37

Re: 回复: Re: 如何将c源程序在openbsd中编译链接后执行?

帖子 junfengfan » 2012-10-16 22:02

unreal 写了:#include <math.h> 不行吗?
不行,一直出错,说 max 或者 sqrt  没有定义,为何这样做我不知道为什么。

头像
unreal
银 Ag
帖子: 1081
注册时间: 2010-06-07 18:52

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 unreal » 2012-10-16 22:57

刚才在我机器上试了,cc ma.c /usr/lib/libm.a -o ma 任然报 max 是未定义引用。而且 我看了/usr/include/math.h 里面根本没有定义 max(),最接近的只有 fmax(void)。
勤能補拙 Just do it now!

junfengfan
铜 Cu
帖子: 236
注册时间: 2010-02-03 18:37

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 junfengfan » 2012-10-18 9:28

unreal 写了:刚才在我机器上试了,cc ma.c /usr/lib/libm.a -o ma 任然报 max 是未定义引用。而且 我看了/usr/include/math.h 里面根本没有定义 max(),最接近的只有 fmax(void)。
对,max 没有定义,但sqrt sin cos等可以用!

头像
unreal
银 Ag
帖子: 1081
注册时间: 2010-06-07 18:52

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 unreal » 2012-10-23 21:40

咳咳,我也被“引用未定义”困扰了:confused:
这是我用的教材 http://www.hzbook.com/Books/2334.html 书中使用自有的头文件和库,但是居然编译不过去。请列位兄台指教~
以下这个例程:

代码: 全选

/*
 * File: add2.c
 * ------------
 * This program reads in two numbers, adds them together,
 * and prints their sum.
 */

#include <stdio.h>
#include "genlib.h"
#include "simpio.h"

main()
{
    int n1, n2, total;

    printf("This program adds two numbers.\n");
    printf("1st number? ");
    n1 = GetInteger();
    printf("2nd number? ");
    n2 = GetInteger();
    total = n1 + n2;
    printf("The total is %d.\n", total);
} 
编译就报:

代码: 全选

/tmp//ccQV165R.o(.text+0x40): In function ‘main’:
: undefined reference to ‘GetInteger’
/tmp//ccQV165R.o(.text+0x44): In function ‘main’:
: undefined reference to ‘GetInteger’
/tmp//ccQV165R.o(.text+0x60): In function ‘main’:
: undefined reference to ‘GetInteger’
/tmp//ccQV165R.o(.text+0x64): In function ‘main’:
: undefined reference to ‘GetInteger’
collect2: ld returned 1 exit status
无耐只得改用C自己的 scanf() 才编译通过。

代码: 全选

/*
 * File: add2.c
 * ------------
 * This program reads in two numbers, adds them together,
 * and prints their sum.
 */

#include <stdio.h>

main()
{
    int n1, n2, total;

    printf("This program adds two numbers.\n");
    printf("1st number? ");
    scanf("%d",&n1);
    printf("2nd number? ");
    scanf("%d",&n2);
    total = n1 + n2;
    printf("The total is %d.\n", total);
} 
勤能補拙 Just do it now!

头像
unreal
银 Ag
帖子: 1081
注册时间: 2010-06-07 18:52

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 unreal » 2012-10-23 21:43

genlb.h

代码: 全选

/*
 * File: genlib.h
 * Version: 1.0
 * Last modified on Sun Jul 24 10:32:49 1994 by eroberts
 * -----------------------------------------------------
 * This file contains several definitions that form the
 * core of a general-purpose ANSI C library developed by Eric
 * Roberts.  The goal of this library is to provide a basic
 * set of tools and conventions that increase the readability
 * of C programs, particularly as they are used in a teaching
 * environment.
 *
 * The basic definitions provided by genlib.h are:
 *
 *    1.  Declarations for several new "primitive" types
 *        (most importantly bool and string) that are
 *        used throughout the other libraries and
 *        applications as fundamental types.
 *
 *    2.  A new set of functions for memory allocation.
 *
 *    3.  A function for error handling.
 *
 *    4.  A repeat statement for loops with interior exits.
 */

#ifndef _genlib_h
#define _genlib_h

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>

/* Section 1 -- Define new "primitive" types */

/*
 * Type: bool
 * ----------
 * This type has two values, FALSE and TRUE, which are equal to 0
 * and 1, respectively.  Most of the advantage of defining this type
 * comes from readability because it allows the programmer to
 * provide documentation that a variable will take on only one of
 * these two values.  Designing a portable representation, however,
 * is surprisingly hard, because many libraries and some compilers
 * define these names.  The definitions are usually compatible but
 * may still be flagged as errors.
 */

#ifdef THINK_C
   typedef int bool;
#else
#  ifdef TRUE
#    ifndef bool
#      define bool int
#    endif
#  else
#    ifdef bool
#      define FALSE 0
#      define TRUE 1
#    else
       typedef enum {FALSE, TRUE} bool;
#    endif
#  endif
#endif

/*
 * Type: string
 * ------------
 * The type string is identical to the type char *, which is
 * traditionally used in C programs.  The main point of defining a
 * new type is to improve program readability.   At the abstraction
 * levels at which the type string is used, it is usually not
 * important to take the string apart into its component characters.
 * Declaring it as a string emphasizes this atomicity.
 */

typedef char *string;

/*
 * Type: stream
 * ------------
 * Like string, the stream type is used to provide additional
 * readability and is defined to be equivalent to FILE *
 * (which is particularly confusing because it violates
 * standard case conventions).  This type is not used in
 * the text but is preserved in genlib.h, so it is possible
 * to teach all of CS1 without exposing any pointers.
 */

typedef FILE *stream;

/*
 * Constant: UNDEFINED
 * -------------------
 * Besides NULL, the only other constant of pointer type is
 * UNDEFINED, which is used in certain packages as a special
 * sentinel to indicate an undefined pointer value.  In many
 * such contexts, NULL is a legitimate data value and is
 * therefore inappropriate as a sentinel.
 */

#define UNDEFINED ((void *) undefined_object)

extern char undefined_object[];

/* Section 2 -- Memory allocation */

/*
 * General notes:
 * --------------
 * These functions provide a common interface for memory
 * allocation.  All functions in the library that allocate
 * memory do so using GetBlock and FreeBlock.  Even though
 * the ANSI standard defines malloc and free for the same
 * purpose, using GetBlock and FreeBlock provides greater
 * compatibility with non-ANSI implementations, automatic
 * out-of-memory error detection, and the possibility of
 * substituting a garbage-collecting allocator.
 */

/*
 * Function: GetBlock
 * Usage: ptr = (type) GetBlock(nbytes);
 * -------------------------------------
 * GetBlock allocates a block of memory of the given size.  If
 * no memory is available, GetBlock generates an error.
 */

void *GetBlock(size_t nbytes);

/*
 * Function: FreeBlock
 * Usage: FreeBlock(ptr);
 * ----------------------
 * FreeBlock frees the memory associated with ptr, which must
 * have been allocated using GetBlock, New, or NewArray.
 */

void FreeBlock(void *ptr);

/*
 * Macro: New
 * Usage: p = New(pointer-type);
 * -----------------------------
 * The New pseudofunction allocates enough space to hold an
 * object of the type to which pointer-type points and returns
 * a pointer to the newly allocated pointer.  Note that
 * "New" is different from the "new" operator used in C++;
 * the former takes a pointer type and the latter takes the
 * target type.
 */

#define New(type) ((type) GetBlock(sizeof *((type) NULL)))

/*
 * Macro: NewArray
 * Usage: p = NewArray(n, element-type);
 * -------------------------------------
 * NewArray allocates enough space to hold an array of n
 * values of the specified element type.
 */

#define NewArray(n, type) ((type *) GetBlock((n) * sizeof (type)))

/* Section 3 -- Basic error handling */

/*
 * Function: Error
 * Usage: Error(msg, ...)
 * ----------------------
 * Error generates an error string, expanding % constructions
 * appearing in the error message string just as printf does.
 * If an error handler exception has been introduced (see the
 * "exception.h" facility), the ErrorException exception is
 * raised with the expanded error string as argument.  If
 * there is no ErrorException defined, the program exits
 * with a status code indicating failure (as given by the
 * constant ErrorExitStatus).  The length of the error
 * message string following expansion must not exceed
 * MaxErrorMessage, and it is the client's responsibility
 * to ensure this.
 */

void Error(string msg, ...);

/* Section 4 -- The repeat pseudo-statement */

/*
 * Statement form: repeat { ... }
 * ------------------------------
 * Some instructors who have taught CS1 using this library
 * have found that using
 *
 *     while (TRUE)
 *
 * to initiate a loop with an interior exit is confusing to
 * students, particularly when it comes at the beginning of
 * the course.  This macro defines "repeat" as an infinite
 * loop construct for instructors who find it easier to
 * explain, although it is not used in the text.   Similar
 * macro definitions are common in industry.
 */

#define repeat for (;;)

#endif 
genlib.c

代码: 全选

/*
 * File: genlib.c
 * Version: 1.0
 * Last modified on Sun Jul 24 10:29:46 1994 by eroberts
 * -----------------------------------------------------
 * This file implements the general C library package.  See the
 * interface description in genlib.h for details.
 */

#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdarg.h>

#include "genlib.h"
#include "gcalloc.h"
#include "exception.h"

/*
 * Constants:
 * ----------
 * ErrorExitStatus -- Status value used in exit call
 * MaxErrorMessage -- Longest error message allowed
 */

#define ErrorExitStatus 1
#define MaxErrorMessage 500

/* Section 1 -- Define new "primitive" types */

/*
 * Constant: UNDEFINED
 * -------------------
 * This entry defines the target of the UNDEFINED constant.
 */

char undefined_object[] = "UNDEFINED";

/* Section 2 -- Memory allocation */

/*
 * Implementation notes:
 * ---------------------
 * The code for the memory allocator is divided between
 * genlib.c and gcalloc.c, and the division strategy may at
 * first seem unnatural, since the function ProtectBlock is
 * declared in gcalloc.h but defined here in genlib.c.  The
 * intention is to minimize the size of object files
 * produced by linkers that search a library for modules
 * that are actually referenced.  The libraries themselves
 * need to call ProtectBlock (usually through the macro
 * ProtectVariable), but will not require the actual code
 * for the allocator unless InitGCAllocator is explicitly
 * called.
 */

/*
 * Global variable: _acb
 * ---------------------
 * This variable is used to hold a method suite that makes it
 * easy to substitute a garbage-collecting allocator for the
 * ANSI allocator.
 */

_GCControlBlock _acb = NULL;

/* Memory allocation implementation */

void *GetBlock(size_t nbytes)
{
    void *result;

    if (_acb == NULL) {
        result = malloc(nbytes);
    } else {
        result = _acb->allocMethod(nbytes);
    }
    if (result == NULL) Error("No memory available");
    return (result);
}

void FreeBlock(void *ptr)
{
    if (_acb == NULL) {
        free(ptr);
    } else {
        _acb->freeMethod(ptr);
    }
}

void ProtectBlock(void *ptr, size_t nbytes)
{
    if (_acb != NULL) _acb->protectMethod(ptr, nbytes);
}

/* Section 3 -- Basic error handling */

/*
 * Implementation notes: Error
 * ---------------------------
 * Writing the Error function requires some care, since it is
 * called in circumstances in which parts of the system may be
 * broken.  In particular, it is not acceptable for Error to
 * call GetBlock, since the error condition may be that the
 * system is out of memory, in which case calling GetBlock would
 * fail.  The error string should be allocated dynamically,
 * so that this function can be used in reentrant code.
 * Note that it is critical to exit if the length bound for
 * an error message is exceeded, since this error almost
 * certainly corrupts the stack.
 */

void Error(string msg, ...)
{
    va_list args;
    char errbuf[MaxErrorMessage + 1];
    string errmsg;
    int errlen;

    va_start(args, msg);
    vsprintf(errbuf, msg, args);
    va_end(args);
    errlen = strlen(errbuf);
    if (errlen > MaxErrorMessage) {
        fprintf(stderr, "Error: Error Message too long\n");
        exit(ErrorExitStatus);
    }
    if (_acb == NULL) {
        errmsg = malloc(errlen + 1);
    } else {
        errmsg = _acb->allocMethod(errlen + 1);
    }
    if (errmsg == NULL) {
        errmsg = "No memory available";
    } else {
        strcpy(errmsg, errbuf);
    }
    if (HandlerExists(&ErrorException)) {
        RaiseException(&ErrorException, "ErrorException", errmsg);
    } else {
        fprintf(stderr, "Error: %s\n", errmsg);
        exit(ErrorExitStatus);
    }
} 
勤能補拙 Just do it now!

头像
unreal
银 Ag
帖子: 1081
注册时间: 2010-06-07 18:52

回复: 如何将c源程序在openbsd中编译链接后执行?

帖子 unreal » 2012-10-23 21:45

simpio.h

代码: 全选

/*
 * File: simpio.h
 * Version: 1.0
 * Last modified on Wed Apr 27 07:29:13 1994 by eroberts
 * -----------------------------------------------------
 * This interface provides access to a simple package of
 * functions that simplify the reading of input data.
 */

#ifndef _simpio_h
#define _simpio_h

#include "genlib.h"

/*
 * Function: GetInteger
 * Usage: i = GetInteger();
 * ------------------------
 * GetInteger reads a line of text from standard input and scans
 * it as an integer.  The integer value is returned.  If an
 * integer cannot be scanned or if more characters follow the
 * number, the user is given a chance to retry.
 */

int GetInteger(void);

/*
 * Function: GetLong
 * Usage: l = GetLong();
 * ---------------------
 * GetLong reads a line of text from standard input and scans
 * it as a long integer.  The value is returned as a long.
 * If an integer cannot be scanned or if more characters follow
 * the number, the user is given a chance to retry.
 */

long GetLong(void);

/*
 * Function: GetReal
 * Usage: x = GetReal();
 * ---------------------
 * GetReal reads a line of text from standard input and scans
 * it as a double.  If the number cannot be scanned or if extra
 * characters follow after the number ends, the user is given
 * a chance to reenter the value.
 */

double GetReal(void);

/*
 * Function: GetLine
 * Usage: s = GetLine();
 * ---------------------
 * GetLine reads a line of text from standard input and returns
 * the line as a string.  The newline character that terminates
 * the input is not stored as part of the string.
 */

string GetLine(void);

/*
 * Function: ReadLine
 * Usage: s = ReadLine(infile);
 * ----------------------------
 * ReadLine reads a line of text from the input file and
 * returns the line as a string.  The newline character
 * that terminates the input is not stored as part of the
 * string.  The ReadLine function returns NULL if infile
 * is at the end-of-file position.
 */

string ReadLine(FILE *infile);

#endif 
simpio.c

代码: 全选

/*
 * File: simpio.c
 * Version: 3.0
 * Last modified on Tue Oct  4 11:24:40 1994 by eroberts
 * -----------------------------------------------------
 * This file implements the simpio.h interface.
 */

#include <stdio.h>
#include <string.h>

#include "genlib.h"
#include "strlib.h"
#include "simpio.h"

/*
 * Constants:
 * ----------
 * InitialBufferSize -- Initial buffer size for ReadLine
 */

#define InitialBufferSize 120

/* Exported entries */

/*
 * Functions: GetInteger, GetLong, GetReal
 * ---------------------------------------
 * These functions first read a line and then call sscanf to
 * translate the number.  Reading an entire line is essential to
 * good error recovery, because the characters after the point of
 * error would otherwise remain in the input buffer and confuse
 * subsequent input operations.  The sscanf line allows white space
 * before and after the number but no other extraneous characters.
 */

int GetInteger(void)
{
    string line;
    int value;
    char termch;

    while (TRUE) {
        line = GetLine();
        if (line == NULL) Error("GetInteger: unexpected end of file");
        switch (sscanf(line, " %d %c", &value, &termch)) {
          case 1:
            FreeBlock(line);
            return (value);
          case 2:
            printf("Unexpected character: '%c'\n", termch);
            break;
          default:
            printf("Please enter an integer\n");
            break;
        }
        FreeBlock(line);
        printf("Retry: ");
    }
}

long GetLong(void)
{
    string line;
    long value;
    char termch;

    while (TRUE) {
        line = GetLine();
        if (line == NULL) Error("GetLong: unexpected end of file");
        switch (sscanf(line, " %ld %c", &value, &termch)) {
          case 1:
            FreeBlock(line);
            return (value);
          case 2:
            printf("Unexpected character: '%c'\n", termch);
            break;
          default:
            printf("Please enter an integer\n");
            break;
        }
        FreeBlock(line);
        printf("Retry: ");
    }
}

double GetReal(void)
{
    string line;
    double value;
    char termch;

    while (TRUE) {
        line = GetLine();
        if (line == NULL) Error("GetReal: unexpected end of file");
        switch (sscanf(line, " %lf %c", &value, &termch)) {
          case 1:
            FreeBlock(line);
            return (value);
          case 2:
            printf("Unexpected character: '%c'\n", termch);
            break;
          default:
            printf("Please enter a real number\n");
            break;
        }
        FreeBlock(line);
        printf("Retry: ");
    }
}

/*
 * Function: GetLine
 * -----------------
 * This function is a simple wrapper; all the work is done by
 * ReadLine.
 */

string GetLine(void)
{
    return (ReadLine(stdin));
}

/*
 * Function: ReadLine
 * ------------------
 * This function operates by reading characters from the file
 * into a dynamically allocated buffer.  If the buffer becomes
 * full before the end of the line is reached, a new buffer
 * twice the size of the previous one is allocated.
 */

string ReadLine(FILE *infile)
{
    string line, nline;
    int n, ch, size;

    n = 0;
    size = InitialBufferSize;
    line = GetBlock(size + 1);
    while ((ch = getc(infile)) != '\n' && ch != EOF) {
        if (n == size) {
            size *= 2;
            nline = (string) GetBlock(size + 1);
            strncpy(nline, line, n);
            FreeBlock(line);
            line = nline;
        }
        line[n++] = ch;
    }
    if (n == 0 && ch == EOF) {
        FreeBlock(line);
        return (NULL);
    }
    line[n] = '\0';
    nline = (string) GetBlock(n + 1);
    strcpy(nline, line);
    FreeBlock(line);
    return (nline);
} 
勤能補拙 Just do it now!

回复

在线用户

正浏览此版面之用户: 没有注册用户 和 1 访客