LLVM cannot find clang binary - clang

I have just built and installed LLVM Clang 3.5.0 with compiler-rt. clang binary seems to work, but cannot build a simple test program:
$ cat hello.c
#include <stdio.h>
int main(int argc, char **argv) {
printf("Hello World\n");
return 0;
}
Building it borks with error: unable to execute command: Executable "" doesn't exist!
$ clang hello.c -o hello
error: unable to execute command: Executable "" doesn't exist!
Executable "" ? Interesting...
Debugging it further reveals that clang tries to call itself to build .o object file and then ld to link it, but does not know where itself exists apparently.
$ clang -### hello.c -o hello
clang version 3.5.0 (tags/RELEASE_350/final)
Target: x86_64-alpine-linux-musl
Thread model: posix
"" "-cc1" "-triple" "x86_64-alpine-linux-musl" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "hello.c" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-fuse-init-array" "-target-cpu" "x86-64" "-target-linker-version" "2.24" "-dwarf-column-info" "-resource-dir" "../lib/clang/3.5.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "../lib/clang/3.5.0/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/" "-ferror-limit" "19" "-fmessage-length" "158" "-mstackrealign" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-o" "/tmp/hello-37746e.o" "-x" "c" "hello.c"
"/usr/bin/ld" "-z" "relro" "--eh-frame-hdr" "-m" "elf_x86_64" "-dynamic-linker" "/lib/ld-musl-x86_64.so.1" "-o" "hello" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crt1.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crti.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/crtbegin.o" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../../x86_64-alpine-linux-musl/lib" "-L/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../.." "-L/../lib" "-L/lib" "-L/usr/lib" "/tmp/hello-37746e.o" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "-lc" "-lgcc" "--as-needed" "-lgcc_s" "--no-as-needed" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/crtend.o" "/usr/bin/../lib/gcc/x86_64-alpine-linux-musl/4.8.3/../../../crtn.o"
When I run the first line putting /usr/bin/clang as the first item, it builds just fine:
$ /usr/bin/clang "-cc1" "-triple" "x86_64-alpine-linux-musl" "-emit-obj" "-mrelax-all" "-disable-free" "-main-file-name" "hello.c" "-mrelocation-model" "static" "-mdisable-fp-elim" "-fmath-errno" "-masm-verbose" "-mconstructor-aliases" "-munwind-tables" "-target-cpu" "x86-64" "-target-linker-version" "2.24" "-dwarf-column-info" "-resource-dir" "../lib/clang/3.5.0" "-internal-isystem" "/usr/local/include" "-internal-isystem" "../lib/clang/3.5.0/include" "-internal-externc-isystem" "/include" "-internal-externc-isystem" "/usr/include" "-fdebug-compilation-dir" "/" "-ferror-limit" "19" "-fmessage-length" "158" "-mstackrealign" "-fobjc-runtime=gcc" "-fdiagnostics-show-option" "-o" "/tmp/hello-4f64bb.o" "-x" "c" "hello.c"
$
And following /usr/bin/ld is able to link it just fine resulting in:
$ ./hello
Hello World
Anny suggestions what did I screw during configure/build?

clang source analysis shows that 'clang' program on Linux uses /proc/self/exe to find out real path of its binary. I am running in chroot without /proc mounted, thus it failed.
mount -t proc proc /proc
solves the issue

Related

LLVM14: Profile Guided Optimization yields "Malformed Instrumentation Profile Data"

Windows 10, Ryzen 3700x, gcc 8.1.0 (Posix, SEH-enabled)
I am building clang, llvm, and compiler-rt (the PGO tools) from source. I have downloaded the clang+llvm source for 14.0.0, and built it successfully with the following:
cmake -G "MinGW Makefiles" -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=X86 ../llvm
After this, I can invoke clang, and build projects, ranging from simple "Hello, World", to a much more complex one. I am able to make use of -flto, with the addition of -fuse-ld=lld.
However, if I attempt to do ANY sort of PGO building, I fail. For example, here is the minimal example to demonstrate the problem.
Andrew#Ryzen3700x MINGW64 ~/Desktop
$ cat test.c
#include <stdio.h>
int main() {
printf("Hello, World!");
return 0;
}
Andrew#Ryzen3700x MINGW64 ~/Desktop
$ clang -fprofile-instr-generate test.c
Andrew#Ryzen3700x MINGW64 ~/Desktop
$ ./a.exe
Hello, World!
Andrew#Ryzen3700x MINGW64 ~/Desktop
$ llvm-profdata merge -output=test.profdata default.profraw
warning: default.profraw: malformed instrumentation profile data
error: no profile can be merged
Andrew#Ryzen3700x MINGW64 ~/Desktop
$ llvm-profdata show default.profraw
error: default.profraw: malformed instrumentation profile data: function name is empty
I am aware of many answers to this question, and none of them seem to apply. My .profraw file is not empty.
I will note that when I installed LLVM/Clang directly (not building on my own), the PGO portions DID work. However, after many hours I could not resolve linking issues regarding -flto.

How to install llvm#13 with Homerew on macOS High Sierra 10.13.6? Got "Built target lldELF" error

Although High Sierra is no longer supported by Homebrew, but I need to install llvm#13 formula as a dependency for other formulas. So I tried to install it this way:
$ brew install llvm
...
==> Downloading https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.0/llvm-project-13.0.0.src.tar.xz
Already downloaded: /Users/username/Library/Caches/Homebrew/downloads/8fd68fc8f968137c5080826db6e58682326235960fd8469363eb27d0799978ca--llvm-project-13.0.0.src.tar.xz
...
==> Installing llvm
==> cmake -G Unix Makefiles .. -DLLVM_ENABLE_PROJECTS=clang;clang-tools-extra;lld;lldb;mlir;polly -DLLVM_ENABLE_RUNTIMES=compiler-rt;libcxx;libcxxabi;libunwind;openmp -DLLVM_POLLY_L
==> cmake --build .
...
[ 79%] Built target lldELF
make: *** [all] Error 2
An error is occurred after a long time of compilation. I also found this error in ~/Library/Logs/Homebrew/llvm/02.cmake:
/tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm:246:52: error: use of undeclared identifier 'CPU_SUBTYPE_ARM64E'
if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
^
1 error generated.
make[2]: *** [tools/lldb/source/Host/macosx/objcxx/CMakeFiles/lldbHostMacOSXObjCXX.dir/HostInfoMacOSX.mm.o] Error 1
make[1]: *** [tools/lldb/source/Host/macosx/objcxx/CMakeFiles/lldbHostMacOSXObjCXX.dir/all] Error 2
How can I fix that compilation error?
Install llvm with debug mode enabled:
$ brew install --debug llvm
Installation process encounters with the same error mentioned in the question, but some options are provided to fix the issue. Choose option 5:
- raise
- ignore
- backtrace
- irb
- shell
Choose an action: 5
It gives a shell access to the current build directory of llvm formula. Find the current folder:
$ pwd
/private/tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src
Change the location to the build directory:
cd llvm/build
Edit the HostInfoMacOSX.mm and remove the second part of condition:
vi ../../lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
You need to change the line 246 from:
if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
to:
if (cputype == CPU_TYPE_ARM64) {
Then re-run the last command:
$ cmake --build .
It takes some time to be completed:
...
[100%] Linking CXX executable ../../../../bin/lldb-vscode
cd /tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/tools/lldb/tools/lldb-vscode && /usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_link_script CMakeFiles/lldb-v
scode.dir/link.txt --verbose=1
/usr/local/Homebrew/Library/Homebrew/shims/mac/super/clang++ -stdlib=libc++ -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -Wall -Wextra -Wn
o-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -pedantic -Wno-long-long -Wc++98-compat-extra-semi -Wimplicit-fallthrough -Wcovered-switch-default -Wno-c
lass-memaccess -Wno-noexcept-type -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion -Wmisleading-indentation -Wno-deprecated-declarations -Wno-unkn
own-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -O3 -DNDEBUG -Wl,-search_paths_first -Wl,-headerpad_max_install_names -stdlib=libc++ -Wl,-sectcreate,__
TEXT,__info_plist,/tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/tools/lldb/tools/lldb-vscode/lldb-vscode-Info.plist -Wl,-dead_strip CMakeFiles/lldb-vscode.dir/
lldb-vscode.cpp.o CMakeFiles/lldb-vscode.dir/BreakpointBase.cpp.o CMakeFiles/lldb-vscode.dir/ExceptionBreakpoint.cpp.o CMakeFiles/lldb-vscode.dir/FifoFiles.cpp.o CMakeFiles/lldb-vsc
ode.dir/FunctionBreakpoint.cpp.o CMakeFiles/lldb-vscode.dir/IOStream.cpp.o CMakeFiles/lldb-vscode.dir/JSONUtils.cpp.o CMakeFiles/lldb-vscode.dir/LLDBUtils.cpp.o CMakeFiles/lldb-vsco
de.dir/OutputRedirector.cpp.o CMakeFiles/lldb-vscode.dir/ProgressEvent.cpp.o CMakeFiles/lldb-vscode.dir/RunInTerminal.cpp.o CMakeFiles/lldb-vscode.dir/SourceBreakpoint.cpp.o CMakeFi
les/lldb-vscode.dir/VSCode.cpp.o -o ../../../../bin/lldb-vscode -Wl,-rpath,#loader_path/../lib ../../../../lib/liblldb.13.0.0.dylib -lpthread ../../../../lib/libclang-cpp.dylib ../
../../../lib/libLLVM.dylib
[100%] Built target lldb-vscode
/usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_progress_start /tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/CMakeFiles 0
Then run the install command:
$ cmake --build . --target install
The tail of the result should be:
...
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./CheckAtomic.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/lib/cmake/llvm/./TableGen.cmake
Execute the last command:
$ cmake --build . --target install-xcode-toolchain
The tail of the results should be:
...
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./CheckAtomic.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./FindSphinx.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./FindGRPC.cmake
-- Installing: /usr/local/Cellar/llvm/13.0.0_1/Toolchains/LLVM13.0.0.xctoolchain//usr/lib/cmake/llvm/./TableGen.cmake
Built target install-xcode-toolchain
/usr/local/Cellar/cmake/3.21.4/bin/cmake -E cmake_progress_start /tmp/llvm-20211109-12151-m0zvtm/llvm-project-13.0.0.src/llvm/build/CMakeFiles 0
Then press control+d to return to debug menu. Because the two last commands were run manually, you need to ignore the rest of errors by choosing the option 2:
- raise
- ignore
- backtrace
- irb
- shell
Choose an action: 2
==> cmake --build . --target install
...
cmake
--build
.
--target
install
Error: could not load cache
BuildError: Failed executing: cmake --build . --target install
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2
==> cmake --build . --target install-xcode-toolchain
...
cmake
--build
.
--target
install-xcode-toolchain
Error: could not load cache
BuildError: Failed executing: cmake --build . --target install-xcode-toolchain
1. raise
2. ignore
3. backtrace
4. irb
5. shell
Choose an action: 2
It will continue to install to the rest:
==> Fixing /usr/local/Cellar/llvm/13.0.0_1/bin/FileCheck permissions from 755 to 555
==> Fixing /usr/local/Cellar/llvm/13.0.0_1/bin/analyze-build permissions from 755 to 555
...
==> Changing dylib ID of /usr/local/Cellar/llvm/13.0.0_1/lib/libunwind.1.0.dylib
from #rpath/libunwind.1.dylib
to /usr/local/opt/llvm/lib/libunwind.1.dylib
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FromPathLoader): loading /usr/local/opt/llvm/.brew/llvm.rb
==> Caveats
To use the bundled libc++ please add the following LDFLAGS:
LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
llvm is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have llvm first in your PATH, run:
echo 'export PATH="/usr/local/opt/llvm/bin:$PATH"' >> ~/.zshrc
For compilers to find llvm you may need to set:
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"
==> Summary
🍺 /usr/local/Cellar/llvm/13.0.0_1: 10,907 files, 1.8GB, built in 1418 minutes 39 seconds
It can be verified this way, the default llvm#10 pre-installed:
$ /usr/bin/clang --version
Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
And the new Homebrew version of llvm#13:
$ /usr/local/opt/llvm/bin/clang --version
Homebrew clang version 13.0.0
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
#HamidRohani provides a great solution for those still tinkering in High Sierra (10.13). Getting a recent version of LLVM to compile on my old MAC with an older XCode (clang version 10.0.1 in my case) was a great help. My nominal contribution...
Alternatively, you could define the symbol after line 41 in HostInfoMacOSX.mm:
// Kludge: Symbol definition extracted from a modern machine.h
#ifndef CPU_SUBTYPE_ARM64E
# define CPU_SUBTYPE_ARM64E ((cpu_subtype_t) 2)
#endif
Now, there's no need to modify line 246. And the definition would resolve any (possible) subsequent references. And let me aggregate the steps shown above conducted in brew's debug-shell:
cmake . -DLLVM_CREATE_XCODE_TOOLCHAIN=On
cmake --build .
cmake --build . --target install
cmake --build . --target install-xcode-toolchain
Regarding the LLVM-related variable, setting LLVM_CREATE_XCODE_TOOLCHAIN to On directs CMake to generate a target named 'install-xcode-toolchain'. 1 The target is a work-around to System Integrity Protection (SIP); "Xcode toolchains are a mostly-undocumented feature that allows multiple copies of low level tools to be installed to different locations, and users can easily switch between them." 2
Brew's Caveats
Brew gives you few caveats necessary to use the new compiler: "because macOS already provides this software and installing another version in parallel can cause all kinds of trouble." To use your new compiler, "You need to have llvm first in your PATH and for compilers to find llvm you may need to set" LDFLAGS and CDFLAGS. But since these gems-of-wisdom appear near the end of a million-lines of output, let me re-iterate here:
export PATH="/usr/local/opt/llvm/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/llvm/lib"
export CPPFLAGS="-I/usr/local/opt/llvm/include"
Setting PATH is straight forward. I however, didn't need to set LDFLAGS or CPPFLAGS. Further, no joy with this additional caveat, "To use the bundled libc++ please add the following LDFLAGS":
export LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib"
Anyway, moving on... To demonstrate that all's good, a C++ foo program that incorporates <filesystem>; a library not in High Sierra:
#include <iostream>
// C++17: Modern C++ compiler has std filesystem
#include <filesystem>
namespace fs = std::filesystem;
typedef std::filesystem::path my_path;
using namespace std;
int main ()
{
fs::path path{"/tmp"};
path /= "foo.txt";
ofstream ofs(path);
ofs << "Hello World." << endl;
ofs.close();
return 0;
}
Clearly, a nonsensical program, But to compile:
unset CPPFLAGS
unset LDFLAGS
clang++ -std=c++17 -L/usr/local/opt/llvm/lib foo.cpp -o foo
Again, showing That I didn't need CPPFLAGS and LDFLAGS. And so, The executable links to the correct libc++ library:
MacIntel:c++fs mjo$ otool -L foo
foo:
/usr/local/opt/llvm/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.50.4)
Enjoy.

Nix's clang won't build wasm

I'm have a C Wasm module with the following import:
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
I'm compiling with Clang 12.0.0 on Linux:
clang --target=wasm32 --no-standard-libraries \
-c -Ofast -o out.o in.c
With the package from my package manager (xbps), this works fine. In Nix (see below for the derivation), however (Clang 12.0.1), I get the following warning on nix-build:
tests/test.h:1:16: warning: unknown attribute 'import_module' ignored [-Wunknown-attributes]
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
^~~~~~~~~~~~~~~~~~~~
tests/test.h:1:38: warning: unknown attribute 'import_name' ignored [-Wunknown-attributes]
__attribute__((import_module("env"), import_name("runtime_exit"))) void exit(int);
This is just a warning, but linking later fails: in fact, clang is attempting to link with ld, not wasm-ld or even lld.
My default.nix specifies:
{ pkgs ? import <nixpkgs> {} }:
let
stdenv = pkgs.llvmPackages_12.stdenv;
src = ./.; # etc, etc
in
stdenv.mkDerivation {
# --- snip ---
buildPhase = ''
clang --target=wasm32 --no-standard-libraries \
-c -Ofast -o $out/out.o in.c
'';
# --- snip ---
buildInputs = [ pkgs.clang_12 pkgs.lld_12 ];
}
I don't see why this shouldn't work, but all the different variations of packages I've tried using seem to suggest that I'm getting at the LLVM toolchain incorrectly.
If this isn't enough information, please let me know. Thanks!
Edit
It looks like Nix isn't respecting the --target argument:
$ nix-shell
[nix-shell:~/...]$ clang -target wasm32 --print-target-triple
x86_64-unknown-linux-gnu
[nix-shell:~/...]$ exit
$ clang --target=wasm32 --print-target-triple
wasm32
Despite the above, clang wasm32 as an available target.
The clang wrapper script given by Nix seems to do something. The compiler should be called with clang-[VERSION] instead of clang, for example as:
clang-12 --target=wasm32 --no-standard-libraries \
-c -std=c99 -Ofast -Wall -Werror -pedantic \
input.c -o output.o

PANIC: unprotected error in call to Lua API (undefined symbol: lua_gettop)

My environment is Lua-5.4.2 Luasocket-3.0-rc1.
When I run lua script directly, it work success.
When i run it through c language, it tell me error.
Error Msg is :
PANIC: unprotected error in call to Lua API (error running script: error loading module 'socket.core' from file '/usr/local/lib/lua/5.4/socket/core.so': undefined symbol: lua_gettop)
Aborted(core dumped)
Does anyone know why?
lua script code is:(test.lua)
#!/usr/local/bin/lua
local socket = require("socket")
print(socket._VERSION)
c code is:(main.c)
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
int main(void)
{
lua_State *L;
L = luaL_newstate();
luaopen_base(L);
luaL_openlibs(L);
printf("lua enter\n");
if (luaL_dofile(L, "test.lua"))
{
luaL_error(L, "error running script: %s", lua_tostring(L, -1));
}
printf("lua exit\n");
while(1) pause();
lua_close(L);
return 0;
}
tl;dr: Pass -Wl,-E to GCC.
I was able to reproduce your problem with this Dockerfile:
FROM gcc:11.1.0
RUN wget https://www.lua.org/ftp/lua-5.4.2.tar.gz \
&& git clone https://github.com/diegonehab/luasocket.git
RUN tar zxf lua-5.4.2.tar.gz \
&& cd lua-5.4.2 \
&& make linux \
&& make install \
&& cd ../luasocket \
&& git checkout 5b18e475f38fcf28429b1cc4b17baee3b9793a62 \
&& make linux LUAV=5.4 \
&& make install LUAV=5.4
COPY test.lua main.c ./
When I run lua test.lua in the resulting Docker container, it works fine. When I run gcc -o test main.c /usr/local/lib/liblua.a -ldl -lm -Wl,-rpath='/usr/local/lib/lua/5.4/socket' && ./test, I get the same panic that you get.
The reason that the standalone Lua binary works and yours doesn't is that the former is linked with -E:
MYLDFLAGS= $(LOCAL) -Wl,-E
ld's documentation for -E says this about it:
If you use dlopen to load a dynamic object which needs to refer back to the symbols defined by the program, rather than some other dynamic object, then you will probably need to use this option when linking the program itself.
Lua uses dlopen to load C modules that you require, and said modules need to call Lua functions, which are linked into your binary, so it makes sense that you need this option. And indeed, when I add -Wl,-E to the GCC command line, then it works fine for me:
root#077bbb831441:/# gcc -o test main.c /usr/local/lib/liblua.a -ldl -lm -Wl,-rpath='/usr/local/lib/lua/5.4/socket' -Wl,-E && ./test
lua enter
LuaSocket 3.0-rc1
lua exit

C/XCode: sh: ./child: No such file or directory. Command runs in terminal but not XCode

So I have a child.c file and I want to compile and run it in my main.c file using the system() function of stdlib.h.
child.c:
#include<stdio.h>
int main(){
printf("I am the child\n");
return 0;
}
main.c:
#include <stdio.h>
#include <stdlib.h>
int main() {
system("cd ~/Desktop/HW3/HW3");
system("gcc -o child child.c");
system("./child");
return 0;
}
everything worked fine when I compile and run main.c in terminal using the following command
abcs-mbp:HW3 abc$ cd
abcs-mbp:~ abc$ cd ~/Desktop/HW3/HW3
abcs-mbp:HW3 abc$ gcc -o main main.c
abcs-mbp:HW3 abc$ ./main
and it ran child.c and printed the following:
I am the child
but when I tried to run the exact same main.c in XCode, XCode gave me the following error:
clang: error: no such file or directory: 'child.c'
clang: error: no input files
sh: ./child: No such file or directory
anybody know why this is happening? I think it has something to do with path, but how can I tell XCode the path of child.c and then tell it to compile child.c?
I also tried
system("cd ~/Desktop/HW3/HW3");
system("gcc -o child child.c");
system("./child");
and
system("/Users/vqianxiao/Desktop/HW3/HW3/ gcc -o child child.c");
but nothing seems to work... any help is appreciated!
the reason that it does not work is a combination of things
1) each 'system' call is run in a separate shell instance,
so the second 'system' call
starts from the directory where the main program is running.
2) things do down from there
a suggested fix:
system("cd ~/Desktop/HW3/HW3; && gcc -o child child.c; && ./child;");
notice, all one system call, terminators at end of commands, and linked by && so one command must be successful to continue on to the next command

Resources