Как скомпилировать c файл с заголовками - PullRequest
0 голосов
/ 07 октября 2019

Я прочитал все остальные сообщения, не найдя убедительного ответа. Я знаю, что такое ошибка компоновщика. Вот мой файл. Я пытаюсь скомпилировать его как 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)

Я просто хочу знать минимальную команду, которую я должен набрать для , чтобы эта программа компилировалась. Бонусом будет знать, как я могу настроить его на 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();
}

Ответы [ 2 ]

1 голос
/ 07 октября 2019

В соответствии с рекомендациями, вам необходимо иметь соответствующие .c файлы для каждого из ваших пользовательских заголовков.

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

Если вы не хотите раскрывать источниккод вашей функции, определенный в пользовательских заголовках, вы можете использовать

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

, чтобы получить файлы объекта (.o) и получить конечный исполняемый файл, скомпилировав объектные файлы вместе как

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

0 голосов
/ 07 октября 2019

так что представьте, что у вас есть программа на c с именем "test.c", подобная этой:

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

int main(void){
 // do something
}

Тогда у вас будет папка, подобная этой

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

. Чтобы скомпилировать это, вы должны просто написать:

gcc -o test test.c a.c b.c c.h
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...