This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I have a simple program with my main.cpp, a header file func.h and another source file func.cpp. I use CLion 2016.3. My compiler is gcc.
They look like this:
Main.cpp
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include "func.h"
int main() {
int c;
c = number(2);
printf("%i", c);
}
func.cpp
int number(int a){
return a;
}
func.h
#ifndef TEST2_FUNC_H
#define TEST2_FUNC_H
int number(int a);
#endif //TEST2_FUNC_H
My cmakelists.txt
cmake_minimum_required(VERSION 3.6)
project(test2)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(test2 ${SOURCE_FILES})
If i run the build i get the following error:
CMakeFiles\test2.dir/objects.a(main.cpp.obj): In function `main':
C:/Users/name/ClionProjects/test2/main.cpp:8: undefined reference to `number(int)'
....
How can i fix this? I've searched for other similar issues and found some solutions but they didn't work for me or i didn't know what to do. Actually I have this problem with a C-Project but the issue is the same and I think the solution will be the same.
Can you please help me?
Thank you very much.
Make sure you include func.h in your main
#include "func.h"
and put 'func.cpp' in CMakeList.txt set source
List the sources explicitly here. That is all (.cpp, .c ,.cc) to compile together. If the sources files are not in the current directory, then you have to specify the full path to the source files
set(SOURCE_FILES main.cpp func.cpp)
You can use file(GLOB SOURCE_FILES *.cpp) if you want to automatically add files in your compilation. But keep in mind that this "trick" is strongly not encouraged to do.
Related
This question already has answers here:
How to use FIND_JNI on cmake
(2 answers)
Closed 9 months ago.
I am trying to compile my C++ project using CMake on my Mac M1 Pro 12.0.1.
This is my simple directory structure:
In my foo.cpp, I am including jni.h header file:
#include <iostream>
#include "foo.h"
#include <vector>
#include <jni.h>
void foo()
{
std::cout << "Hello World!\n";
}
This is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
project("myapplication")
add_library(my_app SHARED main.cpp foo.cpp)
target_include_directories(my_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
if(APPLE)
set(JAVA_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
set(JAVA_INCLUDE_PATH2 "$ENV{JAVA_HOME}/include/darwin")
set(JAVA_AWT_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
message("JAVA_INCLUDE_PATH = ${JAVA_INCLUDE_PATH}")
find_package(JNI REQUIRED)
if (JNI_FOUND)
message (STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}")
message (STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}")
endif()
target_include_directories(my_app PUBLIC ${JNI_INCLUDE_DIRS})
endif()
I am getting CMake output as:
-- Found JNI: /System/Library/Frameworks/JavaVM.framework
-- JNI_INCLUDE_DIRS=/Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include;/Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include/darwin;/Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk/Contents/Home/include
-- JNI_LIBRARIES=/System/Library/Frameworks/JavaVM.framework;/System/Library/Frameworks/JavaVM.framework
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/vmangal/my/practice/cmake/build
My JAVA_HOME environment variable is set to /Users/vmangal/Library/Java/JavaVirtualMachines/jdk1.8.0_202.jdk
But during make command, I am getting compilation error:
/Users/vmangal/my/practice/cmake/foo.cpp:4:10: fatal error: 'jni.h' file not found
#include <jni.h>
Am I missing something in CMakeLists.txt ?
I had a similar problem and found that when setting variables this way
set(JAVA_INCLUDE_PATH "$ENV{JAVA_HOME}/include")
i was getting wrong imports for C_INCLUDES and CXX_INCLUDES. Like this (see in CMakeFiles/my_app.dir/flags.make):
C_INCLUDES = -I/include -I/include/darwin
CXX_INCLUDES = -I/include -I/include/darwin
Which basically which meant that $ENV{JAVA_HOME} was an empty string.
After I set the full paths in CMakeLists
set(JAVA_INCLUDE_PATH /usr/local/Cellar/openjdk#17/17.0.3/libexec/openjdk.jdk/Contents/Home/include)
everything started working correctly.
So the conclusion is that if you want to run cmake and use $ENV{JAVA_HOME} – use syntax JAVA_HOME=/path/to/java/home cmake ...
As I'm rather new to Cmake usage, I don't really know how to solve this problem. In my C++ code, I use functions from the Linux i2c library, as follows:
extern "C" {
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
}
#include <sys/ioctl.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
bool cpi2c_writeRegister(uint8_t address, uint8_t subAddress, uint8_t data) {
return i2c_smbus_write_byte_data(address, subAddress, data) == 0;
}
I usually compile with Cmake using CMakeLists, but now it doesn't work since it states: undefined reference to 'i2c_smbus_write_byte_data'. I tried with G++ to link dynamically:
g++ -std=c++11 -Wall -c main.cpp
g++ -std=c++11 -o Main main.o -li2c
This worked well and there are no problems. The problem is I really need to compile with CMakeLists, so do you know a way how to achieve this? Cmake does not find the package by default (since it has no .config-file) and I don't know where the functions from i2c/smbus.h are defined.
Thanks for your help!
Using pkg-config is generally preferred to link libraries that have a .pc file.
But as libi2c does not seem to install a .pc file you can use target_link_libraries() directly by providing the library name. For simplicity and portability use the "Plain library name" (see the target_link_libraries documentation).
target_link_libraries(main i2c)
CMake will take care of expanding the plain library name to -li2c, i2c.lib, or whatever is suited to your build environment and operating system.
Step 1: add
target_link_libraries(${PROJECT_NAME}
i2c
)
To your CMakeList.txt.
Step 2: Declare the headers as "C",
extern "C"
{
#include<linux/i2c-dev.h>
#include <i2c/smbus.h>
}
Because libi2c.so is a dynamic library compiled with GCC.
If you do not declare it explicitly, the g++ will generate different function names in the symbol table thus the ld command cannot find any match in the i2c library.
The answer is, you can use the command target_link_libraries() after creating the executable. You have to provide the name of the object and a path to the .so-file (usually found in /usr/lib). In my case, that would be:
target_link_libraries(main, "/usr/lib/aarch64-linux-gnu/libi2c.so")
This question already has answers here:
How to add "-l" (ell) compiler flag in CMake
(2 answers)
Closed 3 years ago.
I'm trying to familiarize myself with ncurses.
When I compile this code on my IDE (cLion), it gives me the error:
"Error opening terminal: unknown"
I'm using Mac OSX.
If I compile using the terminal with:
"g++ -lncurses main.cpp -o hello"
It compiles and runs successfully.
But I'd like to figure out how to compile and run it on cLion.
I've checked around every on this forum and haven't been able to fix the issue. I've modified the CMakeLists.txt file various ways and none worked.
Where is the issue?
main.cpp
#include <ncurses.h>
using namespace std;
int main() {
initscr();
printw("Hello");
refresh();
int c = getch();
printw("%d", c);
getch();
endwin();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(ncurses)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "-lncurses")
add_executable(lncurses main.cpp)
CMAKE_CXX_FLAGS is the variable that contains compiler flags, not linker flags or libraries.
Use the target_link_libraries command to add libraries to link with:
target_link_libraries(lncurses ncurses)
I am having trouble setting up a C projectin Clion. I changed the name of the main.cpp to main.c, and altered the CMakeLists file accordingly, with the following info:
cmake_minimum_required(VERSION 3.3)
project(Project_1__)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.c)
add_executable(Project_1__ ${SOURCE_FILES})
However I get the following error when I try to build:
fatal error: iostream: No such file or directory #include compilation terminated. mingw32-make.exe[3]: * [CMakeFiles/Project_1__.dir/main.c.obj] Error 1 mingw32-make.exe[2]:
* [CMakeFiles/Project_1__.dir/all] Error 2
This error is due to fact that your complier is unable to find iostream header file. Make sure it exists in that directory. Plus it also depends on your IDE.
Also make sure, it is declared as #include "iostream.h" instead of #include<iostream.h>
iostream header files are declared in many of the compilers is declared by #include<iostream>
C++ needs <iostream> header file while C needs only <stdio.h>
Replace #include <iostream> with #include <stdio.h>. You'll also have to replace the stream related stuff in your code with stdio functions. See man stdio.
Also, you may have to change your makefile as I see -std=c++11 and I suspect that should be -std=c11. I'm not completely clear on this, so YMMV
iostream.h is specific to c++, c do not use stream classes
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 7 years ago.
Attempting to create a simple WebSocket c++ application, the library I am using relies on boost.
I have attempted to add boost to my project but it refuses to compile, heres my cpp file
#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/common/thread.hpp>
#include <websocketpp/common/memory.hpp>
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <sstream>
main()
{
printf("Hello World\n");
return 0;
}
I am attemting to compile it with g++ -I. -Iboost_1_58_0 /home/cabox/workspace/main.cpp -o /home/cabox/workspace/bin/exe, but all i get is
In function `__static_initialization_and_destruction_0(int,int)':
main.cpp:(.text+0xfba): undefined reference to`boost::system::generic_category()'
My folder layout is just my Main.cpp file, the boost_1_58_0 & the websocketpp folders all being in the same parent directory, what is it I'm doing wrong?
Add
-lboost_system
(see also What is an undefined reference/unresolved external symbol error and how do I fix it?)
Optionally specify the library directory with -L
Make sure it's after the cpps
Undefined reference to boost::system::generic_category despite linking with boost_system