使用自定义c++库对的未定义引用

undefined reference to with custom c++ libraries

本文关键字:未定义 引用 自定义 c++      更新时间:2023-10-16

这是我在运行make clean all时遇到的错误:

rm -f mux-tool.o mux-tool
g++ -ggdb -Wall -I ../include -c mux-tool.cpp
g++ -ggdb -Wall -I ../include -o mux-tool ../system/usermux/usermux.o mux-tool.o
mux-tool.o: In function `main':
/home/mdrc/beagle/user-space/mux-tools/mux-tool.cpp:35: undefined reference to `setmux(MuxConfig*)'
/home/mdrc/beagle/user-space/mux-tools/mux-tool.cpp:41: undefined reference to `getmux(MuxConfig*)'
collect2: ld returned 1 exit status
make: *** [mux-tool] Error 1

在用户空间/include/system中,我有如下的usermux.h:

typedef struct {
    unsigned long address;
    unsigned char mode;
    unsigned char input_enable;
    unsigned char pullupdown_enable;
    unsigned char pullupdown_up;
} MuxConfig;
int setmux(MuxConfig* mux);
int getmux(MuxConfig* mux);

在用户空间/系统/usermux中,usermux.c带有:

#include <system/usermux.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)
int setmux(MuxConfig* mux) {
    int fd;
    void *map_base, *virt_addr; 
    unsigned short writeval;
    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
        return -1;
    }
    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mux->address & ~MAP_MASK);
    if(map_base == (void *) -1) return -1;
    virt_addr = map_base + (mux->address & MAP_MASK);
                                writeval = mux->mode & 7;
    if (mux->input_enable)      writeval |= 1 << 8;
    if (mux->pullupdown_enable) writeval |= 1 << 3;
    if (mux->pullupdown_up)     writeval |= 1 << 4;
    *((unsigned short *) virt_addr) = writeval;
    if (close(fd)) return -1;
    return 0;
}
int getmux(MuxConfig* mux) {
    int fd;
    void *map_base, *virt_addr; 
    unsigned short readval;
    if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
        return -1;
    }
    map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mux->address & ~MAP_MASK);
    if(map_base == (void *) -1) return -1;
    virt_addr = map_base + (mux->address & MAP_MASK);
    readval = *((unsigned short *) virt_addr);
    mux->mode               = readval &   0x7;
    mux->pullupdown_enable  = (readval &   0xF) != 0;
    mux->pullupdown_up      = (readval &  0x10) != 0;
    mux->input_enable       = (readval & 0x100) != 0;
    if (close(fd)) return -1;
    return 0;
}

最后,在用户空间/mux工具是我的Makefile和mux-tool.cpp:

CFLAGS= -ggdb -Wall
USER_INCLUDES= -I ../include
all: mux-tool
mux-tool: mux-tool.o
    $(CROSS_COMPILE)g++ $(CFLAGS) $(USER_INCLUDES) -o mux-tool ../system/usermux/usermux.o mux-tool.o
mux-tool.o: mux-tool.cpp
    $(CROSS_COMPILE)g++ $(CFLAGS) $(USER_INCLUDES) -c mux-tool.cpp
clean:
    rm -f mux-tool.o mux-tool


#include <system/usermux.h>
#include <cstdlib>
#include <iostream>
using namespace std;
void usage(char* name) {
    cout << "Usage: " << name << " address [mode input_enable pu_en pu_up]" << endl;
    cout << "taddress: Address of pad config. Note that this utility uses half-word addresses" << endl;
    cout << "tmode: Mux mode for the pin, 0-7" << endl;
    cout << "tinput_enable: 1 to enable using pin as input, 0 otherwise" << endl;
    cout << "tpu_en: 1 to enable the pull up/down, 0 to disable" << endl;
    cout << "tpu_up: 1 to use pull up, 0 for pull down" << endl;
}
int main(int argc, char** argv) {
    MuxConfig mux;
    if (argc < 6) {
        if (argc < 2) {
            usage(argv[0]);
            exit(1);
        }
        mux.address = strtoul(argv[1], 0, 0);
        if (argc > 2) {
            mux.mode = atoi(argv[2]);
            mux.input_enable = atoi(argv[3]);
            mux.pullupdown_enable = atoi(argv[4]);
            mux.pullupdown_up = atoi(argv[5]);
            if (setmux(&mux)) {
                cerr << "Error setting mux configuration" << endl;
            } else {
                cout << "Mux set successfully." << endl;
            }
        } else {
            if (getmux(&mux)) {
                cerr << "Error reading mux configuration" << endl;
            } else {
                cout << "Mux config for address " << hex << mux.address << endl;
                cout << "tMode: " << dec << mux.mode << endl;
                cout << "tInput: ";
                if (mux.input_enable) {
                    cout << "enabled";
                } else {
                    cout << "disabled";
                }
                cout << endl;
                cout << "tPull Up/Down: ";
                if (mux.pullupdown_enable) {
                    if (mux.pullupdown_up) {
                        cout << "up";
                    } else {
                        cout << "down";
                    }
                    cout << endl;
                } else {
                    cout << "disabled";
                }
                cout << endl;
            }
        }
    }
}

我认为实用程序的头文件需要

#ifdef __cplusplus
extern "C" {
#endif
// ...
#ifdef __cplusplus
}
#endif

在头文件中或在#include中围绕它。如果让C++编译器在不使用extern "C"的情况下解释声明,那么它将期望有损坏的名称,并且找不到未损坏的C符号。