Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Now CMake will build both static and shared libs #960

Closed
wants to merge 1 commit into from
Closed

Now CMake will build both static and shared libs #960

wants to merge 1 commit into from

Conversation

subnut
Copy link
Contributor

@subnut subnut commented May 12, 2022

Closes #952

Continuation of #953, because GitHub didn't allow me to re-open that PR.

Comment on lines -259 to +305
target_link_libraries(avrdude PUBLIC libavrdude)
if (sharedlib IN_LIST BUILT_LIBS)
target_link_libraries(avrdude PUBLIC sharedlib)
else()
target_link_libraries(avrdude PUBLIC staticlib)
endif()
Copy link
Contributor Author

@subnut subnut May 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we retain the old behaviour of linking the executable with the static library? Or should we make the executable dynamically-linked when possible (like I've done here) ?

@dl8dtl @mariusgreuel

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I ask, why would one not have binaries with statically linked libraries? It makes it way easier to bundle the official Avrdude release binaries without having to think about having the right drivers installed.
A binary that "just works" is what I personally prefer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it entirely defeats the idea of a shared/dynamic library?

To me, it seems this is really a philosophical issue. On Unix, 30 years ago, everyone was asking for shared libraries, because they can be shared between applications. That's why they have the suffix .so, for a "shared object".

On Windows, everyone tends to ship their own version of the DLL anyway. That completely defeats the idea of sharing something. It's then really just a complicated way of doing what could have been achieved with a static linking in the first place.

For that, I'm perfectly fine if we separate it that way: link statically on Windows, and used shared libs an Unix.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely, for AVRDUDE, it's not really a concern, unless we might have a second consumer of the shared lib some day. Even running multiple AVRDUDE processes doesn't gain from a shared library since the "text" (program code) will be shared between these processes anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes it way easier

This is the whole point here. Static libraries are so much easier to use. And it is not just bundling packages. Shared objects or DLLs are a lot of work. You either have to keep your interfaces stable, or you better make sure you get your versioning straight. On Windows, this is why everybody uses COM, i.e. you have immutable interfaces that work very much like pure virtual C++ classes, including all the benefits this implies. And this is what I meant earlier, when I said the avrdude codebase is in no shape for a shared object: We currently have no abstraction at all, let alone immutable interfaces.

I think we should focus on adding features to avrdude, not maintaining shared objects that are not going to be used.

Copy link
Contributor

@dl8dtl dl8dtl May 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes it way easier

This is the whole point here. Static libraries are so much easier to use.

I think we are in strong disagreement here. ;-)

And it is not just bundling packages. Shared objects or DLLs are a lot of work.

I don't think they are more work than static ones. (OK, Windows DLLs seem to be more work, since it seems they cannot refer to global symbols from the resulting executable. That's another matter.)

You either have to keep your interfaces stable,

We need the same for a static library. If we flip the API all the time, nobody could rely on the static version as well. The only difference is, for a static library, the failure becomes already obvious at link time – but it remains a failure nevertheless.

If the API is only getting extended from release to release, there's no fear of incompatibilty and versioning.

Actually, many of the AVRDUDE APIs have been quite stable in recent time.

Segregating the library backend has been a long-standing project, and I wouldn't want to give it up. It helps getting some structure into the code that hasn't been there before. Dynamic libraries are just a side-product then. If you don't like them, don't use them.

Copy link
Contributor Author

@subnut subnut May 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A binary that "just works" is what I personally prefer.

So do I.

But IIRC, the executable that is built currently by using autotools is not fully static.

$ ldd `command -v avrdude`
	linux-vdso.so.1 (0x00007fffeadf4000)
	libusb-1.0.so.0 => /usr/lib/libusb-1.0.so.0 (0x00007f2ff5be5000)
	libusb-0.1.so.4 => /usr/lib64/libusb-0.1.so.4 (0x00007f2ff5bde000)
	libftdi1.so.2 => /usr/lib64/libftdi1.so.2 (0x00007f2ff5bcd000)
	libelf.so.1 => /usr/lib/libelf.so.1 (0x00007f2ff5bb2000)
	libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f2ff5b91000)
	libm.so.6 => /usr/lib/libm.so.6 (0x00007f2ff5a4c000)
	libhidapi-libusb.so.0 => /usr/lib64/libhidapi-libusb.so.0 (0x00007f2ff5a40000)
	libc.so.6 => /usr/lib/libc.so.6 (0x00007f2ff587a000)
	libudev.so.1 => /usr/lib/libudev.so.1 (0x00007f2ff5852000)
	/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f2ff5c97000)
	libz.so.1 => /usr/lib/libz.so.1 (0x00007f2ff5838000)
	librt.so.1 => /usr/lib/librt.so.1 (0x00007f2ff582d000)

See? It still depends on lib{usb,ftdi1,elf,hidapi}

If we decide to make avrdude static, then we'll have to link those (and the libc too, IMO) statically. Only then shall we have an "it just works" executable.

But then, static linking of libc is another can of worms.
Last I checked, you simply couldn't statically link glibc.


But that's not what my original question is about. My original question is about dynamically linking to libavrdude.

My point was that, since we're dynamically linking to the other libraries, why not link dynamically to libavrdude?

That was the rationale behind this code -

if (sharedlib IN_LIST BUILT_LIBS)
    target_link_libraries(avrdude PUBLIC sharedlib)
else()
    target_link_libraries(avrdude PUBLIC staticlib)
endif()

and it caused the resulting executable to be dynamically linked with libavrdude

$ ldd `command -v avrdude`
	linux-vdso.so.1 (0x00007ffe321f6000)
	libavrdude.so.1 => /usr/lib64/libavrdude.so.1 (0x00007fcadf372000)
	libc.so.6 => /usr/lib/libc.so.6 (0x00007fcadf1ac000)
	libm.so.6 => /usr/lib/libm.so.6 (0x00007fcadf067000)
	libelf.so.1 => /usr/lib/libelf.so.1 (0x00007fcadf04c000)
	libusb-0.1.so.4 => /usr/lib64/libusb-0.1.so.4 (0x00007fcadf045000)
	libusb-1.0.so.0 => /usr/lib/libusb-1.0.so.0 (0x00007fcadf026000)
	libhidapi-libusb.so.0 => /usr/lib64/libhidapi-libusb.so.0 (0x00007fcadf01a000)
	libftdi1.so.2 => /usr/lib64/libftdi1.so.2 (0x00007fcadf009000)
	/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fcadf425000)
	libz.so.1 => /usr/lib/libz.so.1 (0x00007fcadefef000)
	libudev.so.1 => /usr/lib/libudev.so.1 (0x00007fcadefc7000)
	libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fcadefa6000)
	librt.so.1 => /usr/lib/librt.so.1 (0x00007fcadef9b000)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the executable that is built currently by using autotools is not fully static

Lets talk about CMake, but even with the Automake, this is per design. Jörg and I actually talked briefly about this and thought this would make the most sense. Reason being:

  • On a Un*x system, we have a controlled environment, i.e. a package manager with dependency management. avrdude will be build for a specific environment, i.e. we know which shared object are present and avrdude will work with. Alternatively, it is relatively easy to build locally, where again avrdude is run in a matching environment. That is also the reason that the release artifacts do not contain any Un*x binaries, because dynamically linked executables won't just work in an arbitrary Un*x system.
  • On Windows, we do not have a controlled environment. avrdude is typically distributed via a download, so we do not know the version of Windows it is run, or which or which versions of the DLLs are present. Hence, we link everything (i.e. libusb, libhid, libftdi, libelf) but the system DLLs static. The crt libraries are static as well because we would have to distribute them otherwise.

Now, with the Arduino team, we have a new request here: We want to be able to install avrdude in an environment we do not control: For instance, download the Arduino IDE and execute it on any Linux system. So now, we have the same set of problems as on Windows, and now Linux people do something similar what Windows people are used to: 1) Either make sure the dependencies are met through some sort of installer, or 2) install shared objects side-by-side with the application, or 3) link everything (but the system/crt libraries) statically.

For a standalone application like avrdude, 3) is a good choice.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My point was that, since we're dynamically linking to the other libraries, why not link dynamically to libavrdude?

Well, if you specify BUILD_SHARED_LIBS=1 you should.

@subnut
Copy link
Contributor Author

subnut commented May 12, 2022

@dl8dtl The macOS dynlib problem has been solved. It builds now.

@mariusgreuel
Copy link
Contributor

Question: Why are you building both static and shared libraries in the same build? For CMake, I think people are very much used to doing separate builds while passing BUILD_SHARED_LIBS.

@dl8dtl
Copy link
Contributor

dl8dtl commented May 12, 2022

Actually, I find that strange. I'm really used to have compilations building both, dynamic libraries "for real live", static libraries for special purposes (e.g. debugging).

@dl8dtl
Copy link
Contributor

dl8dtl commented May 12, 2022

@dl8dtl The macOS dynlib problem has been solved. It builds now.

I have been experimenting a bit with your branch on my private fork, and could also resolve it there by applying the respective linker options.

Still, for me at least, the problem with not being able to declare global symbols as to be imported from the (future) application in the Windows DLL remained. I started to tinker a bit with rewriting the code to rework all that into a callback/configuration mode, but haven't finished.

@mariusgreuel
Copy link
Contributor

Actually, I find that strange. I'm really used to have compilations building both

Probably, that is because you work mostly with automake projects? CMake people would probably claim the opposite if they can no longer tweak their builds. I think we should not make a CMake project look like an automake project and deviate from what people are used to.

@dl8dtl
Copy link
Contributor

dl8dtl commented May 12, 2022

Actually, I find that strange. I'm really used to have compilations building both

Probably, that is because you work mostly with automake projects?

No, independent of that. All FreeBSD-built libraries have both, .a and .so versions. – They don't use automake.

I think automake simply derived that habit from what used to be there before.

@subnut
Copy link
Contributor Author

subnut commented May 13, 2022

@mariusgreuel

For CMake, I think people are very much used to doing separate builds while passing BUILD_SHARED_LIBS

I... don't know. I've never used CMake personally, so I have no idea of the conventions, if any.
(In fact, this is my first time trying to write and understand CMake scripts)

Why are you building both static and shared libraries in the same build?

Because that's what used to happen previously, i.e. when we built with autotools.
Yup. The only reason this PR exists, is because I don't like change. 🙂

And also because it makes packaging easier on Void Linux 😅

@subnut
Copy link
Contributor Author

subnut commented May 13, 2022

I'm not saying we should do it the way I've done in this PR.

I opened this PR simply because I wanted to. It seemed like a good challenge, and an opportunity for me to dip my toes into CMake world. 😄

I'm not an avrdude developer (yet 😉) so I am not going to voice any opinion on the structural decisions of the project.

@subnut

This comment was marked as off-topic.

@subnut
Copy link
Contributor Author

subnut commented May 13, 2022

rewriting the code to rework all that into a callback/configuration mode, but haven't finished

So, do you suggest that we wait till that code is merged, and then fix the CMake builds? @dl8dtl

@mcuee
Copy link
Collaborator

mcuee commented May 13, 2022

It seems to be a convention that CMake by projects will tend not to build dynamic and static libraries at the same time (even though some projects like libftdi does that).

Interestingly this is used as a point against CMake by Meson developer here (ignore the heated discussion -- libusb project will use auto-tools and not use CMake or Meson anytime soon).
libusb/libusb#1134 (comment)

@mariusgreuel
Copy link
Contributor

It seems to be a convention that CMake by projects will tend not to build dynamic and static libraries at the same time

This is why there is BUILD_SHARED_LIBS. The reason being is that you want to be able to build different objects depending on the value of BUILD_SHARED_LIBS, and you typically do so by passing additional options.

Moreover, if you build both shared and static libraries in one shot, the build options will apply to both. For instance, if you pass a compiler option that applies to static builds only, you will break the entire build because linking the shared library will break. Or vice versa.

@mariusgreuel
Copy link
Contributor

I guess I am repeating myself, but I like to see the extra code to build both static and dynamic libraries (including the platform conditional code) gone from the CMake files.

All FreeBSD-built libraries have both, .a and .so versions

Just to avoid misunderstandings here, we should still be able to build both static and dynamic libraries, just not in one shot, for the reasons I outlined above.

@mariusgreuel
Copy link
Contributor

One more thing: I created PR #962 for everybody to review where I addressed some of the issues raised. More to come.

@mcuee
Copy link
Collaborator

mcuee commented May 14, 2022

Yes I can confirm this pull request works for building shared lib under macOS whereas #962 does not yet fix that one.


mcuee@mcuees-Mac-mini build % cmake -D CMAKE_C_FLAGS=-I/opt/homebrew/include -D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar -D CMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS="ON" -DCMAKE_VERBOSE_MAKEFILE="ON" ..
-- The C compiler identification is AppleClang 13.1.6.13160021
-- The CXX compiler identification is AppleClang 13.1.6.13160021
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /opt/homebrew/bin/git (found version "2.36.1") 
-- Found FLEX: /usr/bin/flex (found version "2.6.4") 
-- Found BISON: /usr/bin/bison (found version "2.3")
-- Looking for libelf.h
-- Looking for libelf.h - not found
-- Looking for libelf/libelf.h
-- Looking for libelf/libelf.h - found
-- Looking for usb.h
-- Looking for usb.h - found
-- Looking for lusb0_usb.h
-- Looking for lusb0_usb.h - not found
-- Looking for libusb.h
-- Looking for libusb.h - not found
-- Looking for libusb-1.0/libusb.h
-- Looking for libusb-1.0/libusb.h - found
-- Looking for hidapi/hidapi.h
-- Looking for hidapi/hidapi.h - found
-- Looking for ftdi_tcioflush
-- Looking for ftdi_tcioflush - found
-- Configuration summary:
-- ----------------------
-- DO HAVE    libelf
-- DO HAVE    libusb
-- DO HAVE    libusb_1_0
-- DO HAVE    libhidapi
-- DO HAVE    libftdi (but prefer to use libftdi1)
-- DO HAVE    libftdi1
-- DISABLED   doc
-- DISABLED   parport
-- DISABLED   linuxgpio
-- DISABLED   linuxspi
-- ----------------------
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build


mcuee@mcuees-Mac-mini build % make
...

[ 93%] Linking C shared library libavrdude.dylib
cd /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build/src && /opt/homebrew/Cellar/cmake/3.23.1_1/bin/cmake -E cmake_link_script CMakeFiles/sharedlib.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/cc -I/opt/homebrew/include -O2 -g -DNDEBUG -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -compatibility_version 1.0.0 -current_version 1.0.0 -o libavrdude.1.0.0.dylib -install_name @rpath/libavrdude.1.dylib CMakeFiles/objlib.dir/arduino.c.o CMakeFiles/objlib.dir/avr.c.o CMakeFiles/objlib.dir/avr910.c.o CMakeFiles/objlib.dir/avrftdi.c.o CMakeFiles/objlib.dir/avrftdi_tpi.c.o CMakeFiles/objlib.dir/avrpart.c.o CMakeFiles/objlib.dir/bitbang.c.o CMakeFiles/objlib.dir/buspirate.c.o CMakeFiles/objlib.dir/butterfly.c.o CMakeFiles/objlib.dir/config.c.o CMakeFiles/objlib.dir/confwin.c.o CMakeFiles/objlib.dir/crc16.c.o CMakeFiles/objlib.dir/dfu.c.o CMakeFiles/objlib.dir/fileio.c.o CMakeFiles/objlib.dir/flip1.c.o CMakeFiles/objlib.dir/flip2.c.o CMakeFiles/objlib.dir/ft245r.c.o CMakeFiles/objlib.dir/jtagmkI.c.o CMakeFiles/objlib.dir/jtagmkII.c.o CMakeFiles/objlib.dir/jtag3.c.o CMakeFiles/objlib.dir/linuxgpio.c.o CMakeFiles/objlib.dir/linuxspi.c.o CMakeFiles/objlib.dir/lists.c.o CMakeFiles/objlib.dir/micronucleus.c.o CMakeFiles/objlib.dir/par.c.o CMakeFiles/objlib.dir/pgm.c.o CMakeFiles/objlib.dir/pgm_type.c.o CMakeFiles/objlib.dir/pickit2.c.o CMakeFiles/objlib.dir/pindefs.c.o CMakeFiles/objlib.dir/ppi.c.o CMakeFiles/objlib.dir/ppiwin.c.o CMakeFiles/objlib.dir/serbb_posix.c.o CMakeFiles/objlib.dir/serbb_win32.c.o CMakeFiles/objlib.dir/ser_avrdoper.c.o CMakeFiles/objlib.dir/ser_posix.c.o CMakeFiles/objlib.dir/ser_win32.c.o CMakeFiles/objlib.dir/serialupdi.c.o CMakeFiles/objlib.dir/stk500.c.o CMakeFiles/objlib.dir/stk500v2.c.o CMakeFiles/objlib.dir/stk500generic.c.o CMakeFiles/objlib.dir/teensy.c.o CMakeFiles/objlib.dir/updi_link.c.o CMakeFiles/objlib.dir/updi_nvm.c.o CMakeFiles/objlib.dir/updi_readwrite.c.o CMakeFiles/objlib.dir/updi_state.c.o CMakeFiles/objlib.dir/usbasp.c.o CMakeFiles/objlib.dir/usb_hidapi.c.o CMakeFiles/objlib.dir/usb_libusb.c.o CMakeFiles/objlib.dir/usbtiny.c.o CMakeFiles/objlib.dir/update.c.o CMakeFiles/objlib.dir/wiring.c.o CMakeFiles/objlib.dir/xbee.c.o CMakeFiles/objlib.dir/__/lexer.c.o CMakeFiles/objlib.dir/__/config_gram.c.o  -lm /opt/homebrew/lib/libelf.a /opt/homebrew/lib/libusb.dylib /opt/homebrew/lib/libusb-1.0.dylib /opt/homebrew/lib/libhid.dylib /opt/homebrew/lib/libhidapi.dylib /opt/homebrew/lib/libftdi.dylib /opt/homebrew/lib/libftdi1.dylib /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/usr/lib/libreadline.tbd 
cd /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build/src && /opt/homebrew/Cellar/cmake/3.23.1_1/bin/cmake -E cmake_symlink_library libavrdude.1.0.0.dylib libavrdude.1.dylib libavrdude.dylib
[ 93%] Built target sharedlib
/Library/Developer/CommandLineTools/usr/bin/make  -f src/CMakeFiles/avrdude.dir/build.make src/CMakeFiles/avrdude.dir/depend
cd /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build && /opt/homebrew/Cellar/cmake/3.23.1_1/bin/cmake -E cmake_depends "Unix Makefiles" /Users/mcuee/build/avr/avrdude_test/avrdude_shared /Users/mcuee/build/avr/avrdude_test/avrdude_shared/src /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build/src /Users/mcuee/build/avr/avrdude_test/avrdude_shared/build/src/CMakeFiles/avrdude.dir/DependInfo.cmake --color=
/Library/Developer/CommandLineTools/usr/bin/make  -f src/CMakeFiles/avrdude.dir/build.make src/CMakeFiles/avrdude.dir/build
...

@mcuee
Copy link
Collaborator

mcuee commented May 15, 2022

It also works nicely under FreeBSD 13.0 Release.

mcuee@freebsdx64vm:~/build/avrdude_shared/build $ cmake -D CMAKE_C_FLAGS=-I/usr/local/include -D CMAKE_EXE_LINKER_FLAGS=-L/usr/local/lib -D CMAKE_BUILD_TYPE=RelWithDeb ..
-- The C compiler identification is Clang 11.0.1
-- The CXX compiler identification is Clang 11.0.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found Git: /usr/local/bin/git (found version "2.35.2") 
-- Found FLEX: /usr/bin/flex (found version "2.6.4") 
-- Found YACC: /usr/bin/yacc
-- Looking for libelf.h
-- Looking for libelf.h - found
-- Looking for libelf/libelf.h
-- Looking for libelf/libelf.h - not found
-- Looking for usb.h
-- Looking for usb.h - found
-- Looking for lusb0_usb.h
-- Looking for lusb0_usb.h - not found
-- Looking for libusb.h
-- Looking for libusb.h - found
-- Looking for libusb-1.0/libusb.h
-- Looking for libusb-1.0/libusb.h - not found
-- Looking for hidapi/hidapi.h
-- Looking for hidapi/hidapi.h - found
-- Looking for ftdi_tcioflush
-- Looking for ftdi_tcioflush - found
-- Configuration summary:
-- ----------------------
-- DO HAVE    libelf
-- DO HAVE    libusb
-- DO HAVE    libusb_1_0
-- DO HAVE    libhidapi
-- DON'T HAVE libftdi
-- DO HAVE    libftdi1
-- DISABLED   doc
-- DISABLED   parport
-- DISABLED   linuxgpio
-- DISABLED   linuxspi
-- ----------------------
-- Configuring done
-- Generating done
-- Build files have been written to: /home/mcuee/build/avrdude_shared/build
mcuee@freebsdx64vm:~/build/avrdude_shared/build $ make
[  1%] [YACC][Parser] Building parser with yacc
[  3%] [FLEX][Parser] Building scanner with flex 2.6.4
[  4%] Building C object src/CMakeFiles/objlib.dir/arduino.c.o
[  6%] Building C object src/CMakeFiles/objlib.dir/avr.c.o
[  8%] Building C object src/CMakeFiles/objlib.dir/avr910.c.o
[  9%] Building C object src/CMakeFiles/objlib.dir/avrftdi.c.o
[ 11%] Building C object src/CMakeFiles/objlib.dir/avrftdi_tpi.c.o
[ 12%] Building C object src/CMakeFiles/objlib.dir/avrpart.c.o
[ 14%] Building C object src/CMakeFiles/objlib.dir/bitbang.c.o
[ 16%] Building C object src/CMakeFiles/objlib.dir/buspirate.c.o
[ 17%] Building C object src/CMakeFiles/objlib.dir/butterfly.c.o
[ 19%] Building C object src/CMakeFiles/objlib.dir/config.c.o
[ 20%] Building C object src/CMakeFiles/objlib.dir/confwin.c.o
[ 22%] Building C object src/CMakeFiles/objlib.dir/crc16.c.o
[ 24%] Building C object src/CMakeFiles/objlib.dir/dfu.c.o
[ 25%] Building C object src/CMakeFiles/objlib.dir/fileio.c.o
[ 27%] Building C object src/CMakeFiles/objlib.dir/flip1.c.o
[ 29%] Building C object src/CMakeFiles/objlib.dir/flip2.c.o
[ 30%] Building C object src/CMakeFiles/objlib.dir/ft245r.c.o
[ 32%] Building C object src/CMakeFiles/objlib.dir/jtagmkI.c.o
[ 33%] Building C object src/CMakeFiles/objlib.dir/jtagmkII.c.o
[ 35%] Building C object src/CMakeFiles/objlib.dir/jtag3.c.o
[ 37%] Building C object src/CMakeFiles/objlib.dir/linuxgpio.c.o
[ 38%] Building C object src/CMakeFiles/objlib.dir/linuxspi.c.o
[ 40%] Building C object src/CMakeFiles/objlib.dir/lists.c.o
[ 41%] Building C object src/CMakeFiles/objlib.dir/micronucleus.c.o
[ 43%] Building C object src/CMakeFiles/objlib.dir/par.c.o
[ 45%] Building C object src/CMakeFiles/objlib.dir/pgm.c.o
[ 46%] Building C object src/CMakeFiles/objlib.dir/pgm_type.c.o
[ 48%] Building C object src/CMakeFiles/objlib.dir/pickit2.c.o
[ 50%] Building C object src/CMakeFiles/objlib.dir/pindefs.c.o
[ 51%] Building C object src/CMakeFiles/objlib.dir/ppi.c.o
[ 53%] Building C object src/CMakeFiles/objlib.dir/ppiwin.c.o
[ 54%] Building C object src/CMakeFiles/objlib.dir/serbb_posix.c.o
[ 56%] Building C object src/CMakeFiles/objlib.dir/serbb_win32.c.o
[ 58%] Building C object src/CMakeFiles/objlib.dir/ser_avrdoper.c.o
[ 59%] Building C object src/CMakeFiles/objlib.dir/ser_posix.c.o
[ 61%] Building C object src/CMakeFiles/objlib.dir/ser_win32.c.o
[ 62%] Building C object src/CMakeFiles/objlib.dir/serialupdi.c.o
[ 64%] Building C object src/CMakeFiles/objlib.dir/stk500.c.o
[ 66%] Building C object src/CMakeFiles/objlib.dir/stk500v2.c.o
[ 67%] Building C object src/CMakeFiles/objlib.dir/stk500generic.c.o
[ 69%] Building C object src/CMakeFiles/objlib.dir/teensy.c.o
[ 70%] Building C object src/CMakeFiles/objlib.dir/updi_link.c.o
[ 72%] Building C object src/CMakeFiles/objlib.dir/updi_nvm.c.o
[ 74%] Building C object src/CMakeFiles/objlib.dir/updi_readwrite.c.o
[ 75%] Building C object src/CMakeFiles/objlib.dir/updi_state.c.o
[ 77%] Building C object src/CMakeFiles/objlib.dir/usbasp.c.o
[ 79%] Building C object src/CMakeFiles/objlib.dir/usb_hidapi.c.o
[ 80%] Building C object src/CMakeFiles/objlib.dir/usb_libusb.c.o
[ 82%] Building C object src/CMakeFiles/objlib.dir/usbtiny.c.o
[ 83%] Building C object src/CMakeFiles/objlib.dir/update.c.o
[ 85%] Building C object src/CMakeFiles/objlib.dir/wiring.c.o
[ 87%] Building C object src/CMakeFiles/objlib.dir/xbee.c.o
[ 88%] Building C object src/CMakeFiles/objlib.dir/__/lexer.c.o
[ 90%] Building C object src/CMakeFiles/objlib.dir/__/config_gram.c.o
[ 90%] Built target objlib
[ 91%] Linking C static library libavrdude.a
[ 91%] Built target staticlib
[ 93%] Linking C shared library libavrdude.so
[ 93%] Built target sharedlib
[ 95%] Building C object src/CMakeFiles/avrdude.dir/main.c.o
[ 96%] Building C object src/CMakeFiles/avrdude.dir/term.c.o
[ 98%] Building C object src/CMakeFiles/avrdude.dir/whereami.c.o
[100%] Linking C executable avrdude
[100%] Built target avrdude


@mcuee
Copy link
Collaborator

mcuee commented Aug 27, 2022

Not so sure why the author close this issue, the pull request is actually still good for macOS.

git clone https://github.com/avrdudes/avrdude.git avrdude_pr960
cd avrdude_pr960
git fetch origin pull/960/head && git checkout FETCH_HEAD

cmake -D CMAKE_C_FLAGS=-I/opt/homebrew/include 
-D CMAKE_EXE_LINKER_FLAGS=-L/opt/homebrew/Cellar 
-D CMAKE_BUILD_TYPE=RelWithDebInfo 
-DBUILD_SHARED_LIBS="ON" 
-DCMAKE_VERBOSE_MAKEFILE="ON" -B build_darwin

cmake --build build_darwin

Results:

mcuee@mcuees-Mac-mini avrdude_pr960 % ls ./build_darwin/src                       
CMakeFiles		avrdude			cmake_install.cmake	libavrdude.a
Makefile		avrdude.conf		libavrdude.1.0.0.dylib	libavrdude.dylib
ac_cfg.h		avrdude.spec		libavrdude.1.dylib

mcuee@mcuees-Mac-mini avrdude_pr960 % otool -L ./build_darwin/src/avrdude         
./build_darwin/src/avrdude:
	@rpath/libavrdude.1.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
	/opt/homebrew/opt/libusb-compat/lib/libusb-0.1.4.dylib (compatibility version 9.0.0, current version 9.4.0)
	/opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 4.0.0, current version 4.0.0)
	/opt/homebrew/opt/libhid/lib/libhid.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/opt/homebrew/opt/hidapi/lib/libhidapi.0.dylib (compatibility version 0.0.0, current version 0.12.0)
	/opt/homebrew/opt/libftdi0/lib/libftdi.1.dylib (compatibility version 22.0.0, current version 22.0.0)
	/opt/homebrew/opt/libftdi/lib/libftdi1.2.dylib (compatibility version 2.0.0, current version 2.5.0)
	/usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)

mcuee@mcuees-Mac-mini avrdude_pr960 % otool -L ./build_darwin/src/libavrdude.dylib
./build_darwin/src/libavrdude.dylib:
	@rpath/libavrdude.1.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
	/opt/homebrew/opt/libusb-compat/lib/libusb-0.1.4.dylib (compatibility version 9.0.0, current version 9.4.0)
	/opt/homebrew/opt/libusb/lib/libusb-1.0.0.dylib (compatibility version 4.0.0, current version 4.0.0)
	/opt/homebrew/opt/libhid/lib/libhid.0.dylib (compatibility version 1.0.0, current version 1.0.0)
	/opt/homebrew/opt/hidapi/lib/libhidapi.0.dylib (compatibility version 0.0.0, current version 0.12.0)
	/opt/homebrew/opt/libftdi0/lib/libftdi.1.dylib (compatibility version 22.0.0, current version 22.0.0)
	/opt/homebrew/opt/libftdi/lib/libftdi1.2.dylib (compatibility version 2.0.0, current version 2.5.0)
	/usr/lib/libedit.3.dylib (compatibility version 2.0.0, current version 3.0.0)

@mcuee
Copy link
Collaborator

mcuee commented Aug 27, 2022

@subnut mentioned that he did not closed the pull requests but his comment does not appear here. Strange.
Somehow I also can not re-open this pull requests.

@mcuee
Copy link
Collaborator

mcuee commented Aug 27, 2022

@subnut I am not so sure if this is closed because you have deleted your branch.

mcuee added a commit to mcuee/avrdude that referenced this pull request Oct 25, 2022
@mcuee
Copy link
Collaborator

mcuee commented Oct 26, 2022

This PR can no longer be applied to the git main. The following is roughly the same but missing library installation.

$ git diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 400da29..7b33bc8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,6 @@ option(HAVE_PARPORT "Enable parallel port support" OFF)
 option(USE_EXTERNAL "Use external libraries from AVRDUDE GitHub repositories" OFF)
 option(USE_LIBUSBWIN32 "Prefer libusb-win32 over libusb" OFF)
 option(DEBUG_CMAKE "Enable debugging output for this CMake project" OFF)
-option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
 
 if(WIN32)
     # Prefer static libraries over DLLs on Windows
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ca6cb64..847db99 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -47,8 +47,11 @@ endif()
 # Setup target specific options
 # =====================================
 
-include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
 add_compile_definitions(CONFIG_DIR=\"${CONFIG_DIR}\")
+include_directories(
+    BEFORE ${CMAKE_CURRENT_BINARY_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    )
 
 if(WIN32)
     set(EXTRA_WINDOWS_RESOURCES "${PROJECT_BINARY_DIR}/src/windows.rc")
@@ -132,7 +135,25 @@ add_custom_target(conf ALL DEPENDS avrdude.conf)
 # Project
 # =====================================
 
-add_library(libavrdude
+set(includes
+    "${PROJECT_SOURCE_DIR}"
+    "${PROJECT_BINARY_DIR}"
+    "${LIBUSB_COMPAT_DIR}"
+    "${EXTRA_WINDOWS_INCLUDES}"
+    )
+set(deplibs
+    ${LIB_MATH}
+    ${LIB_LIBELF}
+    ${LIB_LIBUSB}
+    ${LIB_LIBUSB_1_0}
+    ${LIB_LIBHID}
+    ${LIB_LIBHIDAPI}
+    ${LIB_LIBFTDI}
+    ${LIB_LIBFTDI1}
+    ${LIB_LIBREADLINE}
+    ${EXTRA_WINDOWS_LIBRARIES}
+    )
+set(sources
     ac_cfg.h
     arduino.h
     arduino.c
@@ -241,36 +262,58 @@ add_library(libavrdude
     ${BISON_Parser_OUTPUTS}
     "${EXTRA_WINDOWS_SOURCES}"
     )
-    
-set_target_properties(libavrdude PROPERTIES
-    PREFIX ""
-    PUBLIC_HEADER "libavrdude.h"
-    VERSION 1.0.0
-    SOVERSION 1
-    )
 
-target_include_directories(libavrdude
-    PUBLIC
-    "${PROJECT_SOURCE_DIR}"
-    "${PROJECT_BINARY_DIR}"
-    "${LIBUSB_COMPAT_DIR}"
-    "${EXTRA_WINDOWS_INCLUDES}"
-    )
+if (MSVC)
+    set(BUILT_LIBS staticlib)
+    add_library(staticlib STATIC ${sources})
+    set_target_properties(staticlib PROPERTIES
+        PREFIX ""
+        OUTPUT_NAME "libavrdude"
+        PUBLIC_HEADER "libavrdude.h"
+        )
+    target_include_directories(staticlib PUBLIC ${includes})
+    target_link_libraries(staticlib PUBLIC ${deplibs})
+else()
+    # build objects
+    add_library(objlib OBJECT ${sources})
+    target_include_directories(objlib PUBLIC ${includes})
+    set_target_properties(objlib PROPERTIES
+        POSITION_INDEPENDENT_CODE true)
 
-target_link_libraries(libavrdude
-    PUBLIC
-    ${LIB_MATH}
-    ${LIB_LIBELF}
-    ${LIB_LIBUSB}
-    ${LIB_LIBUSB_1_0}
-    ${LIB_LIBHID}
-    ${LIB_LIBHIDAPI}
-    ${LIB_LIBFTDI}
-    ${LIB_LIBFTDI1}
-    ${LIB_LIBREADLINE}
-    ${EXTRA_WINDOWS_LIBRARIES}
-    )
+    # staticlib
+    set(BUILT_LIBS staticlib)
+    add_library(staticlib STATIC $<TARGET_OBJECTS:objlib>)
+    set_target_properties(staticlib PROPERTIES
+        PREFIX ""
+        OUTPUT_NAME "libavrdude"
+        PUBLIC_HEADER "libavrdude.h"
+        )
+    target_include_directories(staticlib PUBLIC ${includes})
+    target_link_libraries(staticlib PUBLIC ${deplibs})
 
+    # sharedlib
+    if(NOT WIN32) # DLL cannot have undefined references
+        set(BUILT_LIBS staticlib sharedlib)
+        add_library(sharedlib SHARED $<TARGET_OBJECTS:objlib>)
+        set_target_properties(sharedlib PROPERTIES
+            PREFIX ""
+            OUTPUT_NAME "libavrdude"
+            PUBLIC_HEADER "libavrdude.h"
+            VERSION 1.0.0
+            SOVERSION 1
+            )
+        target_include_directories(sharedlib PUBLIC ${includes})
+        target_link_libraries(sharedlib PUBLIC ${deplibs})
+        if (APPLE)
+            target_link_options(sharedlib
+                PRIVATE -undefined
+                PRIVATE dynamic_lookup
+                )
+        endif()
+    endif()
+endif()
+
+# executable
 add_executable(avrdude
     main.c
     term.c
@@ -284,19 +327,21 @@ add_executable(avrdude
     whereami.h
     "${EXTRA_WINDOWS_RESOURCES}"
     )
+if (sharedlib IN_LIST BUILT_LIBS)
+    target_link_libraries(avrdude PUBLIC sharedlib)
+else()
+    target_link_libraries(avrdude PUBLIC staticlib)
+endif()
 
-target_link_libraries(avrdude PUBLIC libavrdude)
+# =====================================
+# Install
+# =====================================
 
 # =====================================
 # Install
 # =====================================
 
 install(TARGETS avrdude DESTINATION bin)
-install(TARGETS libavrdude
-    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-    PUBLIC_HEADER DESTINATION include COMPONENT dev
-    )
 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/avrdude.conf" TYPE SYSCONF)
 install(FILES "avrdude.1"
        DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"


This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unable to build libavrdude dynamic and static library with CMake buildsystem
5 participants