I'm using CLion on El Capitan. Now I need to use the readline and add_history function in my project. But the linker complains those below down.
Undefined symbols for architecture x86_64:
"_add_history", referenced from:
_main in lisp_3.c.o
"_readline", referenced from:
_main in lisp_3.c.o
ld: symbol(s) not found for architecture x86_64
I can tackle it by adding a -ledit flag when compiling it manually or linking the libedit.tbd in Xcode but CLion uses CMake. So I don't know which library should I add to the CMakeLists.txt.
It's the first time I have used CMake to build a project. And I could only follow what he did in this question How to include C static libraries in CMAKE project on MAC OS X
cmake_minimum_required(VERSION 3.3)
project(test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(SOURCE_FILES read.c)
add_executable(test ${SOURCE_FILES})
find_library(readline_lib /* what can I place here?*/)
set(frameworks ${readline_lib})
target_link_libraries(test ${frameworks})
a link to a tar of the readline library is available at: <https://cnswww.cns.cwru.edu/php/chet/readline/rltop.html>
or more directly from: <git.savannah.gnu.org/cgit/readline.git/snapshot/readline-master.tar.gz>
I think the history functions come with the readline library.
Add this line to your CMakeLists.txt:
target_link_libraries(yourprojectname /usr/lib/x86_64-linux-gnu/libreadline.so)
I solved the same problem using:
target_link_libraries(test edit)
You need your program test to link against editline lib not readline
And below is the minimal CMakeList.txt file to compile it
cmake_minimum_required(VERSION 3.3)
project(test C)
set(SOURCE_FILES read.c)
add_executable(test ${SOURCE_FILES})
target_link_libraries(test edit)
Related
I am porting a Linux application to macOS and there is a difference in the linking behavior that took some of my time to reveal itself. The project uses a two-stage CMake-based build process: one CMake tree creates a dynamic library that links to static library that is created in the second tree that is created later. The static library does not exist yet when the dynamic library is created. This works on Linux: dynamic library gets created with symbols from static library and they are forward-declared. When the second tree is built, the dynamic library gets linked to an executable which also links the static library and this way everything works fine. This does not work on macOS because in the first CMake tree, the compiler fails at the dynamic library's linking step because the static library from the second tree does not exist yet.
I have reduced my application to a minimal example (the code can be found at the end of my question).
The setup is as follows:
Minimal C program with a main() function
Dynamic library with one function
Static library with one function
The program calls a function from the dynamic library. The dynamic library is of course linked dynamically to the program.
The dynamic library calls a function from the static library. The static library is linked statically to the dynamic library.
If we stop linking the static library to dynamic library:
# This target_link_libraries is intentionally commented out.
#target_link_libraries(dynamic_lib static_lib)
we, of course, get errors when building a program. But the errors are different on macOS and Linux:
macOS/clang fails earlier at the step when the dynamic library gets linked vs
Linux/gcc fails later at the step when the program gets linked
I do recognize that the difference can be in the fact that I am using clang on macOS and gcc on Linux but this does not explain the issue to me.
I would like to know:
Why does this difference exist?
Can I get the Linux behavior on macOS by tweaking the compiler/linker flags?
The example has been published to Github: Linking a dynamic library that links in symbols from a static library (macOS vs Linux).
These are the key files from my example on Github:
CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(untitled1 C)
add_compile_options("-fPIC")
set(CMAKE_C_STANDARD 99)
add_library(static_lib static_lib.c)
add_library(dynamic_lib SHARED dynamic_lib.c)
# THE ISSUE IS HERE:
# This target_link_libraries is intentionally commented out.
# on macOS the build process fails when linking dynamic_lib
# on Linux the build process fails when linking the
# 'untitled1' program.
#target_link_libraries(dynamic_lib static_lib)
add_executable(untitled1 main.c)
target_link_libraries(untitled1 dynamic_lib)
dynamic_lib.c
#include "dynamic_lib.h"
#include "static_lib.h"
void dynamic_lib_func() {
static_lib_func();
}
static_lib.c
#include "static_lib.h"
void static_lib_func() {}
macOS output
[ 25%] Building C object CMakeFiles/dynamic_lib.dir/dynamic_lib.c.o
/Library/Developer/CommandLineTools/usr/bin/cc -Ddynamic_lib_EXPORTS -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -fPIC -fPIC -std=gnu99 -o CMakeFiles/dynamic_lib.dir/dynamic_lib.c.o -c /Users/stanislaw/workspace/code/Examples/untitled1/dynamic_lib.c
[ 50%] Linking C shared library libdynamic_lib.dylib
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -E cmake_link_script CMakeFiles/dynamic_lib.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/cc -g -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk -dynamiclib -Wl,-headerpad_max_install_names -o libdynamic_lib.dylib -install_name #rpath/libdynamic_lib.dylib CMakeFiles/dynamic_lib.dir/dynamic_lib.c.o
Undefined symbols for architecture x86_64:
"_static_lib_func", referenced from:
_dynamic_lib_func in dynamic_lib.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Linux output
[ 16%] Linking C shared library libdynamic_lib.so
[ 33%] Built target dynamic_lib
Scanning dependencies of target untitled1
[ 50%] Linking C executable untitled1
libdynamic_lib.so: undefined reference to `static_lib_func'
collect2: error: ld returned 1 exit status
I have managed to find a solution to the related issue that I also encountered while porting the same project from Linux to macOS: How to share a global variable between a main process and a dynamic library via a static library (macOS)?.
It turns out that this kind of "forward declaration" of the library symbols is possible on macOS:
Adding the -undefined dynamic_lookup flag makes macOS to pass the original error.
Adding this to my example's CMakeLists.txt file solves the issue:
target_link_options(dynamic_lib PRIVATE -undefined dynamic_lookup)
I thought of compiling Lua from source code and then create a C module.
I compiled Lua with success but I can't build my C module.
So, I compiled Lua like this:
gcc -o Lua *.c -Os -std=c99
Compiled my module like this:
gcc -Wall -shared -fPIC -o module.so -I. module.c
But there are a few errors here:
Undefined symbols for architecture x86_64:
"_lua_pushcclosure", referenced from:
_luaopen_module in module-fb0b1f.o
"_lua_pushnumber", referenced from:
_super in module-fb0b1f.o
"_lua_setglobal", referenced from:
_luaopen_module in module-fb0b1f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The C module itself:
#include "lua.h"
static int super(lua_State* L) {
lua_pushnumber(L, 5);
return 1;
}
int luaopen_module(lua_State* L) {
lua_register(L, "super", super);
return 0;
}
My Lua script:
require("module")
print(super())
I'm on Unix based system (Mac), but I want it to work on Linux as well.
Edit:
Problem to compile C module was fixed by entering -bundle -undefined dynamic_lookup instead of -shared (Thanks lhf).
But I can't import the module in Lua.
> require("module")
error loading module 'module' from file './module.so':
dynamic libraries not enabled; check your Lua installation
Another thing:
This seems to be a quick fix only; -bundle -undefined dynamic_lookup. This does not work on Linux. How can I do this on linux? I wanted a solution for Unix based systems.
Download Lua from lua.org and build Lua with make macosx. See Getting started.
Use -bundle -undefined dynamic_lookup instead of -shared to build module.so.
Use require"module" to load it into Lua.
Call super.
Make sure you're running the lua program that you have built above, not some other version that is installed.
When compiling/statically linking a project of mine, I get the following error (in this case with OpenAL, I've tried other audio libraries such as PulseAudio and get similar errors):
Undefined symbols for architecture x86_64:
"_alcCaptureCloseDevice", referenced from:
_ad_close in libsphinxbase.a(ad_openal.c.o)
"_alcCaptureOpenDevice", referenced from:
_ad_open_dev in libsphinxbase.a(ad_openal.c.o)
"_alcCaptureSamples", referenced from:
_ad_read in libsphinxbase.a(ad_openal.c.o)
"_alcCaptureStart", referenced from:
_ad_start_rec in libsphinxbase.a(ad_openal.c.o)
"_alcCaptureStop", referenced from:
_ad_stop_rec in libsphinxbase.a(ad_openal.c.o)
"_alcGetIntegerv", referenced from:
_ad_read in libsphinxbase.a(ad_openal.c.o)
ld: symbol(s) not found for architecture x86_64
You can find the CMakeLists.txt in the link to the project, but I think the error lies within its dependency (despite it compiling just fine and generating a x86_64 architecture library). Here is the dependency's main CMakeLists.txt:
#
# Initial CMake and project setup
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
SET(PROJECT_NAME sphinxbase)
PROJECT(${PROJECT_NAME})
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
SET_DIRECTORY_PROPERTIES(PROPERTIES EP_PREFIX ${CMAKE_BINARY_DIR}/build-data)
#
# Setup compiler flags
#
if (NOT CMAKE_BUILD_TYPE)
message(STATUS "No build type selected, default to Release")
set(CMAKE_BUILD_TYPE CACHE Release FORCE)
endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -std=gnu11 -O0 -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -std=gnu11 -O3")
#
# Final project settings
#
configure_file("${CMAKE_SOURCE_DIR}/include/sphinx_config.h.in" "${CMAKE_SOURCE_DIR}/include/sphinx_config.h")
INCLUDE_DIRECTORIES(include)
ADD_SUBDIRECTORY(src)
ADD_SUBDIRECTORY(test EXCLUDE_FROM_ALL)
ADD_LIBRARY(${PROJECT_NAME} STATIC
$<TARGET_OBJECTS:libsphinxad>
$<TARGET_OBJECTS:fe>
$<TARGET_OBJECTS:feat>
$<TARGET_OBJECTS:lm>
$<TARGET_OBJECTS:util>
$<TARGET_OBJECTS:sphinx_adtools>
$<TARGET_OBJECTS:sphinx_cepview>
$<TARGET_OBJECTS:sphinx_fe>
$<TARGET_OBJECTS:sphinx_jsgf2fsg>
$<TARGET_OBJECTS:sphinx_lmtools>
)
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${LIBS})
I'm setting ${LIBS} in the libsphinxad object folder:
include_directories(${CMAKE_SOURCE_DIR}/include/sphinxbase)
if (WIN32)
set(SOURCES ${SOURCES} ad_win32.c)
endif ()
find_package(PulseAudio)
if (PULSEAUDIO_FOUND)
set(SOURCES ${SOURCES} ad_pulse.c)
set(LIBS ${PULSEAUDIO_LIBRARIES} CACHE INTERNAL "libs")
endif()
find_package(OSS)
if (OSS_FOUND)
set(SOURCES ${SOURCES} ad_oss.c )
endif()
find_package(OpenAL)
if (OPENAL_FOUND)
set(SOURCES ${SOURCES} ad_openal.c)
set(LIBS ${OPENAL_LIBRARY} CACHE INTERNAL "libs")
include_directories(${OPENAL_INCLUDE_DIR})
endif()
find_package(ALSA)
if (ALSA_FOUND)
set(SOURCES ${SOURCES} ad_alsa.c)
set(LIBS ${ALSA_LIBRARIES} CACHE INTERNAL "libs")
endif()
add_library(libsphinxad OBJECT ${SOURCES})
As you can see, I'm linking to the OpenAL framework. Here is the path that CMake is sending into TARGET_LINK_LIBRARIES that gives the error above:
/System/Library/Frameworks/OpenAL.framework
It looks like I'm doing things correctly, so I'm somewhat confused. I've tried adding -framework flags and adding linking to other libraries such as CoreAudio and Foundation to no avail. Any suggestion?
I have gotten the project to build without error linking to the dynamic library, but for my purposes I need to link the library statically.
I'm importing a C project into the Clion IDE, that uses Cmake.
My project uses these external libraries: Math and Ncurses.
However i'm not able to get the script CMakeLists.txt working.
This is the script:
cmake_minimum_required(VERSION 2.8.4)
project(thegame)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -lncurses -lm")
set(SOURCE_FILES thegame.c ./src/headers/set.h ./src/headers/functions.h ./src/headers/game.h ./src/headers/heap.h ./src/headers/lib.h
./src/headers/parser.h ./src/headers/pathfind.h ./src/headers/structures.h
./src/functions.c ./src/game.c ./src/heap.c ./src/lib.c ./src/parser.c ./src/pathfind.c ./src/set.c
)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "~/Binaries")
add_executable(thegame ${SOURCE_FILES})
I'm getting a lot of messages like this:
thegame.c:(.text.startup+0x1c): undefined reference to "mousemask"
...
What I'm doing Wrong?
I try to compile the picoc project into xcode. No external libraries, just .c and .h files that I imported in the Command Line Tool C project.
All .c files compile without issue, but when XCode is linking, I get these messages:
Undefined symbols for architecture x86_64:
"_BasicIOInit", referenced from:
_PicocInitialise in platform.o
"_CStdOut", referenced from:
_PrintSourceTextErrorLine in platform.o
_PlatformVPrintf in platform.o
"_MathFunctions", referenced from:
_IncludeInit in include.o
"_MathSetupFunc", referenced from:
_IncludeInit in include.o
"_PicocPlatformScanFile", referenced from:
_IncludeFile in include.o
...
The command giving the error is the following:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -v -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk -L/Users/laurent/Library/Developer/Xcode/DerivedData/Pico-dhfwbamkhiyphjcwuncbwjsyjlax/Build/Products/Debug -F/Users/laurent/Library/Developer/Xcode/DerivedData/Pico-dhfwbamkhiyphjcwuncbwjsyjlax/Build/Products/Debug -filelist /Users/laurent/Library/Developer/Xcode/DerivedData/Pico-dhfwbamkhiyphjcwuncbwjsyjlax/Build/Intermediates/Pico.build/Debug/Pico.build/Objects-normal/x86_64/Pico.LinkFileList -mmacosx-version-min=10.8 -o /Users/laurent/Library/Developer/Xcode/DerivedData/Pico-dhfwbamkhiyphjcwuncbwjsyjlax/Build/Products/Debug/Pico
The Pico.LinkFileList file contains properly the list of all necessary .o files.
As all the unfound functions are in the properly compiled .c files (and compiled as .o), what should I do to avoid these errors ?
Thanks.
Those symbols are in clibrary.c; you must have missed it from the list of source files to compile.
Your next question will doubtless be about libraries to link the executable with, and to solve that I would suggest you look at the Makefile.
Adding Pico to the Target Dependencies list worked for me after the same situation. (from Pico i mean the xcode project folder from where we have created library)
reference :
https://github.com/bulldog2011/pico
In case it can help someone, I found out that some #ifdef commands were excluding the functions to be compiled.