3

I am trying to call assembler function from C++ but facing linkage error. I am using Clang(Apple 11.0.0) on Mac OS and cmake. Here is my cmake file:

cmake_minimum_required(VERSION 3.13)

project(bitShiftAsm)

set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_CXX_STANDARD 17)

add_custom_command(
    OUTPUT ${CMAKE_SOURCE_DIR}/func.o
    WORKING_DIR ${CMAKE_SOURCE_DIR}
    COMMAND nasm -f macho64 ../func.asm
)

SET(OBJS
    ${CMAKE_SOURCE_DIR}/func.o
)

add_executable(bitShiftAsm ${OBJS} main.cpp)

SET_SOURCE_FILES_PROPERTIES(
    ${OBJS}
    PROPERTIES
    EXTERNAL_OBJECT true
    GENERATED true
)

Assembler file:

global _my_fn
_my_fn:
    mov rax, rdi
    add rax, 100
    ret

C++ file:

#include <iostream>

extern "C" long my_fn(long in);

int main()
{
    cout << "Result: " << my_fn(3) << endl;
}

Linkage error is:

nasm -f macho64 ../func.asm
c++    -g -isysroot 
MacOSX10.15.sdk -mmacosx-version-min=10.14   -std=gnu++1z -o 
CMakeFiles/bitShiftAsm.dir/main.cpp.o -c    .../bitShiftAsm/main.cpp
[100%] Linking CXX executable bitShiftAsm
cmake -E cmake_link_script CMakeFiles/bitShiftAsm.dir/link.txt --verbose=1
c++  -g -isysroot
MacOSX10.15.sdk -mmacosx-version-min=10.14 -Wl,-search_paths_first -Wl,- 
headerpad_max_install_names  CMakeFiles/bitShiftAsm.dir/main.cpp.o ../func.o  - 
o bitShiftAsm 
Undefined symbols for architecture x86_64:
  "_my_fn", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64

I have separate command to compile asm file and generate .o file from it. Appreciate any help. Thanks in advance.

Oleg
  • 1,027
  • 1
  • 8
  • 18
  • 1
    What error are you getting from the linker? – 1201ProgramAlarm Dec 10 '19 at 16:28
  • 2
    You forgot to make your function global. Add `global my_fn` to your assembly file. You might also need to rename it to `_my_fn` with a leading underscore. – Jester Dec 10 '19 at 16:28
  • I added it but still got the same linkage error. – Oleg Dec 10 '19 at 16:38
  • For consistency, and to ensure the `add_executable()` call can *see* the `.o` file, use `${CMAKE_SOURCE_DIR}/func.o` instead of `../func.o`. Also, try setting the source file properties of the `.o` file in your CMake, using the suggestion [here](https://stackoverflow.com/a/38610428/3987854). – Kevin Dec 10 '19 at 16:38
  • Also get your toolchain to show the commands it is running (no idea how to do that with CMake, maybe some verbose setting somewhere). – Jester Dec 10 '19 at 16:41
  • Yes, the verbose compiler output, such as `make VERBOSE=1`, would be helpful. – Kevin Dec 10 '19 at 16:43
  • I tried everything but nothing helps. With verbose I am getting exact commands that are running but at the end the same error again and nothing more. – Oleg Dec 10 '19 at 16:51
  • But what **are** the exact commands that are running? Please tell us. – Nate Eldredge Dec 10 '19 at 16:55
  • I added verbose logs. It seems that func.o is involved in linkage. – Oleg Dec 10 '19 at 17:04
  • Does it exist in `..`? Have you added the `global _my_fn` and changed `my_fn:` to `_my_fn:`? – Jester Dec 10 '19 at 17:07
  • Well the error message says it all. _my_fn is undefined. You define my_fn. A little fun fact: C implementations may mangle names too! Most often by adding a leading underscore. – n. m. could be an AI Dec 10 '19 at 17:12
  • Yes, I have added everything that is in discussion. Still no luck. – Oleg Dec 10 '19 at 17:16
  • 2
    Have you tried just running `nm` or `objdump` on `main.cpp.o` and `func.o`? You can see exactly what symbols the linker is working with ... – Useless Dec 10 '19 at 17:16
  • Hm, I removed the build directory and it started working. Very strange. Thanks a lot. – Oleg Dec 10 '19 at 17:22
  • 1
    CMake caches much of its variables, so when making changes to your CMake file, it is good practice to clear the CMake cache (i.e. by removing the build directory). This way, CMake runs from scratch and can recognize your changes. Please consider posting an answer showing what you changed in the code, so future visitors can understand the solution! – Kevin Dec 10 '19 at 17:51

0 Answers0