Home > OS >  GCC/CC unable to compile C project with multiple files (mac os)
GCC/CC unable to compile C project with multiple files (mac os)

Time:06-30

I am getting started with C programming as part of some course work. My IDE suggests I have constructed the following correctly (i.e. go to definition works, no red squigglies), but gcc and cc are both rejecting it with a similar error message:

main.c:

#include "help.h"

int main(int argc, const char* argv[]) {
    herp();
    return 0;
}

help.h

#ifndef help_herp
#define help_herp

void herp();

#endif

help.c

#include "help.h"

void herp() {
    // nothing
}

Seems pretty simple (but I am an extreme beginner with C, so I may have just left some boilerplate off). Unfortunately it's not compiling:

gcc main.c -o out

Undefined symbols for architecture x86_64:
  "_herp", referenced from:
      _main in main-538251.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

You can use -v but it's honestly not super helpful (or at least not to me):

gcc main.c -o out -v

Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin19.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.15.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=all -fno-strict-return -masm-verbose -munwind-tables -target-sdk-version=10.15.4 -fcompatibility-qualified-id-block-type-checking -target-cpu penryn -dwarf-column-info -debugger-tuning=lldb -target-linker-version 609.8 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include -internal-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include -internal-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/include -internal-externc-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include -Wno-reorder-init-list -Wno-implicit-int-float-conversion -Wno-c99-designator -Wno-final-dtor-non-final-class -Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-quoted-include-in-framework-header -Wno-implicit-fallthrough -Wno-enum-enum-conversion -Wno-enum-float-conversion -fdebug-compilation-dir /Users/richard.rast/hacks/cderp -ferror-limit 19 -fmessage-length 254 -stack-protector 1 -fstack-check -mdarwin-stkchk-strong-link -fblocks -fencode-extended-block-signature -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fobjc-runtime=macosx-10.15.0 -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/hy/6j_xcjw100g_037n1zmydvfc3rt5bn/T/main-6e386a.o -x c main.c
clang -cc1 version 12.0.0 (clang-1200.0.32.29) default target x86_64-apple-darwin19.6.0
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/local/include"
ignoring nonexistent directory "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory)
End of search list.
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -platform_version macos 10.15.0 10.15.4 -syslibroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -o out -L/usr/local/lib /var/folders/hy/6j_xcjw100g_037n1zmydvfc3rt5bn/T/main-6e386a.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
  "_herp", referenced from:
      _main in main-6e386a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Same issue if I use cc.

Note that if I skip the link step (which is, erm, important), it seems to work:

gcc main.c -o out -c

(generates no output, there is a file called out with 672 bytes in it)

so I assume it's a linker issue. I don't know if this is something specific to setting up C on a mac, or what -- I have been running and compiling Java / JS / Rust / Golang / Python on this machine for years, but I haven't had a need to work with C directly.

Similar error messages happen if I swap out gcc for cc or clang.

I would appreciate even any way to get more useful information on this error message; as it is, it's saying something doesn't exist, when it clearly does, and I'm at a loss.

CodePudding user response:

This is a good time to learn about the concept of translation units.

The compiler only deals with one single translation unit at a time, it will not know anything about other possible translation units, it's the job of the linker to put all translation units together.

Your command you use to build your program:

gcc main.c -o out

That only compiles and attempts to link one of the two translation units, the one created from main.c. The translation unit from help.c isn't used at all.

You need to pass both source files for the front-end program gcc to build and link both of them:

gcc main.c help.c -o out

CodePudding user response:

in your help.c file, there should be a void herp(); function, but not a main function. Since C does not support OOP, there can only be one main function among all the source files.

CodePudding user response:

You need to tell the compiler that your project contains two source files:

gcc -o out main.c help.c

Also at your level, I would suggest to use an IDE (for example Eclipse CDT) to focus on programming not building. Later you will learn how to build complicated projects. But now simply learn to program.

  • Related