简体   繁体   English

如何编译带有标题的 c 文件

[英]How to compile c file with headers

I did read all the other posts unable to find a conclusive answer.NB I know what linker error is.我确实阅读了所有其他帖子,但找不到确凿的答案。NB 我知道 linker 错误是什么。 Here is my file.这是我的文件。 I'm trying to compile it as gcc -o sapy test_assign1_1.c Assignment1.c and getting error我正在尝试将其编译为gcc -o sapy test_assign1_1.c Assignment1.c并出现错误

Undefined symbols for architecture x86_64:
  "_errorMessage", referenced from:
      _testCreateOpenClose in test_assign1_1-506ae6.o
      _testSinglePageContent in test_assign1_1-506ae6.o
      _additionalTestCases in test_assign1_1-506ae6.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 just want to know the minimum command that should I type to make this program compile.我只想知道我应该输入的最小命令来编译这个程序。 A bonus would be to know how can I set it up on VScode.一个好处是知道如何在 VScode 上设置它。

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

#include "storage_mgr.h"
#include "dberror.h"
#include "test_helper.h"

// test name
char *testName;

/* test output files */
#define PAGEFILETEST "test_pagefile.bin"

/* prototypes for test functions */
static void testCreateOpenClose(void);
static void testSinglePageContent(void);
static void additionalTestCases(void);

/* main function running all tests */
int
main (void)
{
    testName = "";

    initStorageManager();
    testCreateOpenClose();
    testSinglePageContent();
    additionalTestCases();
    return 0;
}


/* check a return code. If it is not RC_OK then output a message, error description, and exit */
/* Try to create, open, and close a page file */
void
testCreateOpenClose(void)
{
    SM_FileHandle fh;
    //SM_PageHandle ph = (SM_PageHandle) malloc(PAGE_SIZE);
    testName = "test create open and close methods";

    TEST_CHECK(createPageFile (PAGEFILETEST));
    printf(" Page file created");
    TEST_CHECK(openPageFile (PAGEFILETEST, &fh));
    ASSERT_TRUE(strcmp(fh.fileName, PAGEFILETEST) == 0, "filename correct");
    ASSERT_TRUE((fh.totalNumPages == 1), "expect 1 page in new file");
    ASSERT_TRUE((fh.curPagePos == 0), "freshly opened file's page position should be 0");

    TEST_CHECK(closePageFile (&fh));
    TEST_CHECK(destroyPageFile (PAGEFILETEST));
    // after destruction trying to open the file should cause an error
    ASSERT_TRUE((openPageFile(PAGEFILETEST, &fh) != RC_OK), "opening non-existing file should return an error.");
    // memset(ph, 0, PAGE_SIZE);
    //TEST_CHECK(writeCurrentBlock(&fh,ph))
    TEST_DONE();
}

/* Try to create, open, and close a page file */
void
testSinglePageContent(void)
{
    SM_FileHandle fh;
    SM_PageHandle ph;
    int i;

    testName = "test single page content";


    ph = (SM_PageHandle) malloc(PAGE_SIZE);

    // create a new page file
    TEST_CHECK(createPageFile (PAGEFILETEST));
    TEST_CHECK(openPageFile (PAGEFILETEST, &fh));

    // read first page into handle
    TEST_CHECK(readFirstBlock (&fh, ph));
    // the page should be empty (zero bytes)
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page");
    printf("first block was empty\n");

    // change ph to be a string and write that one to disk
    for (i=0; i < PAGE_SIZE; i++)
        ph[i] = (i % 10) + '0';
    TEST_CHECK(writeBlock (0, &fh, ph));
    printf("writing first block\n");

    // read back the page containing the string and check that it is correct
    TEST_CHECK(readFirstBlock (&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected.");
    printf("reading first block\n");
    TEST_CHECK(writeCurrentBlock(&fh,ph));
    // printf("run writeCurrentBlock with 1...\n");
    // destroy new page file
    TEST_CHECK(destroyPageFile (PAGEFILETEST));

    TEST_DONE();
}

void additionalTestCases(void){
    SM_FileHandle fh;
    SM_PageHandle ph;
    int i;

    testName = "test multiple page content";


    ph = (SM_PageHandle) malloc(PAGE_SIZE);

    // create a new page file
    TEST_CHECK(createPageFile (PAGEFILETEST));
    TEST_CHECK(openPageFile (PAGEFILETEST, &fh));

    // read first page into handle
    TEST_CHECK(readFirstBlock (&fh, ph));
    // the page should be empty (zero bytes)
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == 0), "expected zero byte in first page of freshly initialized page");
    printf("first block was empty\n");

    // change ph to be a string and write that one to disk
    for (i=0; i < PAGE_SIZE; i++)
        ph[i] = (i % 10) + '0';
    TEST_CHECK(writeBlock (0, &fh, ph));
    printf("writing first block\n");

    // read back the page containing the string and check that it is correct
    TEST_CHECK(readFirstBlock (&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "character in page read from disk is the one we expected.");
    printf("reading first block\n");
    TEST_CHECK(writeCurrentBlock(&fh,ph));


    // Reading the next block from file.
    TEST_CHECK(readNextBlock (&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "Expecting character in page read from disk.");
    printf("Reading next block \n");

    // Reading the current block from file.
    TEST_CHECK(readCurrentBlock (&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "Expecting character in page read from disk.");
    TEST_CHECK(readPreviousBlock (&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "Expecting character in page read from disk.");
    printf("Reading previous block \n");


    // Reading the specific block (2nd block in this case) from file.
    TEST_CHECK(readBlock(2,&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "Expecting character in page read from disk.");
    printf("Reading second block \n");

    // Reading the last block from file.
    TEST_CHECK(readLastBlock (&fh, ph));
    for (i=0; i < PAGE_SIZE; i++)
        ASSERT_TRUE((ph[i] == (i % 10) + '0'), "Expecting character in page read from disk.");
    printf("Reading last block \n");

    // destroy new page file
    TEST_CHECK(destroyPageFile (PAGEFILETEST));

    TEST_DONE();
}

As the best practice goes, you need to have the corresponding .c files for each of your custom headers.作为最佳实践,您需要为每个自定义标头拥有相应的.c文件。

gcc -o sapy storage_mgr.c dberror.c test_helper.c

If you do not want to expose the source code of your function defined in the custom headers, you can use如果您不想公开自定义标头中定义的 function 的源代码,可以使用

gcc -c storage_mgr.c dberror.c test_helper.c

to get the object ( .o ) files and get the final executable by compiling the object files together as获取 object ( .o ) 文件并通过将 object 文件一起编译来获得最终可执行文件

gcc -o sapy storage_mgr.o dberror.o test_helper.o

so imagine you have a program on c called "test.c" like this one:所以想象一下,你在 c 上有一个名为“test.c”的程序,如下所示:

#include "a.h"
#include "b.h"
#include "c.h"

int main(void){
 // do something
}

Then, You will have a folder like this然后,您将有一个这样的文件夹

|
|--test.c
|--a.c
|--a.h
|--b.c
|--b.h
|--c.h 

In order to compile this, you should just write:为了编译它,你应该只写:

gcc -o test test.c a.c b.c c.h

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM