I have just started with iotivity and have been reading the documentation. On this setup page, under the heading running the c++ samples, it tells how to run the examples, but before that I should build them first and it seems the page Build the C++ samples it refers to, is missing.
When I tried to build the examples in a normal way using g++, it gave some missing header errors, meaning that's not the right way or will take a lot of effort.
Do any one know how to build the examples packet with iotivity release?
Place the following makefile in the iotivity/resource/examples directory :
IDIR=-I../include -I./../csdk/stack/include/ -I./../c_common/ -I./../oc_logger/include
CC=g++
CFLAGS=-Wall -std=c++11 $(IDIR) -loc -loctbstack -loc_logger -lpthread
SERV_OBJ = simpleserver.o
CLIENT_OBJ = simpleclient.o
%.o: %.cpp
$(CC) -c -o $# $^ $(CFLAGS)
#Build the simpleserver executable
all:simpleserver simpleclient
simpleserver:$(SERV_OBJ)
$(CC) -o $# $^ $(CFLAGS)
#Build the simpleclient executable
simpleclient:$(CLIENT_OBJ)
$(CC) -o $# $^ $(CFLAGS)
and then hit make on the terminal. Then execute simpleclient and simpleserver on two different terminals. In case you get the error :
./simpleclient: error while loading shared libraries: liboc.so: cannot open shared object file: No such file or directory
type the following:
export LD_LIBRARY_PATH=../../out/linux/x86_64/release
I researched a lot to find where the executables get generated for the c++ samples, finally found the path.
On 64-bit Ubuntu 14.04 LTS ,
when iotivity is built as follows:
$ scons
the executables get created in path /iotivity/out/linux/x86_64/release/resource/examples for the code present in /iotivity/resource/examples so you can just go to /iotivity/out/linux/x86_64/release/resource/examples and execute simpleserver(./simpleserver) and simpleclient(./simpleclient)
Check this page about IoTivity supported (and unsupported) examples :
https://wiki.iotivity.org/examples#
cd ${project_dir}/out/${TARGET_OS}/${TARGET_ARCH}/${BUILD_MODE}/resource/examples/
killall simpleserver simpleclient # make sure none are running
./simpleserver 2>&1 | tee simpleserver.log.txt &
./simpleclient 2>&1 | tee simpleclient.log.txt
Some c++ examples are not working in 1.3.0 while 1.2.1 should be ok
But if you want to build other examples from outside the main tree, I made a dedicated project that use gnu make.
Hope this helps
Related
I need to build a program on Windows, MacOS and Linux which relies on multiples dependencies. I tried to limit them as much as I could but I should ended up using WxWidgets, libcurl, openssl and libarchive.
I choose those dependencies because I must be able to:
compute a md5 hash (openssl)
decompress a zip archive (libarchive)
provide a GUI (WxWidgets)
use HTTPS (libcurl)
I am aware that this might be an overkill to import 5 libraries to only do those 5 things but I do not know any better solution yet. As I am writing this, I'm only using libcurl and openssl and building for Windows, MacOS and Linux is already very difficult for me.
I would like to distribute a standalone executable for each platform in addition to the source code, to build my project, I use the following Makefile :
CXX = g++
NAME = foo
SRC = $(wildcard src/*.cpp)
OBJ = $(SRC:.cpp=.o)
CXXFLAGS = -I./inc -std=c++11 -Wall -Wextra -Werror -g
all : $(NAME)
$(NAME) : $(OBJ)
$(CXX) $(CXXFLAGS) -o $# $^ -lcurl -lssl -lcrypto
clean :
rm -rf $(SRC:.cpp=.o)
fclean : clean
rm -rf $(NAME) test
re : fclean all
reclean : fclean all clean
.PHONY : all clean fclean re reclean
This worked great(even on Windows thanks to MSYS2 and MINGW) until I tried to statically linked each library to distribute a standalone binary :
$(NAME) : $(OBJ)
$(CXX) $(CXXFLAGS) -o $# $^ -lcurl -lssl -lcrypto
becamed
$(NAME) : $(OBJ)
$(CXX) $(CXXFLAGS) -o $# $^ libcurl.a libssl.a libcrypto.a
On Linux(Ubuntu 22.04), I downloaded curl and openssl source codes and built them using -static flags, copied the *.a inside my project's directory and I was done.
Now I'm trying to build curl and openssl on Windows with MSYS2, most of my attempts failed with error messages and took forever(> 30 minutes) to complete the build process. After struggling a little too much time, I finally managed to compile openssl by adding -lcrypto -lcrypt32..?
I do not think I will be able to finish this project with this "building process" as I still need to figure it out how build and link libarchive and WxWidgets. Is there anything I am missed out regarding the building process ? Should I pick others libraries ? Or It is just how it is ?
Thanks for your help.
C++ newbie here my command is g++ main.cpp -o main gives me linking errors like the following
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
if i pass c++ files g++ main.cpp myfile.cpp -o main everything is correct
any ideas how to compile multiple c++ files without passing everything in command line.
Thanks
any ideas how to compile multiple c++ files without passing everything in command line.
To build an application you need all object files, so you have to pass all cpp files to compiler.
But for simple cases when all cpp-files stay at single folder, you can
use command (simple, but slow method):
g++ *.cpp -o main
any ideas how to compile multiple c++ files without passing everything in command line.
First create object files:
g++ -c main.cpp -o main.o
g++ -c myfile.cpp -o myfile.o
Then pass them to the linker:
g++ main.o myfile.o -o main
Though there is a fairly large learning curve for Make, a make file is the preferred solution. On SO, I have also noticed significant use of CMake.
Additional ideas for your Makefile:
The following two rules handle 90% of my simpler unit test executables:
R01 handles files with both .cc and .hh
R02 handles files with only .cc
# pattern rule R01
# when any ARCHIVE changes, trigger a rebuild
% : %.cc %.hh $(LIB_ARCHIVEs)
#echo
#echo R01: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# $(LIB_DIRs) $(LIB_NMs)
# pattern rule R02
# when any ARCHIVE changes, trigger a rebuild
% : %.cc $(LIB_ARCHIVEs)
#echo
#echo R02: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# $(LIB_DIRs) $(LIB_NMs)
Occasionally, I will add specific LIB names and directories ... directly to the LIB_DIRs and LIB_NMs definition in the Makefile. For example, here I have added -lrt and -pthread:
LIB_NMs += -lbag_i686 -lposix_i686 -lrt -pthread
bag_i686 and posix_i686 are libraries I built ... simple C++ class wrappers around the linux and posix functions. Most of my unit tests do not use much of posix stuff, but I get no grief including it.
With C++ std::thread, I seldom use -pthread. However, I occasionally use posix semaphore.
My compile command line access (in emacs on Ubuntu) provides a history, so the occasional change or addition to the command line is only a 'bother' one time. From then on, the newer command is available in history.
The emacs I launch is configured with an 'embedded' pre-defined compile command:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64' -j 2 -k
This command shows up the 1st time I launch the compiler from within emacs. Emacs presents it as if the command is already in 'compile-command history'.
I manually shorten this if I'm not rebuilding all, usually I only build a single ut:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64'
So, for example, when I am ready to compile dumy431.cc, I invoke:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64' dumy431
The next build I launch (from within emacs compile) starts with the previous command, and up/down arrow roll through any other versions of the command.
With this form of the command, I can trivially change from g++ to clang++ by inserting "clan" at the appropriate place:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='clang++ -m64'
clang++ often provides additional diagnostics that g++ does not report. To roll back to g++, I can up-arrow in the compiler command panel (or edit the command).
Here is a small example where my unit test code has multiple src files. Often, the non-main files (such as eng_format.*) are code that I plan to capture to one of my libraries for future use:
FMssb.o : FMssb.cc FMssb.hh
#echo
#echo R_FMssb.o: $<
rm -f $#
$(CC) $(CC_FLAGS) -c $< -o $#
FMssb_ut : FMssb_ut.cc eng_format.o FMssb.o $(LIB_ARCHIVEs)
#echo
#echo R_FMssb_ut: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# eng_format.o FMssb.o $(LIB_DIRs) $(LIB_NMs)
eng_format.o : eng_format.cpp eng_format.hpp $(LIB_ARCHIVEs)
#echo
#echo R_EF: $<
rm -f $#
$(CC) $(CC_FLAGS) -c $< -o $# $(LIB_DIRs) $(LIB_NMs)
So I'm on Windows, and I'm wondering how to build a DLL and a Static Library in MingW, and in different architectures like x86 and x64. I'm new to MingW, but not C++. I've been looking around Google a while and haven't found a way to do it yet, the reason being is because most of the tutorials I find are out-of-date.
GNU 'Make' File
Sources = Test.cpp Utilities.cpp
Objects = $(Sources:.cpp=.o)
ProjName = MyProgram
BuildName = $(ProjName).dll
$(ProjName) : $(Objects)
g++ -o $(BuildName) $(Objects)
$(Objects) :
g++ -c -D TEST_DYNAMIC $(Sources)
Clean :
rm $(Objects) $(BuildName)
Addition Information
Mingw Version: 4.8.1-4
Attempts
http://www.mingw.org/wiki/sampledll
-shared is an unrecognized command.
Okay so I figured out why it wasn't working. Those sites are not out-of-date, my MingW was, but my system was using Cygwin, which is what I don't want. So I changed my 'Path' variable to direct it to the correct Mingw.
I am learning how to set up makefiles, and have ran into a problem. To demonstrate this I have created a simple "project" consisting of source files main.m and test.m.
I am trying to setup make to compile these files (only if somethings changed), and store the object files in somewhere else (here build/)
My Makefile:
OBJ = ./build
SOURCES=main.m test.m
OBJECTS=$(addprefix $(OBJ)/,$(SOURCES:.m=.o))
EXECUTABLE=test
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
gcc $(OBJECTS) -o $(EXECUTABLE)
$(OBJECTS): $(OBJ)/%.o: %.m build/
gcc -c $< -o $#
build/:
mkdir build
When I run it for the first time (with only the Makefile and the sources in the current directory) it does what I expect it to do:
gcc -c main.m -o build/main.o
gcc -c test.m -o build/test.o
gcc ./build/main.o ./build/test.o -o test
However if I run make again:
gcc -c main.m -o build/main.o
gcc ./build/main.o ./build/test.o -o test
What have I done wrong? Also noting any other errors in the Makefile is appreciated, as I am trying to learn to create "good" Makefiles.
EDIT:
What I spotted from make -d:
Finished prerequisites of target file `build/main.o'.
Prerequisite `main.m' is older than target `build/main.o'.
Prerequisite `build/' is older than target `build/main.o'.
No need to remake target `build/main.o'.
and
Finished prerequisites of target file `build/test.o'.
Prerequisite `test.m' is older than target `build/test.o'.
Prerequisite `build/' is newer than target `build/test.o'.
Must remake target `build/test.o'.
Your make -d output shows that make thinks your build directory has been updated, and so that file needs to be rebuilt.
I guess that happens because some operation either on your build system's part or by something else in your filesystem is causing some timestamp on that directory to be updated.
You can fix the problem by making build an order-only prerequisite by adding a | to that rule:
$(OBJECTS): $(OBJ)/%.o: %.m | build
I deleted the / too, since it wasn't doing anything.
Since you asked, some other editorial notes:
Add a clean target. Something like:
clean:
rm -rf $(EXECUTABLE) $(OBJ)
You don't need the ./ when you set OBJ. Just OBJ = build is enough.
You don't need the / on build as mentioned above. But that doesn't really matter, since you shouldn't be referring it to it anyway. Repalce build with $(OBJ) wherever you see it.
mkdir will fail if the directory already exists. You probably should prefix that command with a -:
$(OBJ):
-mkdir $(OBJ)
Note that I've done the replacement with $(OBJ) that I mentioned in #3 above.
Auto-generation of dependencies is very helpful. Your project as shown isn't big enough to really need it, but it's easy enough to add, so why not. You'll need to do a couple of things. First, get the appropriate dependency file names:
DEPFILES = $(addprefix $(OBJ)/,$(SOURCES:.m=.d))
Then get the compiler to generate them by adding the -MMD flag:
gcc -MMD -c $< -o $#
Lastly, include them in your makefile if they're available, by adding a line at the end of your makefile:
-include $(DEPFILES)
Here are my two questions:
I am now learning to manage my code with CVS, and I just want to make a repository for my C++ files, Makefile and bash and python scripts only, not the object files and executables. So I made several subdirectories under my project directory: src, bin, scripts, results and data.
I put C++ files and Makefile under ~/myproject/src, Bash and Python scripts under ~/myproject/scripts and object and executables under ~/myproject/bin. I am hoping only the files under src and scripts will be updated via CVS. I wonder how you organize your projects? Just hope to follow some good habits.
Since I put my C++ files and Makefile into ~/myproject/src and object and executable files into ~/myproject/bin, I have to specify the directories in Makefile. Here is what I am doing
Makefile:
...
BIN_DIR=/home/myproject/bin/
all: $(BIN_DIR)myexecutable TAGS
TAGS: *.cc *.h
etags --members --declarations -l c++ *.cc *.h
$(BIN_DIR)myexecutable: $(BIN_DIR)myobject.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
Makefile.depend: *.h *.cc Makefile
$(CXX) -M $(CXXFLAGS) *.cc > Makefile.depend
clean:
\rm -f $(BIN_DIR)myexecutable $(BIN_DIR)*.o Makefile.depend TAGS`
However this will give error
make: *** No rule to make target /home/myproject/bin/myobject.o', needed by /home/myproject/bin/myexecutable'.
How to specify a different directory for object and executable files from C++ files in Makefile?
If you want to learn make, the GNU make manual is very good, both as a reference and a tutorial. You might want to consider using the patsubst command. The following is a chopped down version of one of my own makefiles that uses it:
OUT = bin/csvfix.exe
CC = g++
IDIR = inc
ODIR = obj
SDIR = src
INC = -Iinc -I../alib/inc
LIBS = ../alib/lib/alib.a -lodbc32
_OBJS = csved_atable.o \
csved_case.o \
csved_cli.o \
csved_command.o \
csved_date.o \
OBJS = $(patsubst %,$(ODIR)/%,$(_OBJS))
$(ODIR)/%.o: $(SDIR)/%.cpp
$(CC) -c $(INC) -o $# $< $(CFLAGS)
$(OUT): $(OBJS)
$(CC) -o $# $^ $(CFLAGS) $(LIBS)
strip $(OUT)
clean:
rm -f $(ODIR)/*.o $(OUT)
You can keep your files in different directories if you like, but that isn't necessary. Add a file or directory to the CVS repository once, and CVS will retain it indefinitely. From then on you can update it, check it in, whatever. If you don't add an object file to the repository, CVS won't touch it. If you want to add a whole directory tree, and you're in the habit of keeping objects there, just make clean before you do it.
Make is a wonderful tool, but it has some glaring faults. What you're describing is one of the classic problems: Make is good at using a source there to make something here, but not the other way around. Here are a couple of ways to do what you're trying to do.
A) Run make in your binary directory:
...
all: myexecutable TAGS
myexecutable: myobject.o
$(CXX) $(CXXFLAGS) -o $# $^ $(LDFLAGS)
VPATH = /home/myproject/src
...
cd ~/myproject/bin
make -f ../src/makefile
B) Put the objects on the bin directory by brute force:
$(BIN_DIR)%.o: %.cc
$(CXX) $(CXXFLAGS) -c -o $# $^
This will give you a problem with Makefile.depend, which you can approach several ways.
C) Learn some more advanced Make techniques. You probably shouldn't try this yet.
Your directory structure seems sensible.
I would make an explicit rule for executing the compiler, like
TARGET_DIR=bin
SRC_DIR=src
CXX=g++
CXXFLAGS=
ETC=
OBJS=$(TARGET_DIR)/test.o
all: $(OBJS)
$(TARGET_DIR)/%.o: $(SRC_DIR)/%.cc
$(CXX) -c -o $# $(CXXFLAGS) $(ETC) $<
Use automake and autoconf for building your project.
As for the structure of files just look at any big open-source C++ application. Any KDE application
will do fine for that matter. If you find an application that uses C++ and Python even better.
Why not go for eclipse, which is quite popular and handy for managing large projects. You can make a new project in eclipse, import-export code into the project from other projects, does version control for you as well etc. No need to write your make files, eclipse does it for you with your mentioned preferences in GUI.
If you are involved in a C++ project, just install the CDT plugin over eclipse and your are done.