1

I have an Xcode project where I am using C to handle a low level task so I created the C file and the bridging header. However, I am getting a linker error when I try to build my project: "Linker command failed with exit code 1 (use -v to see invocation)"

Here is my .c file :

#include <stdio.h>
#include <IOKit/IOKitLib.h>


typedef struct {
    uint32_t datasize;
    uint32_t datatype;
    uint8_t data[32];
    
} SMCVal_t;


io_connect_t conn;

kern_return_t openSMC(void) {
    
    kern_return_t result;
    kern_return_t service;
    io_iterator_t iterator;
    
    service = IOServiceGetMatchingServices(kIOMainPortDefault, IOServiceMatching("AppleSMC"), &iterator);
    if(service == 0) {
        printf("error: could not match dictionary");
        return 0;
    }
    result = IOServiceOpen(service, mach_task_self(), 0, &conn);
    IOObjectRelease(service);
    return 0;
}

    
kern_return_t closeSMC(void) {
    return IOServiceClose(conn);
}

double getTemperature(char *key);
    
kern_return_t readSMC(char *key, SMCVal_t *val) {

    kern_return_t result;
    uint32_t keyCode = *(uint32_t *)key;
    
    SMCVal_t inputStruct;
    SMCVal_t outputStruct;
    
    inputStruct.datasize = sizeof(SMCVal_t);
    inputStruct.datatype = 'I' << 24;            //a left shift operation. turning the I into an int by shifting the ASCII value 24 bits to the left
    
    inputStruct.data[0] = keyCode;
    result = IOConnectCallStructMethod(conn, 5, &inputStruct, sizeof(SMCVal_t), &outputStruct, (size_t*)&inputStruct.datasize);
    
    if (result == kIOReturnSuccess) {
        if (val -> datasize > 0) {
            if (val -> datatype == ('f' << 24 | 'l' << 16 | 't' << 8 )) {
                float temp = *(float *)val -> data;
                return temp;
            }
        }
    }
    return 0.0;
    
}

    
int main(void) {
    
    kern_return_t result;
    
    result = openSMC();
    
    if(result == kIOReturnSuccess) {
        double temp = getTemperature("TC0P");
        printf("temp: %.2f\n", temp);
        
        result = closeSMC();
    }
    return 0;
}

and below here is my corresponding header file:

#ifndef getsmc_h
#define getsmc_h
#include <stdio.h>
#include <IOKit/IOKitLib.h>

typedef struct {
    
    uint32_t datasize;
    uint32_t datatype;
    uint32_t data[32];
    
} SMCVal_t;

kern_return_t openSMC(void);
kern_return_t closeSMC(void);
kern_return_t readSMC(char *key, SMCVal_t *val);

double getTemperature(char *key);

#endif /* getsmc_h */
5
  • 1
    “Linker command failed with exit code 1” is not a linker error message. It is a shell or whatever ran the linker telling you that the linker failed. The actual linker error message is just above that (if the window contains a stream of text output from the build) or in some other window of your IDE. Find the linker error message and show that. (Actually, first, read the linker error message and try to understand it.) Commented Jan 1, 2024 at 18:04
  • 1
    Why do you have two definitions for SMCVal_t but with a different type for the array member data? Commented Jan 1, 2024 at 18:10
  • Note that the declarations in the header do not use any information from <stdio.h> so the header should not include <stdio.h>. Headers should be self-contained, idempotent and minimal — see Should I use #include in headers? for more information about this. Every source file (.c file) that defines or uses any of the facilities declared in your header, getsmc.h, should include that header. Headers are the glue that ensure consistency between translation units. Commented Jan 1, 2024 at 23:27
  • Why does Swift appear in the list of tags? Your code appears to be C code, not Swift code. Commented Jan 1, 2024 at 23:33
  • @JonathanLeffler I only added the swift tag because my c files are part of a bigger swift Xcode project where im just using C to access low level hardware on my Mac machine thats the only reason why I included the swift tag. Commented Jan 2, 2024 at 19:06

1 Answer 1

2

Your C file has only the declaration line

double getTemperature(char *key);

Later, this function is accessed in your main function in the line

            double temp = getTemperature("TC0P");

Since there's no getTemperature function for the linker to link to, this would cause a linker error to occur.


On a side note, your C file doesn't include your header file, so it doesn't have any effect on the compilation and linking.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.